茶后闲聊
不知关注我博客的Xcoder们,有没有在看完我分享的技术之后,着手一个自己的小项目,至少我觉得这些知识点,是比较有意思的。咱们之前说过,你可以做一个恶搞声音的小功能,也可以做一个专业音乐制作的软件,同时也可以做一个裁切音频的软件,再或者可以实现一个掌上KTV。
下面我说一个我在做一个《即兴唱吧》这个小软件的时候,遇到的一个小坑。
背景:
我之前封装了实时录音添加音效的小模板,为了省事,我把代码直接拷贝到了《即兴唱吧》里面,在我那个小Demo中是没任何问题的,代码完整运行,而且我每次上班都用它来唱歌消遣。但是放到《即兴唱吧》里面,录制就崩溃!不写入音频流直接实时播放没问题!这让我忧伤了很久,至少一个上午。
代码贴上来:
mixNode.installTap(onBus:0, bufferSize:4410, format: inputNode.inputFormat(forBus:0)) { (buffer, when)in
try! audioFile.write(from: buffer)
}
看着没啥问题啊!
有些经验的Xcoder们会说,你没移除Tap吧?
代码贴上来:
func stopRecoder(){
engine.inputNode?.removeTap(onBus:0)
engine.stop()
}
这咋回事呢?
其实我之前看文档的时候,还非常注意了下这句话,在拷贝的时候,给忘记查看了,大家看下:
官方说明如下:
@method writeFromBuffer:error:
@abstract Write a buffer.
@param buffer
The buffer from which to write to the file. Its format must match the file's
processing format.
@param outError
on exit, if an error occurs, a description of the error
@return
YES for success.
@discussion
Writes sequentially. The buffer's frameLength signifies how much of the buffer is to be written.
注意看我加粗的部分!
大概意思是写入文件的流,他的格式必须匹配文件生成的格式!
那文件是啥格式呢?
别去想了,AVAudioFile里面提供了,
文档如下:
/*! @property processingFormat
@abstract The processing format of the file.
*/
publicvarprocessingFormat:AVAudioFormat{ get }
各位Xcoder们,知道咋回事了吧!
就是设置的输入文件格式和生成的文件格式不匹配!才一直录制就崩溃!
这还一点需要注意,尽量把输出格式也设置成文件格式。
最终把成功的代码贴上来:
mixNode.installTap(onBus:0, bufferSize:4410, format: audioFile.processingFormat) { (buffer, when)in
try! audioFile.write(from: buffer)
}
好啦!自己切记吧!
完整代码就不提供了!如果有机会我会开一堂专题课来讲这个项目。