繁体   English   中英

Swift代码使用AVWriter/AVReader从.mp4视频中提取.wav音频写入零字节文件

[英]Swift code to use AVWriter/AVReader to extract .wav audio from .mp4 video writing zero byte file

我已经浏览了这里的文档和所有帖子,我已经走到了这一步。

下面的 function 应该取一个 AVAsset 并写出一个.wav 文件。 但是,写出的文件是零字节。 我不确定我什至可以检查作者在每一步都在写什么。

我错过了什么?

    static func writeAudioTrackToUrl(asset: AVAsset, _ url: URL) throws {
    // initialize asset reader, writer
    let assetReader = try AVAssetReader(asset: asset)
    let assetWriter = try AVAssetWriter(outputURL: URL(fileURLWithPath: "/tmp/audiowav.wav"), fileType: .wav)
    
    // get audio track
    let audioTrack = asset.tracks(withMediaType: AVMediaType.audio).first!
    
    // configure output audio settings
    let audioSettings: [String : Any] = [
        AVFormatIDKey: kAudioFormatLinearPCM,
        AVSampleRateKey: 22050.0,
        AVNumberOfChannelsKey: 1,
        AVLinearPCMBitDepthKey: 16,
        AVLinearPCMIsFloatKey: false,
        AVLinearPCMIsBigEndianKey: false,
        AVLinearPCMIsNonInterleaved: false
    ]
    let assetReaderAudioOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: audioSettings)
    
    if assetReader.canAdd(assetReaderAudioOutput) {
        assetReader.add(assetReaderAudioOutput)
    } else {
        fatalError("could not add audio output reader")
    }
    
    let inputAudioSettings: [String:Any] = [AVFormatIDKey : kAudioFormatLinearPCM]
    let audioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: inputAudioSettings, sourceFormatHint: (audioTrack.formatDescriptions[0] as! CMFormatDescription))
    
    let audioInputQueue = DispatchQueue(label: "audioQueue")
    assetWriter.add(audioInput)
    
    assetWriter.startWriting()
    assetReader.startReading()
    assetWriter.startSession(atSourceTime: CMTime.zero)
    
    audioInput.requestMediaDataWhenReady(on: audioInputQueue) {
        while (audioInput.isReadyForMoreMediaData) {
            let sample = assetReaderAudioOutput.copyNextSampleBuffer()
            if (sample != nil) {
                audioInput.append(sample!)
            } else {
                audioInput.markAsFinished()
                DispatchQueue.main.async {
                    assetWriter.finishWriting {
                        assetReader.cancelReading()
                    }
                }
                break
            }
        }
    }
}

这里的问题是您将输入音频转换为由audioSettings描述的 LPCM 格式,但随后您将audioTrack.formatDescriptions[0]sourceFormatHint提供给AVAssetWriterInput

这是一个问题,因为音轨格式描述不会是 LPCM,而是压缩格式,例如kAudioFormatMPEG4AAC

只是放弃提示,我认为无论如何它都是为了通过压缩格式。

此外, inputAudioSettings中的 LPCM 未指定 - 为什么不直接传递audioSettings呢?

总之,试试这个:

let audioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: audioSettings)

ps运行前别忘了删除output文件, AVAssetWriter好像不会覆盖已有文件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM