使用原始 PCM 生成视频或音频

Generating video or audio using raw PCM

使用 Int16 数组作为音频的立体声通道生成 .mov 或 .m4a 文件的过程是什么?

我可以轻松地从 .mov 文件生成 [Int16] 的原始 PCM 数据,并将其存储在两个文件 leftChannel.pcmrightChannel.pcm 中,并执行一些操作以备后用。但是我无法从这些文件中重新生成视频。

任何过程,即使用原始 PCM 直接生成视频或使用从 PCM 生成 m4a 的中间步骤都可以。

更新:

我想出了如何将 PCM 阵列转换为音频文件。但是不会播放。

private func convertToM4a(leftChannel leftPath : URL, rightChannel rigthPath : URL, converterCallback : ConverterCallback){

    let m4aUrl = FileManagerUtil.getTempFileName(parentFolder: FrameExtractor.PCM_ENCODE_FOLDER, fileNameWithExtension: "encodedAudio.m4a")
    if FileManager.default.fileExists(atPath: m4aUrl.path) {
        try! FileManager.default.removeItem(atPath: m4aUrl.path)
    }
    do{
        let leftBuffer = try NSArray(contentsOf: leftPath, error: ()) as! [Int16]
        let rightBuffer = try NSArray(contentsOf: rigthPath, error: ()) as! [Int16]

        let sampleRate = 44100
        let channels = 2
        let frameCapacity = (leftBuffer.count + rightBuffer.count)/2

        let outputSettings = [
            AVFormatIDKey : NSInteger(kAudioFormatMPEG4AAC),
            AVSampleRateKey : NSInteger(sampleRate),
            AVNumberOfChannelsKey : NSInteger(channels),
            AVAudioFileTypeKey : NSInteger(kAudioFileAAC_ADTSType),
            AVLinearPCMIsBigEndianKey : true,
            ] as [String : Any]

        let audioFile = try AVAudioFile(forWriting: m4aUrl, settings: outputSettings, commonFormat: .pcmFormatInt16, interleaved: false)

        let format = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: Double(sampleRate), channels: AVAudioChannelCount(channels), interleaved: false)!

        let pcmBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(frameCapacity))!
        pcmBuffer.frameLength = pcmBuffer.frameCapacity

        for i in 0..<leftBuffer.count {
            pcmBuffer.int16ChannelData![0][i] = leftBuffer[i]
        }

        for i in 0..<rightBuffer.count {
            pcmBuffer.int16ChannelData![1][i] = rightBuffer[i]
        }

        try! audioFile.write(from: pcmBuffer)

        converterCallback.m4aEncoded(to: m4aUrl)

    } catch {
        print(error.localizedDescription)
    }
}

将其保存为 .m4a 并使用 AVAudioFileTypeKey 作为 m4a type 给出格式错误的文件错误。

使用上述设置将其另存为 .aac 可以播放文件,但声音有问题。就是嗡嗡声加上原声的slow mo effect,一开始以为是采样率输入输出的问题,其实不是。

我假设输出词典有问题。任何帮助将不胜感激。

至少使用您显示的代码创建 AAC 文件是可行的。

我用有效的 Int16 音频数据写出了两个 NSArrays,并且用你的代码得到了一个有效的结果,例如在 QuickTime Player 中播放时(使用后缀 .aac)听起来与输入相同。

你是如何创建输入的?

例如,嗡嗡声(有很多噪音)如果您使用 AVAudioFormat 读取音频数据,例如.pcmFormatInt16 格式但实际读取的数据是 .pcmFormatFloat32 格式(最常见的默认格式)。不幸的是,如果您尝试这样做,没有运行时警告。

如果是这种情况,请尝试使用 .pcmFormatFloat32。如果您在 Int16 中需要它,您可以通过基本将两个通道的 [-1,1] 映射到 [-32768,32767] 来自己转换它。

let fac = Float(1 << 15)
for i in 0..<count {
    let val = min(max(inBuffer!.floatChannelData![ch][i] * fac, -fac), fac - 1)
    xxx[I] = Int16(val)
}
...