iOS——录制音频后回放失败,显示OSStatus错误-43(找不到文件)

5
当我的视图加载时,我通过以下方式设置AVAudioRecorder实例:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
audioSession.delegate = self;
[audioSession setActive:YES error:nil];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];

NSString *tempDir = NSTemporaryDirectory();
NSString *soundFilePath = [tempDir stringByAppendingPathComponent:@"sound.m4a"];

NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSLog(@"%@", soundFileURL);

NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey,
                                [NSNumber numberWithInt:AVAudioQualityMin], AVEncoderAudioQualityKey,
                                [NSNumber numberWithInt:16], AVEncoderBitRateKey,
                                [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                                [NSNumber numberWithFloat:8000.0], AVSampleRateKey,
                                [NSNumber numberWithInt:8], AVLinearPCMBitDepthKey,
                                nil];

NSError *error = nil;

self.recorder = [[AVAudioRecorder alloc]
                 initWithURL:soundFileURL
                 settings:recordSettings
                 error:&error];
self.recorder.delegate = self;

if (error) {
    NSLog(@"error: %@", [error localizedDescription]);
} else {
    [self.recorder prepareToRecord];
}

然后,当用户按下录制按钮时,我执行以下操作:
- (IBAction)record:(id)sender {
    if (!self.isRecording) {
        self.isRecording = YES;
        [self.recorder record];
        self.recordButton.enabled = NO;
    }
}

停止录制/播放的操作:

- (IBAction)stop:(id)sender {
    if (self.isRecording) {
        [self.recorder stop];
        self.recordButton.enabled = YES;
        self.isRecording = NO;
    }

    if (self.isPlaying) {
        [self.player stop];
        self.isPlaying = NO;
        self.playButton.enabled = YES;
    }
}

在录制之后,我希望能够回放所录制的内容,因此我进行了以下操作:
- (IBAction)play:(id)sender {
    NSError *error = nil;
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.recorder.url error:&error];
    self.player.delegate = self;

    if (error) {
        NSLog(@"%@", error.localizedDescription);
    } else {
        self.isPlaying = YES;
        [self.player play];
        self.playButton.enabled = NO;
    }
}

但是当我去播放文件时,出现了OSStatus错误-43,表示找不到文件。

顺便说一下,这都是在设备上运行的,在模拟器上,当我尝试实例化录音机或播放器时也会出现错误,并且从我看到的情况来看,这是一个模拟器问题。

编辑1:我解决了OSStatus错误-43的部分问题,这与编码格式有关,我注释掉了格式,然后它正确地记录和播放了该文件,但我需要以压缩格式记录。有人知道此设置吗?

编辑2:我成功找到了可用于压缩AAC音频的设置。一个2分钟的音频文件大小为256KB,我更新了我的代码以反映当前状态。感谢所有回答过我的人提供的帮助。


我相信在这种情况下会产生错误,当我停止录制时,录音机也会停止,所以我非常怀疑。 - 8vius
不好意思,如果我有点错,因为我几乎没有使用过任何音频相关的类,但是是否有[self.player prepareToPlay] - Bo A
问题:您是在设备上测试还是在模拟器上测试?如果是设备,请问是哪一款设备? - Bo A
这是在设备上,iPhone 4,运行iOS 5.1。 - 8vius
当我运行你的代码并点击录制按钮后,会出现以下错误:<AQConverterThread> aq@0xc240600: ConvertInput: AudioConverterFillComplexBuffer 返回 560226676,packetCount 3。然后当你点击停止时,会出现以下错误:<com.apple.main-thread> flushing pending input terminated - error '!dat'。而点击播放会出现以下错误:操作无法完成。(OSStatus 错误 1685348671。)我已经复制了你的代码并设置了正确的属性。 - Joshua Dance
显示剩余2条评论
4个回答

8
"我要猜一下(没有人回答,编辑:现在有了)(我在iOS中没有太多音频方面的经验),但是......

尝试更改。

"
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:nil];

to

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

是的,这可能会避免需要像我在答案中提到的那样将类别更改回播放。 - Beltalowda
刚刚注意到,我在代码中将其设置为PlayAndRecord,但在记录方法中将其设置回了record(我太蠢了)。已编辑我的代码以反映更改。仍然只得到像白噪声一样的东西。 - 8vius
修改了代码,现在出现文件未找到的错误。看起来它没有创建音频文件。 - 8vius

2

AVEncoderBitRateKey在使用AAC格式编码时无效。请尝试以下代码。

NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSLog(@"%@", soundFileURL);

 NSDictionary *recordSettings = [NSDictionary 
                                        dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithInt:kAudioFormatMPEG4AAC],
                                        AVFormatIDKey,
                                        [NSNumber numberWithInt: AVAudioQualityMax],
                                        AVEncoderAudioQualityKey,
                                        [NSNumber numberWithInt: 1], 
                                        AVNumberOfChannelsKey,
                                        [NSNumber numberWithFloat:44100.0], 
                                        AVSampleRateKey,
                                        nil];
NSError *error = nil;

self.recorder = [[AVAudioRecorder alloc]
                 initWithURL:soundFileURL
                 settings:recordSettings
                 error:&error];
self.recorder.delegate = self;

if (error) {
    NSLog(@"error: %@", [error localizedDescription]);
    NSLog(@"error: %@", [error description]);
} else {
    [self.recorder prepareToRecord];
} 

编辑1:

OSStatus错误-43文件未找到不是模拟器问题。这是一个错误日志,显示您的录音设置不正确,所需的编码格式不支持您选择的设置

当您遇到此错误时,您的文件将以您提供的格式创建。但它将不会初始化您的音频记录器以开始录制。如果您有任何疑问,请选择与第一个问题中相同的设置进行记录并尝试播放。由于不支持的设置,它不会记录和播放。

因此,对于压缩编码格式,您可以使用我在代码中提供的设置。您可以使用.aac格式进行此设置。它将以每10秒164KB的速度记录aac格式。对于其余格式,您必须尝试并找出。


我看到了你的新代码。你的编码格式是kAudioFormatMPEG4AAC,扩展名是.m4a。我认为你需要.aac扩展名的文件。为此,请使用这段代码。这样会更好。 - Dinesh Raja
我之前在模拟器上遇到了一些错误,但是当我停止使用AVEncoderBitRateKey后,一切都正常了。谢谢! - Scott Carter

0

您可能需要将AVAudioSession类别设置回播放模式:

NSError *_error = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&_error];

if (_error) {
    // handle error here
}

这也应该避免在静音开关切换时音频无法播放的问题。


我修改了我的代码,没有注意到这一点,现在我得到了OSStatus错误-43(文件未找到)。 - 8vius
请注意,您应该测试“setCategory:error:”是否返回YES或NO,而不是测试错误是否为nil。 - dulgan

0

好的,请尝试这样做:

NSURL *soundFileURL设置为您类的全局变量,以便您可以在类中的任何地方访问它,并以与现在相同的方式设置(除了它应该是soundFileURL = [NSURL fileURLWithPath:soundFilePath];而不是NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];)。

然后更改此处

self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.recorder.url error:&error];

转换为这个

self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接