system audio playback fix
This commit is contained in:
1 parent
9807a77d9b
commit
e87f0f1aa0
3 files changed
+22
-58
No files matched your search
@@ -30,5 +30,6 @@
|
|||||||
-(NSString*) getActiveCodecName;
|
-(NSString*) getActiveCodecName;
|
||||||
|
|
||||||
+ (void)setVolume:(float)newVolume;
|
+ (void)setVolume:(float)newVolume;
|
||||||
|
+ (void)resetSysAudioPlayback;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -48,7 +48,6 @@ static SDL_AudioDeviceID audioDevice;
|
|||||||
static OPUS_MULTISTREAM_CONFIGURATION audioConfig;
|
static OPUS_MULTISTREAM_CONFIGURATION audioConfig;
|
||||||
static void* audioBuffer;
|
static void* audioBuffer;
|
||||||
static float volume = 1.0;
|
static float volume = 1.0;
|
||||||
static bool sysAudioQueueReset = false;
|
|
||||||
static int audioFrameSize;
|
static int audioFrameSize;
|
||||||
|
|
||||||
static bool useSystemAudioEngine;
|
static bool useSystemAudioEngine;
|
||||||
@@ -57,8 +56,6 @@ static AVAudioEngine *audioEngine;
|
|||||||
static AVAudioPlayerNode *audioPlayerNode;
|
static AVAudioPlayerNode *audioPlayerNode;
|
||||||
static AVAudioPCMBuffer *pcmBuffer;
|
static AVAudioPCMBuffer *pcmBuffer;
|
||||||
static AVAudioFormat *audioFormat;
|
static AVAudioFormat *audioFormat;
|
||||||
static int64_t systemAudioScheduledFrames;
|
|
||||||
static CFTimeInterval systemAudioLastFlushTime;
|
|
||||||
|
|
||||||
static bool muteInBackground;
|
static bool muteInBackground;
|
||||||
static bool fullColorRange;
|
static bool fullColorRange;
|
||||||
@@ -67,32 +64,6 @@ static VideoDecoderRenderer* renderer;
|
|||||||
|
|
||||||
static BandwidthTracker *bwTracker;
|
static BandwidthTracker *bwTracker;
|
||||||
|
|
||||||
static int64_t GetSystemAudioQueuedFrames(void)
|
|
||||||
{
|
|
||||||
if (audioPlayerNode == nil) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVAudioTime *nodeTime = audioPlayerNode.lastRenderTime;
|
|
||||||
if (nodeTime == nil) {
|
|
||||||
return systemAudioScheduledFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVAudioTime *playerTime = [audioPlayerNode playerTimeForNodeTime:nodeTime];
|
|
||||||
if (playerTime == nil) {
|
|
||||||
return systemAudioScheduledFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t queuedFrames = systemAudioScheduledFrames - playerTime.sampleTime;
|
|
||||||
return queuedFrames > 0 ? queuedFrames : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ResetSystemAudioBackpressureState(void)
|
|
||||||
{
|
|
||||||
systemAudioScheduledFrames = 0;
|
|
||||||
systemAudioLastFlushTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DrDecoderSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags)
|
int DrDecoderSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags)
|
||||||
{
|
{
|
||||||
[renderer setupWithVideoFormat:videoFormat width:width height:height frameRate:redrawRate fullRange:fullColorRange];
|
[renderer setupWithVideoFormat:videoFormat width:width height:height frameRate:redrawRate fullRange:fullColorRange];
|
||||||
@@ -377,7 +348,6 @@ void ArCleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngineInit(int sampleRate, int channelCount) {
|
void AudioEngineInit(int sampleRate, int channelCount) {
|
||||||
ResetSystemAudioBackpressureState();
|
|
||||||
|
|
||||||
audioEngine = [[AVAudioEngine alloc] init];
|
audioEngine = [[AVAudioEngine alloc] init];
|
||||||
audioPlayerNode = [[AVAudioPlayerNode alloc] init];
|
audioPlayerNode = [[AVAudioPlayerNode alloc] init];
|
||||||
@@ -430,6 +400,16 @@ void AudioEngineInit(int sampleRate, int channelCount) {
|
|||||||
[audioPlayerNode play];
|
[audioPlayerNode play];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (void)resetSysAudioPlayback {
|
||||||
|
audioSessionInterrupted = true;
|
||||||
|
[audioPlayerNode stop];
|
||||||
|
[audioEngine stop];
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
||||||
{
|
{
|
||||||
if(appDidEnterBackgroundWithoutPip && muteInBackground) return;
|
if(appDidEnterBackgroundWithoutPip && muteInBackground) return;
|
||||||
@@ -456,41 +436,20 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
|||||||
float* fbuf = (float*)audioBuffer;
|
float* fbuf = (float*)audioBuffer;
|
||||||
|
|
||||||
if(useSystemAudioEngine){
|
if(useSystemAudioEngine){
|
||||||
int64_t maxQueuedFrames = (int64_t)audioConfig.samplesPerFrame * 10;
|
// 创建 AVAudioPCMBuffer
|
||||||
CFTimeInterval now = CACurrentMediaTime();
|
|
||||||
if (GetSystemAudioQueuedFrames() > maxQueuedFrames &&
|
|
||||||
now - systemAudioLastFlushTime >= 5) {
|
|
||||||
// Drop stale local backlog without slowing down upstream packet
|
|
||||||
// consumption, which keeps background playback stable.
|
|
||||||
|
|
||||||
NSLog(@"sdfasfdsfasdfasfasfasdfasfasfdfasf");
|
|
||||||
|
|
||||||
sysAudioQueueReset = true;
|
|
||||||
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
|
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delayTime), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
||||||
sysAudioQueueReset = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
[audioPlayerNode reset];
|
|
||||||
ResetSystemAudioBackpressureState();
|
|
||||||
systemAudioLastFlushTime = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVAudioFrameCount frameCount = decodeLen;
|
AVAudioFrameCount frameCount = decodeLen;
|
||||||
AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:audioFormat frameCapacity:frameCount];
|
AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:audioFormat frameCapacity:frameCount];
|
||||||
buffer.frameLength = frameCount;
|
buffer.frameLength = frameCount;
|
||||||
|
|
||||||
|
// 拷贝数据到 buffer
|
||||||
for (int ch = 0; ch < audioConfig.channelCount; ch++) {
|
for (int ch = 0; ch < audioConfig.channelCount; ch++) {
|
||||||
float *dst = buffer.floatChannelData[ch];
|
float *dst = buffer.floatChannelData[ch];
|
||||||
for (int i = 0; i < decodeLen; i++) {
|
for (int i = 0; i < decodeLen; i++) {
|
||||||
dst[i] = fbuf[i * audioConfig.channelCount + ch] * (sysAudioQueueReset ? 0 : volume); // 非交错数据
|
dst[i] = fbuf[i * audioConfig.channelCount + ch] * volume; // 非交错数据
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 播放
|
||||||
if(!audioSessionInterrupted) {
|
if(!audioSessionInterrupted) [audioPlayerNode scheduleBuffer:buffer completionHandler:nil];
|
||||||
[audioPlayerNode scheduleBuffer:buffer completionHandler:nil];
|
|
||||||
systemAudioScheduledFrames += frameCount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
@@ -586,7 +545,6 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
|
|||||||
// won't be able to acquire it if LiStartConnection is in
|
// won't be able to acquire it if LiStartConnection is in
|
||||||
// progress.
|
// progress.
|
||||||
LiInterruptConnection();
|
LiInterruptConnection();
|
||||||
ResetSystemAudioBackpressureState();
|
|
||||||
[audioPlayerNode stop];
|
[audioPlayerNode stop];
|
||||||
[audioEngine stop];
|
[audioEngine stop];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
@@ -609,7 +567,6 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case AVAudioSessionInterruptionTypeBegan:
|
case AVAudioSessionInterruptionTypeBegan:
|
||||||
audioSessionInterrupted = true;
|
audioSessionInterrupted = true;
|
||||||
ResetSystemAudioBackpressureState();
|
|
||||||
[audioPlayerNode stop];
|
[audioPlayerNode stop];
|
||||||
[audioEngine stop];
|
[audioEngine stop];
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1087,6 +1087,7 @@
|
|||||||
//[self.pipController startPictureInPicture];
|
//[self.pipController startPictureInPicture];
|
||||||
//sleep(1);
|
//sleep(1);
|
||||||
appDidEnterBackgroundWithoutPip = true;
|
appDidEnterBackgroundWithoutPip = true;
|
||||||
|
|
||||||
NSLog(@"applicationWillResignActive %f", CACurrentMediaTime());
|
NSLog(@"applicationWillResignActive %f", CACurrentMediaTime());
|
||||||
[_streamView saveStreamViewWidgetChanges];
|
[_streamView saveStreamViewWidgetChanges];
|
||||||
|
|
||||||
@@ -1105,6 +1106,11 @@
|
|||||||
- (void)applicationDidBecomeActive:(NSNotification *)notification {
|
- (void)applicationDidBecomeActive:(NSNotification *)notification {
|
||||||
appDidEnterBackgroundWithoutPip = false;
|
appDidEnterBackgroundWithoutPip = false;
|
||||||
[_streamMan setNeedRequeuing:true];
|
[_streamMan setNeedRequeuing:true];
|
||||||
|
// dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC));
|
||||||
|
// dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[Connection resetSysAudioPlayback];
|
||||||
|
// });
|
||||||
|
|
||||||
// Stop the background timer, since we're foregrounded again
|
// Stop the background timer, since we're foregrounded again
|
||||||
if (_inactivityTimer != nil) {
|
if (_inactivityTimer != nil) {
|
||||||
Log(LOG_I, @"Stopping inactivity timer after becoming active again");
|
Log(LOG_I, @"Stopping inactivity timer after becoming active again");
|
||||||
|
|||||||
Reference in new issue
Block a user