AVAudioRecorder不会创建可以打开和播放的.m4a文件

时间:2013-07-08 21:32:30

标签: ios avaudiorecorder aac m4a

我正在尝试修改可以将音频文件(安全/加密)发送到其他iOS设备的iOS应用。它使用AVAudioRecorder录制音频文件,并使用AVAudioPlayer播放任何收到的音频文件。

我现在正在尝试修改应用以创建和发送与Android兼容的文件。我将现有的AVAudioRecorder代码修改为:

[settings setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[settings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
[settings setValue:[NSNumber numberWithInt:16] forKey:AVEncoderBitRateKey];
[settings setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
[settings setValue:[NSNumber numberWithFloat:48000.0] forKey:AVSampleRateKey];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dirPath = [paths objectAtIndex:0];

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"yyyy-MM-dd HH-mm"];

NSString *filename = [NSString stringWithFormat:@"%@.aac", [format stringFromDate:NSDate.date]];

由此创建的文件可在Mac,iOS设备上播放,但不能在Android设备上播放。如果手动将文件扩展名更改为以#34; .m4a"结尾,则该文件将在Android上播放。

(" .aac"格式的优势在于旧版本的应用可以接收这些文件并播放它们 - 我们保持向后兼容性。)

所以我做了这个改变:

NSString *filename = [NSString stringWithFormat:@"%@.m4a", [format stringFromDate:NSDate.date]];

但是,生成的文件(在没有AVAudioRecorder错误的情况下创建)无法在Mac上或iOS设备上播放。而我正在等待它是否适用于Android。

当AVAudioPlayer尝试打开该文件时,它会输出:

  

错误域= NSOSStatusErrorDomain代码= 1685348671"操作   无法完成。 (OSStatus错误1685348671。)"代码1685348671    - > " dta?":文件格式错误,不是其类型音频文件的有效实例,或者未被识别为音频文件。

仅将文件重命名为" .aac"再次没有改变它无法加载到Mac或iOS上的任何东西的事实。

现在,似乎最好的解决方案是创建一个" .aac"文件,然后让Android端替换" .aac"用" .m4a"并尝试发挥它。

问题1:有谁知道为什么更改文件扩展名会导致AVAudioPLayer失败?顺便说一下," .m4a"我在上面创建的文件无法使用Mac上的任何内容打开,因此我无法判断问题是文件格式还是iOS或Mac无法读取此文件类型。

对于任何好奇的人,我都会放一份" .aac"和一个" .m4a"来自AVAudioRecorder的文件,在这里:

https://dl.dropboxusercontent.com/u/14939586/2013-07-08%2013-24.m4a https://dl.dropboxusercontent.com/u/14939586/2013-07-08%2010-11.aac

问题2:当我将AVAudioRecorder设置为一个通道时,生成的文件是立体声。为什么? (至少这是VLC关于元数据的说法)

问题3:无论如何为无损编码指定AAC-LC?或者,如果我从AVAudioRecorder转移到较低级别的API,我是否也可以这样做?

3 个答案:

答案 0 :(得分:9)

问题1的答案是你必须正确设置音频会话,否则m4a文件格式不正确。在我开始录制之前,我现在设置的音频会话代码是:

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryRecord error:nil];
[session setActive:YES error:nil];

录制完成后,我将会话设置回播放,以便播放音频文件。

问题2是VLC中显示错误通道数的问题。 MacOS Finder的“获取信息”窗口中的音频文件显示为单个通道。

问题3没有答案。

答案 1 :(得分:3)

对于在“.m4a”文件中创建和录制音频,该文件在iOS和Android中播放,我使用以下代码:

NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];


AudioRecorder = [[AVAudioRecorder alloc] initWithURL:fileOutPutUrl settings:recordSetting error:nil];
[AudioRecorder setDelegate:self];
[AudioRecorder recordForDuration:RecordLimitTime];  // Record Limit if require
if ([AudioRecorder prepareToRecord]) {
    [AudioRecorder record];
}

在Android方面,我不必更改仅播放“.mp3”文件的代码,在android中只需将扩展名从“fileName.m4a”更改为“fileName.mp3”,并且令人惊讶地工作。 iOS file =“fileName.m4a”播放顺畅。

答案 2 :(得分:0)

我遇到了同样的问题,在使用本地文件创建 AVAudioPlayer 时遇到了 NSOSStatusErrorDomain 560030580

问题不在于文件或其格式,而是因为我未正确设置 AVAudioSession

我在录制音频之前调用了 setCategory(.playAndRecord)setActive(yes),然后在播放时调用了 setCategory(.playback)setActive(yes),但我从未调用过 setActive(false)

根据 Apple docs 对于某些播放和录制应用程序,停用需要明确发生,所以我所做的是:

  • 在录音前和通话结束时拨打 setCategory(.record)setActive(yes) setActive(false)
  • 在播放文件之前调用 setCategory(.playback)setActive(yes),完成调用 setActive(false)

此外,我发现这个 https://www.osstatus.com/ 提供了有关处理音频/文件内容时抛出的错误的更多信息。