Thursday, September 30, 2010

Create Movie Using AVFoundation

Steps to Create Movie Using AVFoundation:-
1. Create a AVMutableComposition
CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent(); //Debug purpose - used to calculate the total time taken
NSError *error = nil;
AVMutableComposition *saveComposition = [AVMutableComposition composition];
2. Get the video and audio file path
NSString *tempPath = NSTemporaryDirectory();
NSString *videoPath = nil ;//<Video file path>;
NSString *audioPath = nil ;//<Audio file path>;;
3. Create the video asset 
NSURL * url1 = [[NSURL alloc] initFileURLWithPath:videoPath];
AVURLAsset *video = [AVURLAsset URLAssetWithURL:url1 options:nil];
[url1 release];
4. Get the AVMutableCompositionTrack for video and add the video track to it.
The method insertTimeRange: ofTrack: atTime: decides the what portion of the video to be added and also where the video track should appear in the final video created.
AVMutableCompositionTrack *compositionVideoTrack = [ addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipVideoTrack = [[video tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [video duration])  ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil];
NSLog(@"%f %@",CMTimeGetSeconds([video duration]),error);

5. Create the Audio asset 
NSURL * url2 = [[NSURL alloc] initFileURLWithPath:audioPath];
AVURLAsset *audio = [AVURLAsset URLAssetWithURL:url2 options:nil];
[url2 release];

6. Get the AVMutableCompositionTrack for audio and add the audio track to it.
AVMutableCompositionTrack *compositionAudioTrack = [saveComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipAudioTrack = [[audio tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [audio duration])  ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];
NSLog(@"%f %@",CMTimeGetSeconds([audio duration]),error);
7. Get file path for of the final video.
NSString *path = [tempPath stringByAppendingPathComponent:@"mergedvideo.mov"];
if([[NSFileManager defaultManager] fileExistsAtPath:path])
{
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}
NSURL *url = [[NSURL alloc] initFileURLWithPath: path];

8. Create the AVAssetExportSession and set the preset to it.
The completion handler will be called upon the completion of the export.
AVAssetExportSession *exporter = [[[AVAssetExportSession alloc] initWithAsset:saveComposition presetName:AVAssetExportPresetHighestQuality] autorelease];
exporter.outputURL=url;
exporter.outputFileType=[[exporter supportedFileTypes] objectAtIndex:0];
[exporter exportAsynchronouslyWithCompletionHandler:^{
NSLog(@"export completed : %lf",CFAbsoluteTimeGetCurrent()-currentTime);
}];

The above technique can be used to merge N number of video and audio tracks and create a movie. I hope this tutorial helps to create movie using AVFoundation.


4 comments:

  1. sir,
    here i export the video is succeeded but when i play the video it just displays the blank screen what is the problem sir

    ReplyDelete
  2. Can you post the code. Let me see if I can help you out.

    ReplyDelete
  3. sir,
    The code will be crash at

    AVAssetTrack *clipVideoTrack = [[video tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

    ReplyDelete
  4. its just because you are not adding the AVMutableCompositionTrack object to the main AVMutableComposition object having name saveCompostion....
    AVMutableCompositionTrack *compositionVideoTrack = [ addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];=====>incorrect

    AVMutableCompositionTrack *compositionVideoTrack = [ saveComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

    do above changes ....i guess it will work

    ReplyDelete