【问题标题】:No audio from AVCaptureSession after changing AVAudioSession更改 AVAudioSession 后 AVCaptureSession 没有音频
【发布时间】:2017-06-21 05:28:15
【问题描述】:

我正在制作一个支持视频播放和录制的应用。我总是希望允许背景音频混合,除了在视频播放期间(在播放期间,背景音频应该静音)。因此,我在更改播放状态的同时使用了以下两种方法。当我的 AVPlayer 开始加载时,我调用MuteBackgroundAudio,当我关闭包含它的视图控制器时,我调用ResumeBackgroundAudio。这按预期工作,离开播放后音频成功返回。

问题是,在至少这样做一次之后,每当我使用AVCaptureSession 录制任何内容时,都不会录制任何声音。我的会话配置如下:

AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];

if (error)
{
    NSLog(@"%@", error);
}

if ([self.session canAddInput:audioDeviceInput])
{
    [self.session addInput:audioDeviceInput];
}

[self.session setAutomaticallyConfiguresApplicationAudioSession:NO];

// ... videoDeviceInput

注意我没有设置usesApplicationAudioSession,所以默认为YES

void MuteBackgroundAudio(void)
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        if ([[AVAudioSession sharedInstance] isOtherAudioPlaying] && !isMuted)
        {
            isMuted = YES;

            NSError *error = nil;
            [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
                                             withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker
                                                   error:&error];
            if (error)
            {
                NSLog(@"DEBUG - Set category error %ld, %@", (long)error.code, error.localizedDescription);
            }

            NSError *error2 = nil;
            [[AVAudioSession sharedInstance] setActive:YES
                                           withOptions:0
                                                 error:&error2];
            if (error2)
            {
                NSLog(@"DEBUG - Set active error 2 %ld, %@", (long)error.code, error.localizedDescription);
            }
        }
    });
}

void ResumeBackgroundAudio(void)
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        if (isMuted)
        {
            AVAudioSession *audioSession = [AVAudioSession sharedInstance];

            NSError *deactivationError = nil;
            [audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&deactivationError];

            if (deactivationError)
            {
                NSLog(@"DEBUG - Failed at deactivating audio session, retrying...");
                ResumeBackgroundAudio();
                return;
            }

            isMuted = NO;
            NSLog(@"DEBUG - Audio session deactivated");

            NSError *categoryError = nil;
            [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
                          withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers
                                error:&categoryError];

            if (categoryError)
            {
                NSLog(@"DEBUG - Failed at setting category");
                return;
            }

            NSLog(@"DEBUG - Audio session category set to mix with others");

            NSError *activationError = nil;
            [audioSession setActive:YES error:&activationError];

            if (activationError)
            {
                NSLog(@"DEBUG - Failed at activating audio session");
                return;
            }

            NSLog(@"DEBUG - Audio session activated");
        }
    });
}

调试

我注意到,在调用ResumeBackgroundAudio 后,audioSession 总是需要两次尝试才能成功停用。由于AVAudioSession.h 中的这条评论,我的 AVPlayer 似乎没有及时被释放或停止:

请注意,此方法将在链接的应用程序中抛出异常或 在 iOS 8 之后,如果会话在运行时设置为非活动状态,或者 暂停的 I/O(例如音频队列、播放器、录音机、转换器、远程 I/O 等)。

没有声音被记录的事实让我相信audioSession实际上并没有被激活,但我的日志显示它确实被激活了(总是在递归的第二次迭代中)。

我从this post得到了使用递归来解决这个问题的想法。

为了澄清,导致问题的流程如下:

  1. 在播放 Spotify 的情况下打开应用
  2. 开始播放应用中的任何内容
  3. Spotify 静音,开始播放 (MuteBackgroundAudio)
  4. 播放结束,Spotify 再次开始播放 (ResumeBackgroundAudio)
  5. 开始录制
  6. 停止录制,因为没有音频而生气

【问题讨论】:

  • 我遇到了这个确切的问题。无论在什么情况下,只有我的音频第一次无法正常工作,我需要删除并重新添加音频输入/输出才能获得任何东西。

标签: ios objective-c avfoundation avaudiosession


【解决方案1】:

我遇到了与您描述的完全相同的问题,直到最后一个细节([audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&deactivationError]; 第一次失败,无论如何)

就我而言,唯一可接受的方法是停止然后启动 AVCaptureSession。我不完全确定,但我认为这与 Whatsapp 处理它的方式完全相同 - 他们的相机在我建议的解决方案中表现得与我的完全一样。

在已经运行的会话上删除和添加相同的音频输入似乎也有效,但我遇到了可怕的相机冻结 - 与会话开始/停止相比没有什么。

递归解决方案很好,但我认为“限制”递归调用(添加短暂的延迟和某种最大重试次数)是一个好主意,以防由于合法原因每次设置都失败.否则你的堆栈会溢出,你的应用会崩溃。

如果您或任何人找到了更好的解决方案,我很想知道。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    相关资源
    最近更新 更多