首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使存在文件,AVAudioFile.length也是0。

即使存在文件,AVAudioFile.length也是0。
EN

Stack Overflow用户
提问于 2015-12-06 22:08:06
回答 1查看 1.9K关注 0票数 5

我正在创建一个AVAudioFile,用于将声音写入声音文件。如果文件已经存在,我希望将framePosition移动到文件的末尾,继续在文件末尾写入,而不是替换现有的文件。

我做了一些测试,尝试用不同的URL将缓冲区从文件中读取到一个新文件中,这样它就不会覆盖原始文件。当我试图将缓冲区读入新文件时,我会崩溃:

代码语言:javascript
复制
let audioFile = try AVAudioFile(forReading: [URL to existing .caf file])
let audioFrameCount = AVAudioFrameCount(UInt32(audioFile.length))
let audioBuffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: audioFrameCount)

let newAudioFile = try AVAudioFile(forWriting: [another URL], settings: self.engine.mainMixerNode.outputFormatForBus(0).settings)
try newAudioFile.readIntoBuffer(audioBuffer, frameCount: audioFrameCount!) <-- CRASHES ON THIS LINE

崩溃日志:由于未登录的异常“com.apple.coreaudo.avf音频”终止应用程序,原因:“error-50”

伙计,我真的很讨厌CoreAudio的崩溃日志。他们什么都没告诉我!

难道不可能将数据读入为写入而创建的文件中吗?

更新

好的,在提出一些建议之后,我做了一些修改。基本上,这些是我正在采取的步骤:

  1. 检查文件是否已经存在。
  2. 如果是这样的话,打开它进行读取并获取音频缓冲区。
  3. 创建一个用于写入的新文件(使用相同的文件URL)
  4. 使用writeFromBuffer将缓冲区从旧文件写入新文件
  5. 将新文件的framePosition移到末尾,以便我可以继续编写/记录到它。

但是,在我写入新文件之后,新文件的长度为0。

这是我的密码:

代码语言:javascript
复制
//Check if a file already exists. If so continue to record at the end of it
var audioBuffer : AVAudioPCMBuffer!
var audioFrameCount : AVAudioFrameCount!
if (NSFileManager.defaultManager().fileExistsAtPath(self.audioRecordURL.path!)) {
    do {
        let existingAudioFile = try AVAudioFile(forReading: self.audioRecordURL)
        audioFrameCount = AVAudioFrameCount(existingAudioFile.length)
        if (audioFrameCount > 0) {
            audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount)
        }
    } catch let error as NSError {
        NSLog("Error reading buffer from file %@", error.localizedDescription)
    }
}

//Create a new file. This will replace the old file
do {
    self.audioFile = try AVAudioFile(forWriting: self.audioRecordURL, settings: self.engine.mainMixerNode.outputFormatForBus(0).settings)
} catch let error as NSError {
    NSLog("Error creating AVAudioFile %@", error.localizedDescription)
}

//Read the audio buffer from the old file into the new file
if (audioBuffer != nil) {
    do {
        try self.audioFile.writeFromBuffer(audioBuffer)
        self.audioFile.framePosition = self.audioFile.length
    } catch let error as NSError {
        NSLog("Error reading buffer into file %@", error.localizedDescription)
    }
}

顺便说一句,readIntoBuffer的命名给我带来了极大的困惑。听起来似乎应该使用该方法将文件读入缓冲区,但根据文档,您应该使用它将缓冲区读入文件中?那么为什么我不能使用这个方法将缓冲区添加到我的文件中呢?为什么我要使用writeFromBuffer?

更新2

所以我设法解决了。显然,在使用数据之前,我必须调用readIntoBuffer才能将数据填充到缓冲区中。所以我增加了这一行

代码语言:javascript
复制
try existingAudioFile.readIntoBuffer(audioBuffer)

之后

代码语言:javascript
复制
audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-16 07:02:18

不确定这是否只是您在这里提供的代码中的一个错误,而且我不是这方面的专家,但您大概是想让崩溃的代码行为:

代码语言:javascript
复制
try audioFile.readIntoBuffer(audioBuffer, frameCount: audioFrameCount!)

因为您不能从打开的写入文件(newAudioFile)中读取,这是合理的。

然后,在填充该缓冲区后,您将希望使用writeFromBuffer ref/occ/instm/AVAudioFile/writeFromBuffer:error写入新文件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34123426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档