2013-01-09 29 views
8

Ho un problema strano. Nella mia app sto combinando più file audio e video usando il codice qui sotto. Il video risultante sembra funzionare correttamente dopo averlo scaricato dal dispositivo al computer e aver giocato con Quick Time, ma ogni volta che cerco di riprodurre il video appena composto utilizzando UIWebView o AVPLayer, posso solo vedere la prima parte dei file video uniti.Composizione di video e audio utilizzando AVMutableComposition

Inoltre, quando ho provato a utilizzare MPMoviePlayerController per riprodurlo, si blocca su "Caricamento".

Posso sentire l'audio per tutte le composizioni. Per chiarire che ho due array: 1- AudioPieces con percorsi ai file audio [song1, song2, song3]; 2- MoviePieces con percorsi ai file video [film1, film2, film3]; Dopo aver unito questi file posso vedere solo film1 ma riesco a sentire song1 + song2 + song3. P.S. canzoni e film hanno lunghezze diverse (meno di 0,2 secondi). Qualsiasi aiuto sarà apprezzato. Grazie in anticipo, Janusz

-(void)putFilesTogether{ 
AVMutableComposition *mixComposition = [AVMutableComposition composition]; 
AVMutableCompositionTrack *videoCompositionTrack =[[AVMutableCompositionTrack alloc]init]; 
AVMutableCompositionTrack *audioCompositionTrack =[[AVMutableCompositionTrack alloc]init]; 

NSLog(@" movie %@ audio %@ ", moviePieces, audioPieces); 


NSError * error; 
for(int i=0;i<moviePieces.count;i++) 
{ 
    NSFileManager * fm = [NSFileManager defaultManager]; 
    NSString * movieFilePath; 
    NSString * audioFilePath; 
    movieFilePath = [moviePieces objectAtIndex:i]; 
    audioFilePath = [audioPieces objectAtIndex:i]; 


    if(![fm fileExistsAtPath:movieFilePath]){ 
     NSLog(@"Movie doesn't exist %@ ",movieFilePath); 
    } 
    else{ 
     NSLog(@"Movie exist %@ ",movieFilePath); 
    } 

    if(![fm fileExistsAtPath:audioFilePath]){ 
     NSLog(@"Audio doesn't exist %@ ",audioFilePath); 
    } 
    else{ 
     NSLog(@"Audio exists %@ ",audioFilePath); 
    } 


    NSURL *videoUrl = [NSURL fileURLWithPath:movieFilePath]; 
    NSURL *audioUrl = [NSURL fileURLWithPath:audioFilePath]; 


    AVURLAsset *videoasset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil]; 
    AVAssetTrack *videoAssetTrack= [[videoasset tracksWithMediaType:AVMediaTypeVideo] lastObject]; 

    AVURLAsset *audioasset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil]; 
    AVAssetTrack *audioAssetTrack= [[audioasset tracksWithMediaType:AVMediaTypeAudio] lastObject]; 

    videoCompositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 

    audioCompositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

    CMTime tempTime = mixComposition.duration; 

    [audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioasset.duration) ofTrack:audioAssetTrack atTime:tempTime error:&error]; 

    [videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoasset.duration) ofTrack:videoAssetTrack atTime:tempTime error:&error]; 

    if(error) 
    { 
     NSLog(@"Ups. Something went wrong! %@", [error debugDescription]); 
    } 
} 


NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0]; 
NSString *caldate = [now description]; 

float ran = arc4random()%1000; 
NSString * pathToSave = [NSString stringWithFormat:@"Output%@%f.mp4",caldate,ran]; 
pathToSave =[DOCUMENTS_FOLDER stringByAppendingPathComponent:pathToSave]; 
NSURL *movieUrl = [NSURL fileURLWithPath:pathToSave]; 

AVAssetExportSession *exporter =[[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetPassthrough]; 

exporter.outputFileType=AVFileTypeQuickTimeMovie; 
exporter.outputURL=movieUrl; 
exporter.shouldOptimizeForNetworkUse=YES; 

CMTimeValue val = mixComposition.duration.value; 

CMTime start=CMTimeMake(0, 600); 
CMTime duration=CMTimeMake(val, 600); 
CMTimeRange range=CMTimeRangeMake(start, duration); 
exporter.timeRange=range; 

[exporter exportAsynchronouslyWithCompletionHandler:^{ 
    switch ([exporter status]) { 
     case AVAssetExportSessionStatusFailed:{ 
      NSLog(@"Export failed: %@ %@", [[exporter error] localizedDescription],[[exporter error]debugDescription]); 
      NSString * message = @"Movie wasn't created. Try again later."; 
      [self performSelectorOnMainThread:@selector(dismissMe:) withObject:message waitUntilDone:NO]; 
      break;} 
     case AVAssetExportSessionStatusCancelled:{ NSLog(@"Export canceled"); 
      NSString * message1 = @"Movie wasn't created. Try again later."; 
      [self performSelectorOnMainThread:@selector(dismissMe:) withObject:message1 waitUntilDone:NO]; 
      break;} 
     case AVAssetExportSessionStatusCompleted: 
     { 
      NSString * message = @"Movie was successfully created."; 
      CMTime duration = mixComposition.duration; 

      [self saveData:duration ofPath:pathToSave]; 
      [self cleanFiles]; 
      [self performSelectorOnMainThread:@selector(dismissMe:) withObject:message waitUntilDone:NO]; 
     } 
    }}]; 

}

+0

Sto solo unendo un singolo file audio/video. Il problema è che, il mio file video di 40 secondi e il file audio è di 28 secondi. Quindi per i rimanenti 12 (40-28) secondi - voglio ripeterlo da 0 secondi nel file audio. Come faccio? C'è un modo diretto per farlo? – Hemang

risposta

12

Il problema risiede nel:

videoCompositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 

audioCompositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

Hanno bisogno di essere spostati al di fuori del corpo per ciclo.