2013-01-09 12 views
8

Mam dziwny problem. W mojej aplikacji łączę wiele plików audio i wideo za pomocą poniższego kodu. Wynikowe wideo wydaje się działać dobrze po pobraniu go z urządzenia na komputer i graniu z szybkim czasem, ale za każdym razem, gdy próbuję odtworzyć nowo skomponowane wideo za pomocą UIWebView lub AVPLayer, widzę tylko pierwszą część scalonych plików wideo.Komponowanie wideo i audio za pomocą AVMutableComposition

Ponadto, gdy próbowałem użyć MPMoviePlayerController, aby go odtworzyć, zawiesza się na "Ładowanie".

Słychać dźwięk dla wszystkich kompozycji. Aby było jasne, mam dwie tablice: 1- audioPieces ze ścieżkami do plików audio [song1, song2, song3]; 2- filmPieces ze ścieżkami do plików wideo [film1, film2, film3]; Po scaleniu tych plików widzę tylko film1, ale słyszę song1 + song2 + song3. P.S. utwory i filmy mają różną długość (różnica poniżej 0,2 s). Każda pomoc zostanie doceniona. Dziękuję z góry, 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

Łączę tylko jeden plik audio/wideo. Problem w tym, że mój plik wideo z 40 sekundami i plikiem audio ma 28 sekund. Więc przez pozostałe 12 (40-28) sekund - chcę powtórzyć od 0 sekund w pliku audio. Jak mam to zrobić? Czy istnieje bezpośredni sposób na zrobienie tego? – Hemang

Odpowiedz

12

Problem leży w:

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

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

Muszą być przenoszone na zewnątrz ciała pętli.

Powiązane problemy