Currently I'm working on a application which deals with the videos.
In my application user can trim the video, I have a custom control for selecting the start time and end time. I need to trim the video by these two values. I tried with UIVideoEditorController
like follows.
UIVideoEditorController* videoEditor = [[[UIVideoEditorController alloc] init] autorelease];
videoEditor.delegate = self;
NSString* videoPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"MOV"];
if ( [UIVideoEditorController canEditVideoAtPath:videoPath] )
{
videoEditor.videoPath = videoPath;
[self presentModalViewController:videoEditor animated:YES];
}
else
{
NSLog( @"can't edit video at %@", videoPath );
}
But the issue is the above code will display apple's video editor control and user can do some operations on that view. I don't want to display this view, because I have already displayed the video on MPMoviePlayer
and received the user input (start time and end time) for trimming the video on a custom control.
How can I trim a video without displaying UIVideoEditorController
?
Finally I found the solution.
We can use AVAssetExportSession
for trimming video without displaying UIVideoEditorController
.
My code is like:
- (void)splitVideo:(NSString *)outputURL
{
@try
{
NSString *videoBundleURL = [[NSBundle mainBundle] pathForResource:@"Video_Album" ofType:@"mp4"];
AVAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:videoBundleURL] options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset];
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
[self trimVideo:outputURL assetObject:asset];
}
videoBundleURL = nil;
[asset release];
asset = nil;
compatiblePresets = nil;
}
@catch (NSException * e)
{
NSLog(@"Exception Name:%@ Reason:%@",[e name],[e reason]);
}
}
This method trims the video
- (void)trimVideo:(NSString *)outputURL assetObject:(AVAsset *)asset
{
@try
{
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:asset presetName:AVAssetExportPresetLowQuality];
exportSession.outputURL = [NSURL fileURLWithPath:outputURL];
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
CMTime start = CMTimeMakeWithSeconds(splitedDetails.startTime, 1);
CMTime duration = CMTimeMakeWithSeconds((splitedDetails.stopTime - splitedDetails.startTime), 1);
CMTimeRange range = CMTimeRangeMake(start, duration);
exportSession.timeRange = range;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[self checkExportSessionStatus:exportSession];
[exportSession release];
exportSession = nil;
}
@catch (NSException * e)
{
NSLog(@"Exception Name:%@ Reason:%@",[e name],[e reason]);
}
}
This method checks the status of trimming:
- (void)checkExportSessionStatus:(AVAssetExportSession *)exportSession
{
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
switch ([exportSession status])
{
case AVAssetExportSessionStatusCompleted:
NSLog(@"Export Completed");
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"Error in exporting");
break;
default:
break;
}
}];
}
I'm calling the splitVideo
method from the export button action method and passes the output URL as argument.