我正在使用AVAudioRecorder
使用以下设置在iPhone上录制音频:
NSMutableDictionary *recordSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[NSNumber numberWithInt:1], AVNumberOfChannelsKey,
[NSNumber numberWithInt:12800], AVEncoderBitRateKey,
[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
[NSNumber numberWithInt: AVAudioQualityHigh], AVEncoderAudioQualityKey,
nil];
(我可以灵活处理大多数这些设置,但我必须使用MPEG4 AAC。)
我将音频保存到文件中。
用户需要能够在以后返回并继续录制到同一文件。似乎没有选择直接使用AVAudioRecorder
执行此操作,因此我正在录制到一个新文件并连接它们。
目前,我使用AVMutableComposition
和AVMutableCompositionTrack
作为here附加文件,但是对于较长的录制内容来说真的很慢,所以这不太可行。
我认为如果我可以从第二个文件中删除标题,将音频数据附加到第一个文件,然后更改组合文件的标题以反映新的持续时间,那会快得多。据我所知,两个文件都是使用完全相同的设置创建的,我认为标题中的其他细节应该相同。
不幸的是,我找不到任何关于标题格式的信息,或者是否可以用这种方式组合文件。
所以我的问题是:
答案 0 :(得分:3)
虽然我们要求AVAudioRecorder
以MPEG4-AAC格式录制,但它始终会生成.caf(核心音频格式)文件。这只是一种包装格式,它包含的实际音频数据是AAC格式。
最后,附加文件归结为逐字节操作.caf文件。核心音频格式文件的规范是here。消化此文档并相应地处理文件起初有点令人反感,但事实证明规范非常清晰和完整,所以它并不太繁琐。
正如规范所解释的那样,.caf文件由开头的四字节名称组成。对于AAC文件,始终有desc
块和kuki
块。我们知道我们的两个原始文件格式相同,我们可以将这些块不变地复制到输出文件中。
还有一个pakt
块和一个data
块。我们无法保证输入文件中的这些顺序。可能有也可能没有free
块 - 但这只包含填充0x00,所以我们不需要将它复制到输出文件。
要合并pakt
块,我们需要检查块标头并生成一个新的pakt
块,其mNumberPackets
和mNumberValidFrames
字段是其中的总和输入文件。 mPrimingFrames
和mRemainderFrames
始终为零 - 这些仅与流媒体相关。大部分pakt
块(即实际的数据包表数据)可以连接起来。
同样对于data
块:mChunkSize
字段需要求和,然后可以连接大部分数据。
从这些文件中的所有二进制数字字段读取数据时要小心:文件是big-endian但iPhone是little-endian。
对于额外的功劳,您可能还想考虑从文件中删除音频片段,或者将一个音频文件插入另一个音频文件的中间。这有点棘手,因为你必须解析pakt
块的内容。同样,这是遵循规范的情况:有一个很好的描述如何将数据包大小存储在可变长度的整数中,因此您必须解析这些以查找每个数据包在data
中占用的字节数大块,并相应地计算他们的位置。
总而言之,这比我希望的更麻烦。也许有一个开源库可以为你做这一切,但我找不到一个。
然而,与原始问题中使用AVMutableComposition
和AVMutableCompositionTrack
相比,处理这样的原始文件的速度非常快 - 将长达一小时的记录插入另一个相同长度的记录大约需要两秒钟。
答案 1 :(得分:1)
我找到了一种更快实施的方法:
使用AVAudioRecorder并使用扩展名“m4a”作为临时文件,但如果需要,也可以使用“caf”,但这是不必要的。
修改代码here以使用AVAssetExportPresetPassthrough和exportSession.outputFileType = AVFileTypeQuickTimeMovie以及文件名“audioJoined.mov”。使用新录制的临时m4a和现有的m4a文件。这为您提供了即时连接(无重新压缩)并生成“mov”。
请注意。不幸的是,AVAudioPlayer无法播放“mov”,因此下一步是将其转换为可播放的内容。但是,如果你只是想在某个地方共享文件,那么你可能会跳过下一步,因为在Quicktime中可以在Mac上完全播放mov。它也可以在iTunes中播放并同步回iPhone并在iPod应用程序中播放。
我在一个应用程序中使用此技术,该应用程序能够在录制停止并且文件已播放后恢复录制,或者即使应用程序重新启动,也非常酷。