使用Int16数组作为音频的sterio通道生成.mov或.m4a文件的过程是什么?
我可以从.mov文件轻松生成原始PCM数据[Int16]
,并将其存储在两个文件leftChannel.pcm
和rightChannel.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)
}
}
将AVAudioFileTypeKey
m4a type
保存为.m4a,导致格式错误。
使用上述设置将其保存为.aac会播放文件,但声音会断开。只是嗡嗡作响的声音和原始音频的一些缓慢的mo效果,最初我认为它与采样率的输入和输出有关,但事实并非如此。
我认为输出字典中有问题。任何帮助将不胜感激。
答案 0 :(得分:0)
至少使用您显示的代码创建AAC文件。
我写了两个带有效Int16音频数据的NSArrays,并且你的代码获得了一个有效的结果,例如在QuickTime播放器中使用(使用后缀.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)
}
...