简体   繁体   English

如何使用AVAudioRecorder恢复录制?

[英]How to resume a recording using AVAudioRecorder?

I am writing an application that uses the AVAudioRecorder class. 我正在编写一个使用AVAudioRecorder类的应用程序。 It works great except for when a phone call comes in. I am handling this per apple's guidelines of using the AVAudioRecorderDelegate methods 除了拨打电话外,它的效果很好。我按照苹果公司使用AVAudioRecorderDelegate方法的指导方针处理这个问题。

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

It works great until the interruption ends and I attempt to "resume" the recording by calling the record method again (per the documentation). 它工作得很好,直到中断结束,我试图通过再次调用记录方法来“恢复”记录(根据文档)。 However it does not resume my recording but instead throws out the old one and starts up an entirely new one in its place. 然而,它并没有恢复我的录音,而是抛弃旧的录音,并在它的位置启动一个全新的录音。 I have not been able to find a solution to this problem, if anyone has figured this out, or if it is a bug with apple's AVAudioRecorder please let me know. 我无法找到解决这个问题的方法,如果有人想到这个问题,或者苹果公司的AVAudioRecorder是个错误请告诉我。 I really hope I do not have to write this using AudioQueues . 我真的希望我不必使用AudioQueues来写这个。

thanks 谢谢

Looks like its a bug with apple's API. 看起来它是苹果API的一个错误。 Great fun.... 非常有趣....

This was the response we received from a support ticket. 这是我们从支持票中收到的回复。

"The behavior you described is a bug and unfortunately there's nothing in the API that you can change to work around to actually append to the original recording. The interruption is resulting in capturing only the audio recorded after the interruption. You could try and stop the recording after the interruption then creating a new file after which would at least not cause the user to loose any information, but the result would be two separate files. “你描述的行为是一个错误,不幸的是,API中没有任何东西你可以改变以实际附加到原始录音。中断导致只捕获中断后录制的音频。你可以尝试停止中断后记录,然后创建一个新文件,之后至少不会导致用户丢失任何信息,但结果将是两个单独的文件。

Please file a bug report at for this issue since bugs filed by external developers are critical when iOS engineering is evaluating critical features of fixes to address. 请为此问题提交错误报告,因为当iOS工程师正在评估要解决的修复程序的关键功能时,外部开发人员提交的错误至关重要。 It's easily reproducible but if you have a test app you can include please do, iOS engineering like having apps that show the bug directly. 它很容易重现,但如果你有一个测试应用程序,你可以包括请做,iOS工程,如有直接显示错误的应用程序。 "

My solution was: 我的解决方案是:

  1. Start record on temp file 在临时文件上开始记录

  2. Watch for AVAudioSessionInterruptionNotificatio 观察AVAudioSessionInterruptionNotificatio

  3. On AVAudioSessionInterruptionTypeBegan - stop the recording. 在AVAudioSessionInterruptionTypeBegan上 - 停止录制。
  4. On AVAudioSessionInterruptionTypeEnded - Start new recording. 在AVAudioSessionInterruptionTypeEnded上 - 开始新录制。
  5. When the user stops - Marge the files. 当用户停止时 - Marge文件。

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

You will try by using this piece of code 您将尝试使用这段代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM