AVAssetExportSession 后保存到相册的视频没有声音

After AVAssetExportSession, video saved to Photos album has no audio

我正在录制视频并从 UIImagePickerController 添加水印。

当我录制视频并使用默认录像机播放时,有声音。但是,我添加水印并将视频保存到我的相册后,就没有声音了。

关于我做错了什么有什么想法吗?

谢谢。

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

        let videoPath = info[UIImagePickerControllerMediaURL] as! NSURL

        let stringVideoPath = videoPath.path

        //add watermark starting here

        let videoAsset = AVURLAsset(URL: videoPath)
        let mixComposition = AVMutableComposition()
        let compositionVideoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
        let clipVideoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
        do {
        try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), ofTrack: clipVideoTrack, atTime: kCMTimeZero)
        } catch {
            print("error")
        }


        compositionVideoTrack.preferredTransform = clipVideoTrack.preferredTransform


        //create the watermark image
        let myImage = UIImage(named: "watermarkImage.png")
        let aLayer = CALayer()
        aLayer.contents = myImage?.CGImage
        aLayer.frame = CGRectMake(5, 25, 100, 60)
        aLayer.opacity = 1.0

        //sort layer
        let videoSize = clipVideoTrack.naturalSize
        let parentLayer = CALayer()
        let videoLayer = CALayer()
        parentLayer.frame = CGRectMake(0, 0, videoSize.height, videoSize.width)
        videoLayer.frame = CGRectMake(0, 0, videoSize.height, videoSize.width)
        parentLayer.addSublayer(videoLayer)
        parentLayer.addSublayer(aLayer)

        //create composition and add instructions to insert the layer

        let videoComp = AVMutableVideoComposition()
        videoComp.renderSize = CGSize(width: videoSize.height, height: videoSize.width)
        videoComp.frameDuration = CMTimeMake(1, 30)
        videoComp.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)

        //instructions
        let mainInstruction = AVMutableVideoCompositionInstruction()
        mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, mixComposition.duration)
        let videoTrack = mixComposition.tracksWithMediaType(AVMediaTypeVideo)[0]
        let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)

        layerInstruction.setTransform(compositionVideoTrack.preferredTransform, atTime: kCMTimeZero)


        mainInstruction.layerInstructions = [layerInstruction] 
        videoComp.instructions = [mainInstruction]

        let assetExport = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetMediumQuality)
        assetExport?.videoComposition = videoComp
        let exportPath = NSTemporaryDirectory().stringByAppendingString("TestVideo.mp4")
        let exportURL = NSURL(fileURLWithPath: exportPath)

        if NSFileManager.defaultManager().fileExistsAtPath(exportPath) {
            do { try NSFileManager.defaultManager().removeItemAtPath(exportPath)} catch{}
        }

        assetExport?.outputFileType = AVFileTypeMPEG4
        assetExport?.outputURL = exportURL
        assetExport?.shouldOptimizeForNetworkUse = true
        assetExport?.exportAsynchronouslyWithCompletionHandler({ () -> Void in
            print("done")
            UISaveVideoAtPathToSavedPhotosAlbum(exportURL.path!, self, nil, nil)
        })

        picker.dismissViewControllerAnimated(true, completion: nil)
        picker.view.superview?.removeFromSuperview()

    }

你没有做错任何事。您向 AVMutableComposition 添加了视频轨道,但从未添加音频轨道,因此自然没有音频。在您的代码中查找术语 "audio":它从未出现!如果需要音频,请添加音频,就像添加视频一样(除了您将获取音频轨道而不是视频轨道)。

换句话说,重复这段代码:

let compositionVideoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
let clipVideoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
do {
    try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), ofTrack: clipVideoTrack, atTime: kCMTimeZero)
} catch {
    print("error")
}

...除非你在该代码中看到 "Video" 的任何地方,请输入 "Audio".