茶后閑聊
不知關(guān)注我博客的Xcoder們,有沒有在看完我分享的技術(shù)之后,著手一個(gè)自己的小項(xiàng)目,至少我覺得這些知識(shí)點(diǎn),是比較有意思的。咱們之前說過,你可以做一個(gè)惡搞聲音的小功能,也可以做一個(gè)專業(yè)音樂制作的軟件,同時(shí)也可以做一個(gè)裁切音頻的軟件,再或者可以實(shí)現(xiàn)一個(gè)掌上KTV。
下面我說一個(gè)我在做一個(gè)《即興唱吧》這個(gè)小軟件的時(shí)候,遇到的一個(gè)小坑。
背景:
我之前封裝了實(shí)時(shí)錄音添加音效的小模板,為了省事,我把代碼直接拷貝到了《即興唱吧》里面,在我那個(gè)小Demo中是沒任何問題的,代碼完整運(yùn)行,而且我每次上班都用它來唱歌消遣。但是放到《即興唱吧》里面,錄制就崩潰!不寫入音頻流直接實(shí)時(shí)播放沒問題!這讓我憂傷了很久,至少一個(gè)上午。
代碼貼上來:
mixNode.installTap(onBus:0, bufferSize:4410, format: inputNode.inputFormat(forBus:0)) { (buffer, when)in
try! audioFile.write(from: buffer)
}
看著沒啥問題??!
有些經(jīng)驗(yàn)的Xcoder們會(huì)說,你沒移除Tap吧?
代碼貼上來:
func stopRecoder(){
engine.inputNode?.removeTap(onBus:0)
engine.stop()
}
這咋回事呢?
其實(shí)我之前看文檔的時(shí)候,還非常注意了下這句話,在拷貝的時(shí)候,給忘記查看了,大家看下:
官方說明如下:
@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們,知道咋回事了吧!
就是設(shè)置的輸入文件格式和生成的文件格式不匹配!才一直錄制就崩潰!
這還一點(diǎn)需要注意,盡量把輸出格式也設(shè)置成文件格式。
最終把成功的代碼貼上來:
mixNode.installTap(onBus:0, bufferSize:4410, format: audioFile.processingFormat) { (buffer, when)in
try! audioFile.write(from: buffer)
}
好啦!自己切記吧!
完整代碼就不提供了!如果有機(jī)會(huì)我會(huì)開一堂專題課來講這個(gè)項(xiàng)目。