Trim video without displaying UIVideoEditorController?
Asked Answered
C

2

12

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 ?

Chessboard answered 3/10, 2012 at 18:52 Comment(1)
can u provide me ur code for trimming video, where user can choose start and end time?Bundestag
C
17

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.

Chessboard answered 4/10, 2012 at 17:11 Comment(6)
@Khoool: outputUrl is provided for writing the trimmed video. It's a file path in document directoryChessboard
i m using same code but receiving error: Error in exporting NSString *path=[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) objectAtIndex:0]; path=[path stringByAppendingPathComponent:@"new.mov"]; NSLog(@"path to save video is %@",path); [self splitVideo:path];Yelenayelich
what are u passing in start and stop time. I think it will be clipped video start from or end to. right? Everything working fine except exporting videoYelenayelich
@Khoool: time to split the video, video start and stop timesChessboard
can i use same code for the video which is on Server??i just have the url of the video.please guide meDosh
Hi Error in exporting:4, can you helping this.Oxalate
B
2

We can import 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;
}
Brandonbrandt answered 25/2, 2014 at 12:1 Comment(4)
This answer is same as above, what is the advantage of duplicating the answerChessboard
It is not the Duplicating Answer.In this case, We are using another different solution.Brandonbrandt
In above answer also, it is using AVAssetExportSession. Here also the same thing, then what is the difference ?Chessboard
All functions is combined in one method with "Cache" Combine Output Url in 'AVAssetExportSession'. It is not helpFull for you But all other New Programmers.Brandonbrandt

© 2022 - 2024 — McMap. All rights reserved.