Recortar video sin mostrar UIVideoEditorController?

Actualmente estoy trabajando en una aplicación que trata con los videos. En mi aplicación, el usuario puede recortar el video, tengo un control personalizado para seleccionar la hora de inicio y la hora de finalización. Necesito recortar el video con estos dos valores. Intenté con UIVideoEditorController como sigue.

  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 ); } 

Pero el problema es que el código anterior mostrará el control del editor de video de Apple y el usuario puede hacer algunas operaciones en esa vista. No deseo mostrar esta vista porque ya he mostrado el video en MPMoviePlayer y MPMoviePlayer recibido la input del usuario ( hora de inicio y hora de finalización ) para recortar el video en un control personalizado. ¿Cómo puedo recortar un video sin mostrar UIVideoEditorController ?

Finalmente encontré la solución.

Podemos usar AVAssetExportSession para recortar video sin mostrar UIVideoEditorController .

Mi código es como:

 - (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]); } } 

Este método recorta el 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]); } } 

Este método verifica el estado del recorte:

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

Estoy llamando al método splitVideo desde el método de acción del button de export y pasa la URL de salida como argumento.

Podemos importar AVFoundation / AVFoundation.h

 -(BOOL)trimVideofile { float videoStartTime;//define start time of video float videoEndTime;//define end time of video NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *libraryCachesDirectory = [paths objectAtIndex:0]; libraryCachesDirectory = [libraryCachesDirectory stringByAppendingPathComponent:@"Caches"]; NSString *OutputFilePath = [libraryCachesDirectory stringByAppendingFormat:@"/output_%@.mov", [dateFormatter stringFromDate:[NSDate date]]]; NSURL *videoFileOutput = [NSURL fileURLWithPath:OutputFilePath]; NSURL *videoFileInput;//<Path of orignal Video file> if (!videoFileInput || !videoFileOutput) { return NO; } [[NSFileManager defaultManager] removeItemAtURL:videoFileOutput error:NULL]; AVAsset *asset = [AVAsset assetWithURL:videoFileInput]; AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetLowQuality]; if (exportSession == nil) { return NO; } CMTime startTime = CMTimeMake((int)(floor(videoStartTime * 100)), 100); CMTime stopTime = CMTimeMake((int)(ceil(videoEndTime * 100)), 100); CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime); exportSession.outputURL = videoFileOutput; exportSession.timeRange = exportTimeRange; exportSession.outputFileType = AVFileTypeQuickTimeMovie; [exportSession exportAsynchronouslyWithCompletionHandler:^ { if (AVAssetExportSessionStatusCompleted == exportSession.status) { NSLog(@"Export OK"); } else if (AVAssetExportSessionStatusFailed == exportSession.status) { NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]); } }]; return YES; }