8

I want to trim a video file. I want to just pick the video from a gallery and convert it to a 15-second video. If I use normal trimming with picker view controller, it does not specify a time and just shows the frames, but I need to be fixed for 15 seconds. How can I achieve this?

Ramkumar Paulraj
  • 1,841
  • 2
  • 20
  • 40

2 Answers2

17

Objective-C

-(void)cropVideo:(NSURL*)videoToTrimURL{
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoToTrimURL options:nil];
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *outputURL = paths[0];
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager createDirectoryAtPath:outputURL withIntermediateDirectories:YES attributes:nil error:nil];
    outputURL = [outputURL stringByAppendingPathComponent:@"output.mp4"];
    // Remove Existing File
    [manager removeItemAtPath:outputURL error:nil];


    exportSession.outputURL = [NSURL fileURLWithPath:outputURL];
    exportSession.shouldOptimizeForNetworkUse = YES;
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;
    CMTime start = CMTimeMakeWithSeconds(1.0, 600); // you will modify time range here
    CMTime duration = CMTimeMakeWithSeconds(15.0, 600);
    CMTimeRange range = CMTimeRangeMake(start, duration);
    exportSession.timeRange = range;
    [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
     {
         switch (exportSession.status) {
             case AVAssetExportSessionStatusCompleted:
                 [self writeVideoToPhotoLibrary:[NSURL fileURLWithPath:outputURL]];
                 NSLog(@"Export Complete %d %@", exportSession.status, exportSession.error);
                 break;
             case AVAssetExportSessionStatusFailed:
                 NSLog(@"Failed:%@",exportSession.error);
                 break;
             case AVAssetExportSessionStatusCancelled:
                 NSLog(@"Canceled:%@",exportSession.error);
                 break;
             default:
                 break;
         }

         //[exportSession release];
     }];
}

In Swift 4.0

    static func cropVideo(atURL url:URL) {
    let asset = AVURLAsset(url: url)
    let exportSession = AVAssetExportSession.init(asset: asset, presetName: AVAssetExportPresetHighestQuality)!
    var outputURL = URL(string:NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last!)

    let fileManager = FileManager.default
    do {
        try fileManager.createDirectory(at: outputURL!, withIntermediateDirectories: true, attributes: nil)
    } catch {

    }

    outputURL?.appendPathComponent("output.mp4")
    // Remove existing file
    do {
        try fileManager.removeItem(at: outputURL!)
    }
    catch {

    }

    exportSession.outputURL = outputURL
    exportSession.shouldOptimizeForNetworkUse = true
    exportSession.outputFileType = AVFileTypeQuickTimeMovie
    let start = CMTimeMakeWithSeconds(1.0, 600) // you will modify time range here
    let duration = CMTimeMakeWithSeconds(15.0, 600)
    let range = CMTimeRangeMake(start, duration)
    exportSession.timeRange = range
    exportSession.exportAsynchronously {
        switch(exportSession.status) {
        case .completed: break
            //
        case .failed: break
            //
        case .cancelled: break
            //
        default: break
        }
    }
}
HAK
  • 2,023
  • 19
  • 26
Ramkumar Paulraj
  • 1,841
  • 2
  • 20
  • 40
  • If we vary the the time start&duration then sometimes its not trimming the video right.Can you please check this one. – Imran Jan 16 '14 at 10:42
  • @ram my video duration is 60 second i want to remove from 15 to 30 second – sohil Aug 10 '17 at 09:06
  • CMTime start = CMTimeMakeWithSeconds(15, 600); // you will modify CMTime duration = CMTimeMakeWithSeconds(30, 600); @sohil it will work for you – Ramkumar Paulraj Aug 10 '17 at 09:17
  • @ram i said to you again i don't want to cut the video from beginning as you said but actually i want to cut video from 15 second to 30 second (Note : not cut from beginning). – sohil Aug 10 '17 at 10:54
  • @ram, I am using this code but after trim the video audio is gone can give me any suggestion how trim the video without gone the audio. – pansora abhay Mar 16 '19 at 05:52
1

The above answer worked for me with a little change in case we need to set both start time and end time to trim.

I changed this:

CMTime start = CMTimeMakeWithSeconds(1.0, 600); // you will modify time range here
CMTime duration = CMTimeMakeWithSeconds(15.0, 600);
CMTimeRange range = CMTimeRangeMake(start, duration);

To this:

CMTime start = CMTimeMakeWithSeconds(self.StartTime, 600); // you will modify time range here
    CMTime duration = CMTimeSubtract(CMTimeMakeWithSeconds(self.EndTime, 600), start);
    CMTimeRange range = CMTimeRangeMake(start, duration);

It worked for me.

Imran
  • 1,715
  • 2
  • 20
  • 42