fixed: in stereo mode, audio playback can't be resumed after a phone call is ended

This commit is contained in:
TrueZhuanjia committed 2025-12-19 22:27:05 +08:00
1 parent c0b1326dbd
commit ef60aeeead
1 file changed
+33 -4
+33 -4
View File
@@ -51,6 +51,7 @@ static float volume = 1.0;
static int audioFrameSize; static int audioFrameSize;
static bool useSystemAudioEngine; static bool useSystemAudioEngine;
static bool audioSessionInterrupted;
static AVAudioEngine *audioEngine; static AVAudioEngine *audioEngine;
static AVAudioPlayerNode *audioPlayerNode; static AVAudioPlayerNode *audioPlayerNode;
static AVAudioPCMBuffer *pcmBuffer; static AVAudioPCMBuffer *pcmBuffer;
@@ -295,7 +296,7 @@ int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, v
DataManager* dataMan = [[DataManager alloc] init]; DataManager* dataMan = [[DataManager alloc] init];
TemporarySettings* tempSettings = [dataMan getSettings]; TemporarySettings* tempSettings = [dataMan getSettings];
bool useBluetoothD2P = tempSettings.useBuiltinMic || !tempSettings.redirectMic; bool useBluetoothD2P = tempSettings.useBuiltinMic || !tempSettings.redirectMic;
AVAudioSessionCategoryOptions bluetoothAudioOption = useBluetoothD2P ? AVAudioSessionCategoryOptionAllowBluetoothA2DP : AVAudioSessionCategoryOptionAllowBluetooth; AVAudioSessionCategoryOptions bluetoothAudioOption = useBluetoothD2P ? AVAudioSessionCategoryOptionAllowBluetoothA2DP : AVAudioSessionCategoryOptionAllowBluetoothHFP;
AVAudioSessionCategoryOptions volumeMixOption = tempSettings.duckOtherApps ? AVAudioSessionCategoryOptionDuckOthers : AVAudioSessionCategoryOptionMixWithOthers; AVAudioSessionCategoryOptions volumeMixOption = tempSettings.duckOtherApps ? AVAudioSessionCategoryOptionDuckOthers : AVAudioSessionCategoryOptionMixWithOthers;
AVAudioSession *session = [AVAudioSession sharedInstance]; AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:tempSettings.redirectMic ? AVAudioSessionCategoryPlayAndRecord : AVAudioSessionCategoryPlayback [session setCategory:tempSettings.redirectMic ? AVAudioSessionCategoryPlayAndRecord : AVAudioSessionCategoryPlayback
@@ -304,7 +305,8 @@ int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, v
error:nil]; error:nil];
if(tempSettings.redirectMic) if(@available(iOS 13.0, *)) [session setAllowHapticsAndSystemSoundsDuringRecording:YES error:nil]; if(tempSettings.redirectMic) if(@available(iOS 13.0, *)) [session setAllowHapticsAndSystemSoundsDuringRecording:YES error:nil];
[session setActive:YES error:nil]; [session setActive:YES error:nil];
audioSessionInterrupted = false;
AudioEngineInit(audioConfig.sampleRate, audioConfig.channelCount); AudioEngineInit(audioConfig.sampleRate, audioConfig.channelCount);
return 0; return 0;
@@ -437,7 +439,7 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
} }
} }
// 播放 // 播放
[audioPlayerNode scheduleBuffer:buffer completionHandler:nil]; if(!audioSessionInterrupted) [audioPlayerNode scheduleBuffer:buffer completionHandler:nil];
} }
else{ else{
@@ -534,6 +536,7 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
LiInterruptConnection(); LiInterruptConnection();
[audioPlayerNode stop]; [audioPlayerNode stop];
[audioEngine stop]; [audioEngine stop];
[[NSNotificationCenter defaultCenter] removeObserver:self];
// We dispatch this async to get out because this can be invoked // We dispatch this async to get out because this can be invoked
// on a thread inside common and we don't want to deadlock. It also avoids // on a thread inside common and we don't want to deadlock. It also avoids
@@ -545,6 +548,27 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
}); });
} }
- (void)handleAudioSessionInterruption:(NSNotification *)notification {
NSDictionary *info = notification.userInfo;
AVAudioSessionInterruptionType type =
[info[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
switch (type) {
case AVAudioSessionInterruptionTypeBegan:
audioSessionInterrupted = true;
[audioPlayerNode stop];
[audioEngine stop];
break;
case AVAudioSessionInterruptionTypeEnded:
AudioEngineInit(audioConfig.sampleRate, audioConfig.channelCount);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
audioSessionInterrupted = false;
});
default:
break;
}
}
-(id) initWithConfig:(StreamConfiguration*)config renderer:(VideoDecoderRenderer*)myRenderer connectionCallbacks:(id<ConnectionCallbacks>)callbacks -(id) initWithConfig:(StreamConfiguration*)config renderer:(VideoDecoderRenderer*)myRenderer connectionCallbacks:(id<ConnectionCallbacks>)callbacks
{ {
self = [super init]; self = [super init];
@@ -662,7 +686,12 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
_clCallbacks.rumbleTriggers = ClRumbleTriggers; _clCallbacks.rumbleTriggers = ClRumbleTriggers;
_clCallbacks.setMotionEventState = ClSetMotionEventState; _clCallbacks.setMotionEventState = ClSetMotionEventState;
_clCallbacks.setControllerLED = ClSetControllerLED; _clCallbacks.setControllerLED = ClSetControllerLED;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:nil];
return self; return self;
} }