AVAssetExportSession 不遵守视频合成说明

AVAssetExportSession does not honour videocomposition instructions

我正在尝试在视频的 AVMutableComposition 上应用 AVMutableVideoCompositionLayerInstruction。问题是当使用 AVAssetExportSession 保存视频时它不遵守指令。奇怪的是,相同的组合适用于 AVPlayer(AVPlayer 遵循指令)。

代码如下:

        let path = Bundle.main.path(forResource: "flame", ofType: "mp4")
        let url = NSURL(fileURLWithPath: path!)
        let asset = AVAsset(url: url as URL)

        let mutableComposition = AVMutableComposition()

        let type = AVMediaTypeVideo
        let prefTrackID = kCMPersistentTrackID_Invalid

        let sourceVideoAssetTrack: AVAssetTrack = asset.tracks(withMediaType: type).first!
        let sourceAudioAssetTrack: AVAssetTrack = asset.tracks(withMediaType: AVMediaTypeAudio).first!

        let videoCompositionTrack1 = mutableComposition.addMutableTrack(withMediaType: type, preferredTrackID: prefTrackID)


        do {
            let range = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60,600))
            try videoCompositionTrack1.insertTimeRange(range, of: sourceVideoAssetTrack, at: kCMTimeZero)
        }catch { print(error) }

        let firstTransform = videoCompositionTrack1.preferredTransform;

        let fromLayer = AVMutableVideoCompositionLayerInstruction(assetTrack: videoCompositionTrack1)
        fromLayer.setTransform(firstTransform, at: kCMTimeZero)
        fromLayer.setCropRectangle(CGRect.init(x: 5, y: 5, width: 200, height: 200), at: kCMTimeZero)

        let instruction = AVMutableVideoCompositionInstruction()
        instruction.layerInstructions = [fromLayer]
        instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60,600))

        videoComposition = AVMutableVideoComposition()
        videoComposition!.instructions = [instruction]
        videoComposition!.renderSize = CGSize.init(width: 300, height: 300)
        videoComposition!.frameDuration = CMTimeMake(1, 30)


        if(true){ // just to switch between the saving and playing modes
            var exportPath: NSString = NSTemporaryDirectory().appendingFormat("/video.mov")
            var exportUrl: NSURL = NSURL.fileURL(withPath: exportPath as String) as NSURL

            var exporter = AVAssetExportSession(asset: mutableComposition, presetName: AVAssetExportPresetMediumQuality)!
            exporter.outputURL = exportUrl as URL
            exporter.videoComposition = videoComposition!

            exporter.outputFileType = AVFileTypeMPEG4
            exporter.shouldOptimizeForNetworkUse = true
            exporter.canPerformMultiplePassesOverSourceMediaData = true

            exporter.exportAsynchronously(completionHandler: {
                PHPhotoLibrary.shared().performChanges({
                    PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: exportUrl as URL)
                }) { completed, error in
                    if completed {
                        print("Video is saved!")
                    }
                }
            })
        }
        else{
            let playerItem = AVPlayerItem(asset: mutableComposition)
            playerItem.videoComposition = videoComposition!
            player = AVPlayer(playerItem: playerItem)
            playerLayer = AVPlayerLayer(player: player)
            playerLayer.frame = self.view.frame
            self.view.layer.addSublayer(playerLayer)
            player.play()
        }

AVPlayer 遵循如上所示的 cropRectangle 指令

保存的视频与原始视频相同。

我正在 iOS 9. 我做错了什么?

AVMutableVideoCompositionLayerInstruction 上应用变换时,您可以从 AVAssetpreferredTransform

中获得所需的变换

编辑:事实证明这是现有文件的导出错误,或者在尝试写入时使用唯一名称,例如

String(Date) + ".mov"

或尝试写入前删除