ios - 将 MTAudioProcessingTap 与 AVAssetExportSession 结合使用

标签 ios swift avfoundation core-audio avassetexportsession

我正在尝试使用 AVAssetExportSession 导出可变组合。我使用 MTAudioProcessingTap 处理可变组合中的音频数据,并根据音频数据,使用 AVVideoCompositionCoreAnimationTool 修改可变组合中的一些动画。我希望这是实时发生的,因为动画取决于音频数据。如果我使用 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
            }
        }

下面是设置音频混合的代码:

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
    }

并将音频混合附加到 AVAssetExportSession:

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

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

最佳答案

不,AVAssetExportSession 不 promise 在处理类似时间的视频帧之前、之后或期间调用音频点击。

想想看,AVAudioPlayer(AVPlayer?)也没有 - 所以也许你只是运气好而已。

根据您生成帧的方式,AVAssetExportSession 的运行速度可能比正常播放速度的 1 倍快,这可能与此相关。

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

关于ios - 将 MTAudioProcessingTap 与 AVAssetExportSession 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43951082/

相关文章:

ios - Size Classe 是否有 Regular 和 Compact 的规则?

xcode - Swift 中的直播

ios - 如何使用 AVCapturePhotoOutput

iphone - AVAssetExportSession dealloc 在 iOS 4.3 中崩溃

ios - AVPreviewLayer 内容重力未填充图层

ios - addSubView - 在 UIView 中添加一个按钮也会为其 SuperView 添加相同的按钮

javascript - 在 Swift 中循环遍历 JavaScript 元素,WKWebView

ios - 如何动态地将 subview 添加到表格 View 单元格

ios - RxSwift Input Output, private subject 但在类外被触发

swift - 调用函数后改变位置