ios 如何使用AVAudioRecorder恢复录制?

ryhaxcpt  于 12个月前  发布在  iOS
关注(0)|答案(4)|浏览(113)

我正在编写一个使用AVAudioRecorder类的应用程序。它工作得很好,除了当一个电话进来。我是按照苹果使用AVAudioRecorderDelegate方法的指导方针来处理这个问题的

– (void) audioRecorderBeginInterruption:
– (void) audioRecorderEndInterruption:

它工作得很好,直到中断结束,我试图通过再次调用record方法(根据文档)来“恢复”记录。然而,它并没有恢复我的录音,而是扔掉了旧的,并开始了一个全新的在其位置。我还没有能够找到一个解决这个问题的办法,如果有人已经想通了这一点,或者如果这是一个错误与苹果的AVAudioRecorder请让我知道。我真的希望我不必用AudioQueues写这个。
谢谢

o4tp2gmn

o4tp2gmn1#

看起来像是苹果API的一个bug。很有趣...
这是我们收到的支持票的响应。
“您描述的行为是一个错误,不幸的是,API中没有任何东西可以更改以解决实际附加到原始记录的问题。中断导致仅捕获中断后记录的音频。您可以尝试在中断后停止录制,然后创建一个新文件,之后至少不会导致用户丢失任何信息,但结果将是两个单独的文件。
请针对此问题提交错误报告,因为当iOS工程师评估要解决的修复程序的关键功能时,外部开发人员提交的错误至关重要。它很容易复制,但如果你有一个测试应用程序,你可以包括请做,iOS工程喜欢有应用程序,直接显示错误。”

7kqas0il

7kqas0il2#

我的解决方案是:
1.在临时文件上开始记录
1.注意AVAudioSessionInterruptionNotificatio
1.在AVAudioSessionInterruptionTypeBegan上-停止录制。

  1. On AVAudioSessionInterruptionTypeEnded -开始新录制。
    1.当用户停止时-标记文件。
    Full Code
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(audioSessionInterruptionNotification:)
                                             name:AVAudioSessionInterruptionNotification
                                           object:audioSession];


    -(void)audioSessionInterruptionNotification:(NSNotification*)notification {
    NSString* seccReason = @"";
    //Check the type of notification, especially if you are sending multiple AVAudioSession events here
    NSLog(@"Interruption notification name %@", notification.name);
    NSError *err = noErr;
    if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
    seccReason = @"Interruption notification received";

    //Check to see if it was a Begin interruption
    if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
        seccReason = @"Interruption began";
        NSLog(@"Interruption notification name %@ audio pause", notification.name);

        dispatch_time_t restartTime = dispatch_time(DISPATCH_TIME_NOW,
                                                    0.01 * NSEC_PER_SEC);
        dispatch_after(restartTime, dispatch_get_global_queue(0, 0), ^{
            AVAudioRecorder *recorder = [[self recorderPool] objectForKey:lastRecID];
            if (recorder) {
                if(recorder.isRecording) {
                    [recorder stop];
                    NSLog(@"Interruption notification name Pauseing recording %@", lastRecID);
                } else {
                    NSLog(@"Interruption notification name Already Paused %@", lastRecID);
                }
            }else {
                NSLog(@"Interruption notification name recording %@ not found", lastRecID);
            }
              NSLog(@"Interruption notification Pauseing recording status %d",recorder.isRecording);
        });

    } else if([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]){
        seccReason = @"Interruption ended!";
         NSLog(@"Interruption notification name %@ audio resume", notification.name);
        //Start New Recording
        dispatch_time_t restartTime = dispatch_time(DISPATCH_TIME_NOW,
                                                    0.1 * NSEC_PER_SEC);
        dispatch_after(restartTime, dispatch_get_global_queue(0, 0), ^{
            AVAudioRecorder *recorder = [[self recorderPool] objectForKey:lastRecID];
            NSLog(@"Interruption notification Resumeing recording status %d",recorder.isRecording);
            if (recorder) {
                if(!recorder.isRecording) {
                    NSString *filePath = [[self orgFileNames] objectForKey:lastRecID];
                    NSArray * fileNames =[[self fileNames] objectForKey:lastRecID];
                    NSString *tmpFileName = [self gnrTempFileName:filePath AndNumber:fileNames.count];
                    [[[self fileNames] objectForKey:lastRecID] addObject:tmpFileName];
                    NSURL *url = [NSURL fileURLWithPath:tmpFileName];
                    NSError *error = nil;
                    recorder = [[AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&error];
                    if (![recorder record]) {
                        NSLog(@"Interruption notification Error Resumeing recording %@",tempRecorder);
                        return;
                    }
                    [[self recorderPool] setObject:recorder forKey:lastRecID];
                    NSLog(@"Interruption notification nameResumeing recording %@",lastRecID);
                }else {
                     NSLog(@"Interruption notification Already Recording %d",recorder.isRecording);
                }
            }else {
                NSLog(@"Interruption notification name recording %@ not found",lastRecID);
            }
        });
      }
     } 
    }
zzzyeukh

zzzyeukh3#

实际上没有bug(至少现在没有了)。该方法的当前文档(2023)指出,调用.record()将隐式调用.prepareToRecord(),这将在指定的URL处创建一个NEW文件。苹果的文档明确指出,如果一个文件存在于URL,它将被覆盖。换句话说,使用所提供的API,“恢复”录制是不可能的。使用AVAudioRecorder实现此目的的唯一方法是创建多个文件并合并它们。应该注意的是,苹果的AVAudioRecorder.record()文档是误导性的,因为它实际上说“开始或恢复音频录制”。
https://developer.apple.com/documentation/avfaudio/avaudiorecorder/1388252-recordhttps://developer.apple.com/documentation/avfaudio/avaudiorecorder/1389435-preparetorecord

ql3eal8s

ql3eal8s4#

您将尝试使用这段代码

-(IBAction)pauseandplay:(id)sender
{
    BOOL status= [player isPlaying];
    if(status)
    {
    [pauseplay setImage:[UIImage imageNamed:@"play.png"]];
    [player pause];
    }
    else
    {
    [pauseplay setImage:[UIImage imageNamed:@"icon-pause.png"]];
    [player play];
    updateTimer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(updateCurrentTime) userInfo:player repeats:YES];
    }
}

相关问题