将MTAudioProcessingTap与AVAssetExportSession

时间:2017-05-13 08:45:07

标签: ios swift avfoundation core-audio avassetexportsession

我正在尝试使用AVAssetExportSession导出mutablecomposition。我正在使用MTAudioProcessingTap处理mutablecomposition中的音频数据,并根据音频数据,使用AVVideoCompositionCoreAnimationTool修改mutablecomposition中的一些动画。我希望这是实时发生的,因为动画取决于音频数据。如果我使用AVPlayer,这可以正常工作,但与AVAssetExportSession不同。好像MTAudioProcessingTapProcessCallback中收到的音频数据与AVAssetExportSession中的视频不同步。所以这里的问题是,是否有人知道它们是否应该在AVAssetExportSession期间同步?

这是我的MTAudioProcessingTapProcessCallback

var tapProcess: MTAudioProcessingTapProcessCallback = {
    (tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut) in
            let status = MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut)

            let viewController = MTAudioProcessingTapGetStorage(tap)

            let viewController = Unmanaged<CanvasViewController>.fromOpaque(viewController).takeUnretainedValue()

            DispatchQueue.main.sync {
                // update my CALayer in viewController based on the audio data
            }
        }

以下是设置audiomix的代码:

func setupAudioMix(audioTrack: AVAssetTrack) -> AVAudioMix {
        var callbacks = MTAudioProcessingTapCallbacks(
            version: kMTAudioProcessingTapCallbacksVersion_0,
            clientInfo: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
            init: tapInit,
            finalize: tapFinalize,
            prepare: tapPrepare,
            unprepare: tapUnprepare,
            process: tapProcess)

        var tap: Unmanaged<MTAudioProcessingTap>?
        let err = MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &tap)

        print("err: \(err)\n")
        if err == noErr {
        }

        let inputParams = AVMutableAudioMixInputParameters(track: audioTrack)
        inputParams.audioTapProcessor = tap?.takeUnretainedValue()

        let audioMix = AVMutableAudioMix()
        audioMix.inputParameters = [inputParams]

        return audioMix
    }

将audiomix附加到AVAssetExportSession:

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

        exporter!.outputFileType = AVFileTypeMPEG4
        exporter!.shouldOptimizeForNetworkUse = true

1 个答案:

答案 0 :(得分:0)

不,AVAssetExportSession不承诺在处理类似定时视频帧之前,之后或期间调用音频抽头。

考虑一下,AVAudioPlayerAVPlayer?)也没有想到 - 所以也许你在那里幸运。

根据您生成帧的方式,AVAssetExportSession的运行速度可能超过正常播放速度的1倍。

如果您需要将同步的视频导出为音频,则可能需要较低级别的AVAssetWriter API。