2013-01-09 2 views
8

У меня есть странная проблема. В моем приложении я объединяю несколько аудио- и видеофайлов, используя приведенный ниже код. Приведенное видео, кажется, отлично работает, как только я загрузил его с устройства на компьютер и играл с Quick Time, но всякий раз, когда я пытаюсь воспроизвести вновь созданное видео с помощью UIWebView или AVPLayer, я могу видеть только первую часть объединенных видеофайлов.Составление видео и аудио с использованием AVMutableComposition

Кроме того, когда я пытался использовать MPMoviePlayerController для воспроизведения, он зависает на «Загрузка».

Я могу слышать аудио для всех композиций. Чтобы было ясно, у меня есть два массива: 1- audioPieces с дорожками к аудиофайлам [song1, song2, song3]; 2- кинофильмы с путями к видеофайлам [movie1, movie2, movie3]; После слияния этих файлов я вижу только фильм1, но я могу слышать песню 1 + song2 + song3. P.S. песни и фильмы имеют разную длину (разница меньше 0,2 с). Любая помощь будет оценена по достоинству. Спасибо заранее, 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

Я только объединяю один аудио/видео файл. Проблема в том, что мой видеофайл в 40 секунд и аудиофайл составляет 28 секунд. Итак, для оставшихся 12 (40-28) секунд - я хочу повторить его с 0 секунд в аудиофайле. Как мне это? Есть ли прямой способ сделать это? – Hemang

ответ

12

Проблема лежит в:

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

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

Они должны быть перемещены снаружи для тела цикла.

Смежные вопросы