5

I want to trim a video:

-(void)trimVideo:(NSURL*)outputURL
{
    //[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:outputURL options:nil];
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetLowQuality];

    NSString * outputFilePath = NSHomeDirectory();
    outputFilePath = [outputFilePath stringByAppendingPathComponent:@"Library"];
    outputFilePath = [outputFilePath stringByAppendingPathComponent:@"temp.mov"];
    NSURL * outputFileUrl = [NSURL fileURLWithPath:outputFilePath];

    exportSession.outputURL =  outputFileUrl;
    exportSession.shouldOptimizeForNetworkUse = YES;
    exportSession.outputFileType = AVFileTypeMPEG4;
    CMTime start = CMTimeMakeWithSeconds(1.0, 600);
    CMTime duration = CMTimeMakeWithSeconds(3.0, 600);
    CMTimeRange range = CMTimeRangeMake(start, duration);
    exportSession.timeRange = range;
    [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
     {
         NSLog(@"Export Complete %d %@", exportSession.status, exportSession.error);
         //[exportSession release];
     }];
}

But I get the error:

Export Complete 4 Error Domain=AVFoundationErrorDomain Code=-11823 "Cannot Save" UserInfo=0x2008f420 {NSLocalizedRecoverySuggestion=Try saving again., NSLocalizedDescription=Cannot Save}

Not exactly sure how to resolve.

Sheehan Alam
  • 60,111
  • 124
  • 355
  • 556

1 Answers1

18

This did the trick:

-(void)trimVideo:(NSURL*)videoToTrimURL
{
    //[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
    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);
    CMTime duration = CMTimeMakeWithSeconds(3.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];
     }];
}
Sheehan Alam
  • 60,111
  • 124
  • 355
  • 556
  • getting error :-- [manager writeVideoToPhotoLibrary:[NSURL fileURLWithPath:outputURL]]; – Prince Kumar Sharma Dec 12 '12 at 07:12
  • HELLO Khoool, you have to create that method in your class. -(void)writeVideoToPhotoLibrary:(NSURL *)nsurlToSave{ ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; NSURL *recordedVideoURL= nsurlToSave; if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:recordedVideoURL]) { [library writeVideoAtPathToSavedPhotosAlbum:recordedVideoURL completionBlock:^(NSURL *assetURL, NSError *error){} ]; } [library release] } – TurboManolo Dec 19 '12 at 11:42
  • Finally after a few hours! you fixed this problem. fileURLWithPath works wonders. – jgvb Jun 27 '14 at 20:28
  • 9
    The issue was trying to write to a file that already existed. removeItemAtPath deleted that file before the export and resolved the issue. – David Pettigrew Nov 15 '14 at 20:55
  • Why I didn't find your answer earlier? I got stuck with a bunch of other examples with a AVMutableCompositions, tracks and things like so... – Azat Nov 13 '16 at 20:08
  • I had this problem, and as @DavidPettigrew mentioned, it was trying to write to a file that already existed. Check that the "outputURL" is unique. – coco Apr 28 '17 at 03:30
  • @DavidPettigrew Thanks David! For anyone here in 2018 with Swift 4 it's: ```FileManager.default.removeItem(atPath: exportPath)``` – AdjunctProfessorFalcon Feb 01 '18 at 06:39