看起来是随机文件损坏问题,使用 AVAudioRecorder 时(有时文件无法播放)- iOS

15

我正在开发一个应用程序,但目前遇到了难题。在该应用程序中,您可以进入一个视图,其中列出了标准表格视图中所有本地保存的音频文件。从这里,您可以单击它们进行播放,或者在下方点击录制按钮进行新录音,然后自动保存到应用程序沙箱中。

现在,所有这些工作都非常完美,大部分时间都没有问题。我可以坐在那里录制并播放它们。我可以一遍又一遍地测试约45分钟左右,没有任何问题。然后突然间,在随机的时候,我会遇到一个非常奇怪的问题。问题是,录音机突然开始保存除了损坏文件以外的内容,这些文件不能播放,大小恰好为4096字节,无论您录制多长时间。

我按照完全标准的方式使用AVAudioRecorder来设置它:

// Specific settings for the audio recording
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithInt:AVAudioQualityMin],
    AVEncoderAudioQualityKey,
    [NSNumber numberWithInt:8], 
    AVEncoderBitRateKey,
    [NSNumber numberWithInt: 2], 
    AVNumberOfChannelsKey,
    [NSNumber numberWithFloat:22000.0], 
    AVSampleRateKey,
    nil];

NSError *error = nil;
audioRecorder = [[AVAudioRecorder alloc]
    initWithURL:contentURL
    settings:recordSettings
    error:&error];
audioRecorder.delegate = self;

我是这样开始录制的:

if (!isRecording) {
    isRecording = YES;
    [audioRecorder record];

    // Start the timer
    recordTiming = [NSDate date];

    timeCheck = [NSTimer
        scheduledTimerWithTimeInterval:1.0f
        target:self
        selector:@selector(timeCheck)
        userInfo:nil
        repeats:YES];
}

然后使用以下内容停止它:

if (isRecording) {
    [audioRecorder stop];

    // Stop the timer
    [timeCheck invalidate];
}

我不知道是什么原因导致了这个问题。到目前为止,我已经尝试了几乎所有可能的方法。我检查确保记录器对象被适当地回收(因此每次现在都有一个新实例),并且旧引用已被解除分配等等,以确保它与其他对象无关,但没有任何解决办法。

有人知道可能会导致文件损坏问题的原因吗?


1
那么你的意思是在audioRecorder初始化之后,错误变量始终为nil,对吗? - A-Live
是的,正确 :) 实际上我在下面有一些快速错误检查,以确保NSLog被正确初始化,并且NSError为nil等。 - CodingBeagle
好的,让我们来优化您的代码,那么问题应该很明显或消失了。您可以使用audioRecorder属性recording代替使用isRecording变量。我看不到音频会话初始化,但您可能只是忽略了它。然而,我建议您也改进错误处理,以下回答可供参考:https://dev59.com/UXNA5IYBdhLWcg3wUMHn - A-Live
1
是的,我现在尝试改进一些错误处理 :) 我还将错误缩小到开始录制时,也就是在这行代码:[audioRecorder record]; 我发现在某些情况下它会随机返回NO。有人建议我在录制之前启动音频会话。我还没有找到这个bug,但也许它仍然存在。很难说因为时间可能如此随机 :) 你认为音频会话可能会对此起作用吗?顺便说一句,非常感谢你迄今为止的帮助 :) 非常感激。 - CodingBeagle
@user1163640:你能否把你的解决方案发布为答案并接受它,这样其他人也可以轻松找到它呢? - patric.schenke
显示剩余5条评论
1个回答

7

注意:由于提问者已经不活跃了几天,我猜想这个问题应该为公众的未来参考而回答,因此我发表了这个答案。

在开始录音之前必须获取AVAudioSession

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
   NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
   return;
}
err = nil;
[audioSession setActive:YES error:&err];
if(err){
   NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
   return;
}

参考文献:https://dev59.com/VGkw5IYBdhLWcg3ws8xj#9706731

这篇文章讨论了在IT领域中,特别是在编程方面,如何更好地使用注释。注释应该是简洁明了的,不要过多地解释代码本身已经清楚表达的内容。注释可以帮助其他人更好地理解你的代码和思路。同时,注释也应该随着代码的更新而更新,以保持准确性。


这确实是问题的原因 :) 我已经有一段时间没有检查我的旧问题了,所以对此感到抱歉,但这确实是解决问题的方法。 - CodingBeagle

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