How to merge multiple videos using AVAsset in iOS?

允我心安 提交于 2019-12-07 23:41:28

Check my code below this works correct...

-(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;
}
{ 
   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;

 }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!