AVAudioRecorder does not create .m4a files that can be opened and played

前提是你 提交于 2021-02-06 19:56:40

问题


I am trying to modify an iOS app that can send audio files (securely/encrypted) to other iOS devices. It uses AVAudioRecorder to record the audio files, and it uses AVAudioPlayer to play back any received audio files.

I am now trying to modify the app to create and send files that are compatible with Android. I modified the existing AVAudioRecorder code to this:

[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]];

The files created by this are playable on a Mac, on an iOS device, but not on an Android device. If the file extension were manually changed to end in ".m4a", then the file plays on Android.

(The advantage with the ".aac" format is that old versions of the app can receive these files and play them back — I've maintained backwards compatibility.)

So I made this change:

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

However, the resultant file (which is created with no errors from AVAudioRecorder) cannot be played on Macs nor on iOS devices. And I am waiting to hear whether it works on Android.

When AVAudioPlayer tries to open that file, it outputs:

Error Domain=NSOSStatusErrorDomain Code=1685348671 "The operation couldn’t be completed. (OSStatus error 1685348671.)" Code 1685348671 -> "dta?": The file is malformed, not a valid instance of an audio file of its type, or not recognized as an audio file.

Merely renaming the file to have a ".aac" again doesn't change the fact that it can't be loaded into anything on the Mac or iOS.

Right now, it seems like the best solution would be to create a ".aac" file, and then have the Android end replace the ".aac" with ".m4a" and try to play it.

Question 1: Does anyone know why changing the filename extension can cause AVAudioPLayer to fail? BTW, the ".m4a" file I created above, can't be opened with anything I have on the Mac so I can't tell whether the problem is with the file format or the inability of iOS or Macs to read this file type.

For anyone curious, I put a copy of an ".aac" and a ".m4a" file from AVAudioRecorder, here:

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

Question 2: While I set AVAudioRecorder to one channel, the resultant file is stereo. Why? (At least that is what VLC says about the metadata)

Question 3: Is there anyway to specify AAC-LC for lossless encoding? Or can I only do so if I move from AVAudioRecorder to a lower level API?


回答1:


The answer to question 1 is that you have to set the audio session correctly, otherwise the m4a file does not get formatted correctly. The audio session code that I now set, just before I start recording is:

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

I set the session back for playback after recording is finished so that audio files can be played back.

Question 2 is a problem in VLC which was displaying the incorrect number of channels. The audio file, in the MacOS Finder's Get Info window, shows up as single channel.

Question 3 is unanswered.




回答2:


For Create and Record audio in ".m4a" file, which play in iOS as well as in android, i use following code:

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];
}

In Android side, i don't have to change the code for play only ".mp3" file, in android just change extension from "fileName.m4a" to "fileName.mp3", and it surprisingly works.and in iOS file = "fileName.m4a" play smoothly.



来源:https://stackoverflow.com/questions/17536325/avaudiorecorder-does-not-create-m4a-files-that-can-be-opened-and-played

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!