簡體   English   中英

更改AVAudioSession后,AVCaptureSession沒有音頻

[英]No audio from AVCaptureSession after changing AVAudioSession

我正在制作一個支持視頻播放和錄制的應用。 我總是希望允許背景音頻混合,除了在視頻播放期間(在播放期間,背景音頻應該靜音)。 因此,我在改變播放狀態時使用以下兩種方法。 當我的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似乎沒有及時解除分配或停止:

請注意,如果會話在運行或暫停I / O(例如音頻隊列,播放器,錄像機,轉換器,遠程I / O等)時設置為非活動狀態,則此方法將在iOS 8上或之后鏈接的應用中引發異常。 。

沒有聲音被記錄的事實讓我相信audioSession實際上沒有被激活,但是我的日志記錄說它確實(總是在遞歸的第二次迭代中)。

我從這篇文章中得到了使用遞歸來解決這個問題的想法。

澄清一下,導致問題的流程如下:

  1. 使用Spotify播放打開應用程序
  2. 開始播放應用中的任何內容
  3. Spotify MuteBackgroundAudio靜音,播放開始( MuteBackgroundAudio
  4. 播放結束,Spotify再次開始播放( ResumeBackgroundAudio
  5. 開始錄制
  6. 停止錄音,生氣,沒有音頻

我和你描述的問題完全相同,直到最后一個細節( [audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&deactivationError];第一次失敗,無論如何)

對於我的情況,唯一可接受的方法是停止然后啟動AVCaptureSession。 我不完全確定,但我認為這與Whatsapp處理它的方式完全相同 - 他們的相機與我建議的解決方案完全一樣。

在已經運行的會話中刪除和添加相同的音頻輸入似乎也可以工作,但我的相機凍結很可怕 - 與會話開始/停止相比沒什么。

遞歸解決方案很不錯,但我認為“限制”遞歸調用(添加一個短暫的延遲和某種類型的最大重試計數)是一個好主意,以防由於合法的原因每次都會失敗。 否則你的堆棧將溢出,你的應用程序將崩潰。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM