2016-03-08 38 views
1

我想將多個視頻合併爲一個。如何在iOS中使用AVAsset合併多個視頻?

但我不知道如何做到這一點,所以請幫我解決這個問題。

下面是我的代碼,但它不適合我。

AVMutableComposition* mixComposition = [AVMutableComposition composition]; 

AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) 
           ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] 
           atTime:kCMTimeZero error:nil]; 

AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo                      preferredTrackID:kCMPersistentTrackID_Invalid]; 
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) 
          ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] 
          atTime:kCMTimeZero error:nil]; 

AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition             presetName:AVAssetExportPresetHighestQuality]; 

NSString* videoName = @"export.mov"; 

NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName]; 
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath]; 

if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) 
{ 
    [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil]; 
} 
_assetExport.outputFileType = @"com.apple.quicktime-movie"; 
_assetExport.outputURL = exportUrl; 
_assetExport.shouldOptimizeForNetworkUse = YES; 

[_assetExport exportAsynchronouslyWithCompletionHandler: 
^(void) {  
     // your completion code here 
}]; 

我已經搜索了這個,但沒有答案爲我工作。

+0

你必須寫什麼麻煩,錯誤得到。描述錯誤。 – Tirth

+0

試試這個: - https://github.com/Datt1994/DPVideoMerger – Datt1994

回答

4

檢查我的代碼下面這個工作正確...

-(void)MergeVideo 
{ 
    AppDelegate *appdel = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 

    NSLog(@"Array Video Paths :- %@",appdel.arrVideoPath); 

    CGFloat totalDuration; 
    totalDuration = 0; 

    AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init]; 

    AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo 
                     preferredTrackID:kCMPersistentTrackID_Invalid]; 

    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio 
                    preferredTrackID:kCMPersistentTrackID_Invalid]; 

    CMTime insertTime = kCMTimeZero; 

    for (id object in appdel.arrVideoPath) 
    { 
     AVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:object]]; 

     CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration); 

     [videoTrack insertTimeRange:timeRange 
         ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] 
         atTime:insertTime 
          error:nil]; 

     [audioTrack insertTimeRange:timeRange 
         ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] 
         atTime:insertTime 
          error:nil]; 

     insertTime = CMTimeAdd(insertTime,asset.duration); 
    } 

    NSString* documentsDirectory= [self applicationDocumentsDirectory]; 
    myDocumentPath= [documentsDirectory stringByAppendingPathComponent:@"merge_video.mp4"]; 
    urlVideoMain = [[NSURL alloc] initFileURLWithPath: myDocumentPath]; 

    if([[NSFileManager defaultManager] fileExistsAtPath:myDocumentPath]) 
    { 
     [[NSFileManager defaultManager] removeItemAtPath:myDocumentPath error:nil]; 
    } 

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality]; 
    exporter.outputURL = urlVideoMain; 
    exporter.outputFileType = @"com.apple.quicktime-movie"; 
    exporter.shouldOptimizeForNetworkUse = YES; 

    [exporter exportAsynchronouslyWithCompletionHandler:^{ 

     switch ([exporter status]) 
     { 
      case AVAssetExportSessionStatusFailed: 
       break; 

      case AVAssetExportSessionStatusCancelled: 
       break; 

      case AVAssetExportSessionStatusCompleted: 
       break; 

      default: 
       break; 
     } 
    }]; 
} 

- (NSString*) applicationDocumentsDirectory 
{ 
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; 
    return basePath; 
} 
+0

它不關心方向! – hungbm06

2
{ 
    AVURLAsset *video01; 
    AVURLAsset *video02; 
    CGFloat totalDuration; 
    totalDuration = 0;  //initialization, keep it 0 

    AVMutableComposition *composition = [AVMutableComposition composition]; 

    AVMutableCompositionTrack *composedTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 


    for (int i = 0; i < [arrVideoPath count]; i++)  //arrVideoPath contains all video paths 

    { 
     if (i == 0) 
     { 
      video02 = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[arrVideoPath objectAtIndex:i]] options:nil]; 

      [composedTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, video02.duration) ofTrack:[[video02 tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil]; 
     } 
     else 
     { 
     video01 = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[arrVideoPath objectAtIndex:i-1]] options:nil]; 
     video02 = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[arrVideoPath objectAtIndex:i]] options:nil]; 

     float duration1 = CMTimeGetSeconds([video01 duration]); 
     totalDuration = totalDuration + duration1; 
     CMTime time1 = CMTimeMakeWithSeconds(totalDuration, 1); 

     [composedTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, video02.duration) ofTrack:[[video02 tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:time1 error:nil]; 
    } 

    NSString* documentsDirectory= [self applicationDocumentsDirectory]; 

    myDocumentPath= [documentsDirectory stringByAppendingPathComponent:@"merge_video.mp4"];   //myDocumentPath is NSString that gives path of output video(combined video) 


    urlVideoMain = [[NSURL alloc] initFileURLWithPath: myDocumentPath];  //urlVideoMain is Url of output video. 

    if([[NSFileManager defaultManager] fileExistsAtPath:myDocumentPath]) 
    { 
     [[NSFileManager defaultManager] removeItemAtPath:myDocumentPath error:nil]; 
    }  //removes previous video at same path, essential 


    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality]; 

    exporter.outputURL = urlVideoMain; 

    exporter.outputFileType = @"com.apple.quicktime-movie"; 

    exporter.shouldOptimizeForNetworkUse = YES; 

    [exporter exportAsynchronouslyWithCompletionHandler:^{ 

     switch ([exporter status]) { 

      case AVAssetExportSessionStatusFailed: 

       break; 

      case AVAssetExportSessionStatusCancelled: 

       break; 

      case AVAssetExportSessionStatusCompleted: 

       break; 

      default: 

       break; 

     } 

    }]; 

} 


-(NSString*) applicationDocumentsDirectory 
{ 

     NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

     NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; 

     return basePath; 

} 
+0

這是我的代碼成功運行。它可以合併多個視頻。不要更改任何值,除了視頻路徑數組。 –

+0

雖然這不處理方向。 [這解決了它。](http://stackoverflow.com/questions/12136841/avmutablevideocomposition-rotated-video-captured-in-portrait-mode/21980070#21980070) – bp14

相關問題