AVAssetExportSession第一次工作但是如果我再试一次就会失败 - 视频无法合成

时间:2016-04-12 15:50:38

标签: ios swift video avassetexportsession

我正在开发一个应用程序,人们可以在视频上叠加水印,到目前为止我已经能够成功完成。但是,在我第一次使用自定义覆盖保存视频后,如果我再次尝试保存视频,则会因所述错误而失败:

  

可选(错误域= AVFoundationErrorDomain代码= -11841“操作已停止”UserInfo = {NSLocalizedDescription =操作已停止,NSLocalizedFailureReason =视频无法合成。})

以下是我保存视频的代码:

   @IBAction func saveVideo(sender: AnyObject) {

    self.videoAsset = AVAsset(URL: fileURL as NSURL!)

    // Create Video track (Video + Audio)
    let videoTrack: AVMutableCompositionTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
    let audioTrack:AVMutableCompositionTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

    do {
        try videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration), ofTrack: self.videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] , atTime: kCMTimeZero)
        try audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration), ofTrack: self.videoAsset.tracksWithMediaType(AVMediaTypeAudio)[0] , atTime: kCMTimeZero)
        print("Inserted time ranges just fine\n")
    } catch let error as NSError {
        print("Failed to insert video/audio tracks!!!!\n")
        print(error.localizedDescription)
    }

    videoLayerIntruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
    let videoAssetTrack: AVAssetTrack = self.videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]

    var videoAssetOrientation_: UIImageOrientation = .Up
    var isVideoAssetPortrait_: Bool = false

    let videoTransform:CGAffineTransform = videoAssetTrack.preferredTransform

    if videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0 {
        videoAssetOrientation_ = .Right
        isVideoAssetPortrait_ = true
    }
    if videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0 {
        videoAssetOrientation_ = .Left
        isVideoAssetPortrait_ = true
    }
    if videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0 {
        videoAssetOrientation_ = .Up
    }
    if videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0 {
        videoAssetOrientation_ = .Down
    }

    videoLayerIntruction.setTransform(videoAssetTrack.preferredTransform, atTime: kCMTimeZero)

    mainInstruction.layerInstructions = [videoLayerIntruction]
    mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration)


    var naturalSize = CGSize()

    if isVideoAssetPortrait_ {
        naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width)
    } else {
        naturalSize = videoAssetTrack.naturalSize
    }

    renderWidth = naturalSize.width
    renderHeight = naturalSize.height

    parentLayer.frame = CGRectMake(0, 0, renderWidth, renderHeight)
    parentLayer.geometryFlipped = true
    parentLayer.anchorPoint = CGPointMake(0.5, 0.5)

    videoLayer.frame = CGRectMake(0, 0, renderWidth, renderHeight)

    self.overlayLayer.frame = CGRectMake(self.renderWidth, self.renderHeight, self.newRatioWidth, self.newRatioHeight)
    self.overlayLayer.addAnimation(self.animation, forKey: "contents")
    self.overlayLayer.anchorPoint = CGPointMake(0.5, 0.5)
    self.overlayLayer.contentsGravity = kCAGravityResizeAspect

    parentLayer.addSublayer(videoLayer)

    if addedOverlay == true {
        parentLayer.addSublayer(overlayLayer)
    }

    mainCompositionInst.renderScale = 1.0
    mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight)
    mainCompositionInst.instructions = [mainInstruction]
    mainCompositionInst.frameDuration = CMTimeMake(1, 30)
    mainCompositionInst.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)

    outputURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("CreatedVideo-\(NSUUID().UUIDString).mov")

    let exporter: AVAssetExportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)!
    exporter.outputURL = outputURL
    exporter.outputFileType = AVFileTypeQuickTimeMovie
    exporter.shouldOptimizeForNetworkUse = false
    exporter.videoComposition = mainCompositionInst

    exporter.exportAsynchronouslyWithCompletionHandler({
        dispatch_async(dispatch_get_main_queue(), {
            self.exportVideo(exporter)
            switch exporter.status{
            case  AVAssetExportSessionStatus.Failed:
                print("FAILED EXPORT - \(exporter.error)\n")
            case AVAssetExportSessionStatus.Cancelled:
                print("canceled \(exporter.error)\n")
            default:
                print("COMPLETED EXPORT\n")
            }
        })
    })
}

func exportVideo(sender: AVAssetExportSession) {
    print("Asked to export\n")
    PHPhotoLibrary.sharedPhotoLibrary().performChanges({
    PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(sender.outputURL!)
        }, completionHandler: { success, error in
            if success {
                print("Success! Finished saving video.")
            } else {
                print("ERROR - " + (error?.localizedDescription)!)
            }
    })
}

有没有人知道在第一次成功工作后组合物开始失败的原因是什么?会喜欢任何建议!

1 个答案:

答案 0 :(得分:0)

正如SeanLintern88指出的那样,这个问题的解决方案可以在这里找到: stackoverflow.com/a/31146867/1638273