Search code examples
iosxcodevideouivideoeditorcontroller

Trim video without displaying UIVideoEditorController?


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 ?


Solution

  • 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.