Gaz Long
Gaz Long

Reputation: 367

(Cocoa error -1) When attempting to save video created with AVCaptureSession

I'm generating a video using an AVCapture session and then using an AVVideoCompositionCoreAnimationTool to add a simple overlay. I then use an AVAssetExportSession to output the file. This all seems to work but then when I attempt to save it to the Photo Library using PHPhotoLibrary (because ALAssetsLibrary has been depreciated) is fails with the message:"Cant complete operation cocoa error -1". After extensive Google use and checking the docs I can't work out whats going wrong.

The problem

Any help would be great thanks.

 func videoOutput() {


    videoToMake = AVAsset(URL: videoToMakeURL!)

    if (videoToMake == nil) {

        return
    }


    //This holds the different tracks of the video like audio and the layers
    let mixComposition = AVMutableComposition()

    let videoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

    print("The duration of the video to create is \(videoToMake!.duration.seconds)")

    do{
       try videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero,videoToMake!.duration), ofTrack: videoToMake!.tracksWithMediaType(AVMediaTypeVideo)[0], atTime: kCMTimeZero)
    }catch let error as NSError{
         print("Error inserting time range on video track \(error.localizedDescription)")
         return
    }catch{
        print("An unknown error occured")
    }

    //Make the instructions for the other layers
    let mainInstrucation = AVMutableVideoCompositionInstruction()
    mainInstrucation.timeRange = CMTimeRangeMake(kCMTimeZero, videoToMake!.duration)

    //Create the layer instructions
    let videoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
    let videoAssetTrack = videoToMake!.tracksWithMediaType(AVMediaTypeVideo)[0]


    let assetInfo = orientationFromTransform(videoAssetTrack.preferredTransform)
    // sort size it in respect to the video orientation.

    videoLayerInstruction.setTransform(videoAssetTrack.preferredTransform, atTime: kCMTimeZero)
    videoLayerInstruction.setOpacity(0.0, atTime:videoToMake!.duration)

    //Add the instructions
    mainInstrucation.layerInstructions = [videoLayerInstruction]
    let mainCompositionInst = AVMutableVideoComposition()

    var naturalSize:CGSize
    if assetInfo.isPortrait {
        naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width);
    }else{
        naturalSize = videoAssetTrack.naturalSize
    }

    let renderWidth = naturalSize.width
    let renderHeight = naturalSize.height

    mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight)
    mainCompositionInst.instructions = [mainInstrucation]
    mainCompositionInst.frameDuration = CMTimeMake(1, 30);

    //So now the main composition has been created add the video affects
    applyVideoEffectsToComposition(mainCompositionInst, size: naturalSize)

    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask, true)
    let documentsDirectory = paths[0]
    let random = Int(arc4random_uniform(1000))
    let url = NSURL(fileURLWithPath:documentsDirectory).URLByAppendingPathComponent("FinalVideo\(random)")

    //Create the exporter 
    let exporter = AVAssetExportSession(asset: mixComposition, presetName:AVAssetExportPresetHighestQuality)
    exporter!.outputURL = url
    exporter!.outputFileType = AVFileTypeMPEG4
    exporter!.shouldOptimizeForNetworkUse = true
    exporter!.videoComposition = mainCompositionInst

    //Perform the export
    exporter!.exportAsynchronouslyWithCompletionHandler() {
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
           self.exportDidFinish(exporter!)
       })
    }
}

Upvotes: 2

Views: 6406

Answers (1)

Gaz Long
Gaz Long

Reputation: 367

Well it turns out I was missing the extension from the end of my movie name:

let url = NSURL(fileURLWithPath:documentsDirectory).URLByAppendingPathComponent("FinalVideo\(random)")

So it should have been "FinalVideo(random).mov"

Hope this helps somebody one day.

Upvotes: 3

Related Questions