diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard
index edc5735f..831f22a9 100644
--- a/VoidLink/Base.lproj/iPad.storyboard
+++ b/VoidLink/Base.lproj/iPad.storyboard
@@ -1186,6 +1186,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1360,16 +1380,16 @@
-
+
-
+
@@ -1494,24 +1514,24 @@
-
-
+
+
-
-
+
@@ -1586,6 +1606,8 @@
+
+
diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard
index faacc571..7c427a78 100644
--- a/VoidLink/Base.lproj/iPhone.storyboard
+++ b/VoidLink/Base.lproj/iPhone.storyboard
@@ -2214,16 +2214,16 @@
-
+
-
+
-
+
@@ -2297,6 +2297,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2370,6 +2390,8 @@
+
+
diff --git a/VoidLink/Database/DataManager.h b/VoidLink/Database/DataManager.h
index c06734b8..df00dc02 100644
--- a/VoidLink/Database/DataManager.h
+++ b/VoidLink/Database/DataManager.h
@@ -128,6 +128,7 @@ typedef NS_ENUM(NSInteger, WidgetSizeTransition) {
audioEngine:(NSInteger)audioEngine
appendLeftClick:(BOOL)appendLeftClick
duckOtherApps:(BOOL)duckOtherApps
+ muteInBackground:(BOOL)muteInBackground
backgroundSessionTimer:(NSInteger)backgroundSessionTimer;
- (NSArray*) getHosts;
diff --git a/VoidLink/Database/DataManager.m b/VoidLink/Database/DataManager.m
index 0fe30730..02ee6214 100644
--- a/VoidLink/Database/DataManager.m
+++ b/VoidLink/Database/DataManager.m
@@ -111,6 +111,7 @@
audioEngine:(NSInteger)audioEngine
appendLeftClick:(BOOL)appendLeftClick
duckOtherApps:(BOOL)duckOtherApps
+ muteInBackground:(BOOL)muteInBackground
backgroundSessionTimer:(NSInteger)backgroundSessionTimer{
[_managedObjectContext performBlockAndWait:^{
@@ -172,6 +173,7 @@
settingsToSave.audioEngine = [NSNumber numberWithInteger:audioEngine];
settingsToSave.appendLeftClick = appendLeftClick;
settingsToSave.duckOtherApps = duckOtherApps;
+ settingsToSave.muteInBackground = muteInBackground;
settingsToSave.rememberFoldState = rememberFoldState;
[self saveData];
}];
diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h
index 1ca791c2..c4883e98 100644
--- a/VoidLink/Database/TemporarySettings.h
+++ b/VoidLink/Database/TemporarySettings.h
@@ -85,6 +85,7 @@
@property (nonatomic, retain) NSNumber * audioEngine;
@property (nonatomic) BOOL appendLeftClick;
@property (nonatomic) BOOL duckOtherApps;
+@property (nonatomic) BOOL muteInBackground;
@property (nonatomic, retain) NSNumber * framePacingMode;
- (id) initFromSettings:(Settings*)settings;
diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m
index 353bc642..29380707 100644
--- a/VoidLink/Database/TemporarySettings.m
+++ b/VoidLink/Database/TemporarySettings.m
@@ -142,6 +142,7 @@
self.audioEngine = settings.audioEngine;
self.appendLeftClick = settings.appendLeftClick;
self.duckOtherApps = settings.duckOtherApps;
+ self.muteInBackground = settings.muteInBackground;
#endif
return self;
diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents
index 0ae9a686..ad6cca75 100644
--- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents
+++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents
@@ -57,6 +57,7 @@
+
diff --git a/VoidLink/Stream/Connection.h b/VoidLink/Stream/Connection.h
index 136fdefc..562d037a 100644
--- a/VoidLink/Stream/Connection.h
+++ b/VoidLink/Stream/Connection.h
@@ -19,6 +19,8 @@
#define CONN_TEST_SERVER "www.baidu.com"
@interface Connection : NSOperation
+@property (class, nonatomic, assign) bool muteInBackground;
+@property (class, nonatomic, assign) bool useSystemAudioEngine;
-(id) initWithConfig:(StreamConfiguration*)config renderer:(VideoDecoderRenderer*)myRenderer connectionCallbacks:(id)callbacks;
-(void) terminate;
@@ -26,7 +28,7 @@
-(BandwidthTracker *) getBwTracker;
-(BOOL) getVideoStats:(video_stats_t*)stats;
-(NSString*) getActiveCodecName;
+
+ (void)setVolume:(float)newVolume;
-+ (void)setUseSystemAudioEngine:(bool)useSysAudioEngine;
@end
diff --git a/VoidLink/Stream/Connection.m b/VoidLink/Stream/Connection.m
index a18dbb82..d8fea102 100644
--- a/VoidLink/Stream/Connection.m
+++ b/VoidLink/Stream/Connection.m
@@ -56,6 +56,8 @@ static AVAudioPlayerNode *audioPlayerNode;
static AVAudioPCMBuffer *pcmBuffer;
static AVAudioFormat *audioFormat;
+static bool muteInBackground;
+
static VideoDecoderRenderer* renderer;
static BandwidthTracker *bwTracker;
@@ -334,6 +336,10 @@ void ArCleanup(void)
volume = powf(linearVolume, exponent);
}
++ (void)setMuteInBackground:(bool)mute {
+ muteInBackground = mute;
+}
+
+ (void)setUseSystemAudioEngine:(bool)useSysAudioEngine{
useSystemAudioEngine = useSysAudioEngine;
}
@@ -393,6 +399,8 @@ void AudioEngineInit(int sampleRate, int channelCount) {
void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
{
+ if(appDidEnterBackgroundWithoutPip && muteInBackground) return;
+
int decodeLen;
// Don't queue if there's already more than 30 ms of audio data waiting
diff --git a/VoidLink/Stream/VideoDecoderRenderer.h b/VoidLink/Stream/VideoDecoderRenderer.h
index be311fd1..3bc61d06 100644
--- a/VoidLink/Stream/VideoDecoderRenderer.h
+++ b/VoidLink/Stream/VideoDecoderRenderer.h
@@ -18,7 +18,6 @@
@property (atomic, readonly) PlotMetrics decodeMetrics;
@property (atomic, readonly) PlotMetrics frameQueueMetrics;
-@property (atomic, assign) bool appDidEnterBackgroundWithoutPiP;
@property (nonatomic, strong, readonly) AVSampleBufferDisplayLayer *displayLayer;
diff --git a/VoidLink/Stream/VideoDecoderRenderer.m b/VoidLink/Stream/VideoDecoderRenderer.m
index fa655275..47ea99e8 100644
--- a/VoidLink/Stream/VideoDecoderRenderer.m
+++ b/VoidLink/Stream/VideoDecoderRenderer.m
@@ -115,7 +115,7 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
NSLog(@"initializing video decoder %f", CACurrentMediaTime());
self = [super init];
- _appDidEnterBackgroundWithoutPiP = false;
+ appDidEnterBackgroundWithoutPip = false;
_sq = dispatch_queue_create("com.moonlight.VideoDecoderRenderer",
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0));
@@ -329,7 +329,7 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
// Legacy frame pacing callback - matches upstream/Integration behavior exactly
- (void)displayLinkCallback:(CADisplayLink *)sender
{
- if(_appDidEnterBackgroundWithoutPiP) return;
+ if(appDidEnterBackgroundWithoutPip) return;
VIDEO_FRAME_HANDLE handle;
PDECODE_UNIT du;
@@ -379,7 +379,7 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
Log(LOG_I, @"Setting timebase for stream to %d / %d", pts.value, pts.timescale);
}
- if(!_appDidEnterBackgroundWithoutPiP) [self->_displayLayer enqueueSampleBuffer:frame.sampleBuffer];
+ if(!appDidEnterBackgroundWithoutPip) [self->_displayLayer enqueueSampleBuffer:frame.sampleBuffer];
#ifdef DISPLAYLINK_VERBOSE
// Some OS-level metrics I'm not sure what to do with
diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h
index 4ec296b1..82f0d841 100644
--- a/VoidLink/ViewControllers/SettingsViewController.h
+++ b/VoidLink/ViewControllers/SettingsViewController.h
@@ -187,6 +187,9 @@
@property (strong, nonatomic) IBOutlet UIStackView *duckOtherAppStack;
@property (strong, nonatomic) IBOutlet UISwitch *duckOtherAppSwitch;
+@property (strong, nonatomic) IBOutlet UIStackView *muteInBackgroundStack;
+@property (strong, nonatomic) IBOutlet UISwitch *muteInBackgroundSwitch;
+
@property (strong, nonatomic) IBOutlet UIStackView *testStack;
@property (nonatomic, strong) MicHandler *micHandler;
diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m
index b45a2e9b..70824094 100644
--- a/VoidLink/ViewControllers/SettingsViewController.m
+++ b/VoidLink/ViewControllers/SettingsViewController.m
@@ -792,6 +792,7 @@ BOOL isCustomResolution(int resolutionSelected) {
[self addSetting:self.useBuiltinMicStack ofId:@"useBuiltinMicStack" withInfoTag:YES withDynamicLabel:NO to:audioSection];
[self addSetting:self.micVolumeStack ofId:@"micVolumeStack" withInfoTag:NO withDynamicLabel:YES to:audioSection];
[self addSetting:self.duckOtherAppStack ofId:@"duckOtherAppStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
+ [self addSetting:self.muteInBackgroundStack ofId:@"muteInBackgroundStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
// [self addSetting:self.audioEngineStack ofId:@"audioEngineStack" withInfoTag:YES withDynamicLabel:NO to:audioSection];
// cancel audio engine selector due to system engine is unable to playback multi-channel audio
[self addSetting:self.audioConfigStack ofId:@"audioConfigStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
@@ -1718,6 +1719,9 @@ BOOL isCustomResolution(int resolutionSelected) {
[self.duckOtherAppSwitch setOn:self->tempSettings.duckOtherApps];
+ [self.muteInBackgroundSwitch setOn:tempSettings.muteInBackground];
+ [self.muteInBackgroundSwitch addTarget:self action:@selector(muteInBackgroundSwitchFlipped:) forControlEvents:UIControlEventValueChanged];
+
[self.micVolumeSlider setValue:self->tempSettings.micVolume.floatValue*100];
[self.micVolumeSlider addTarget:self action:@selector(micVolumeSliderMoved:) forControlEvents:UIControlEventValueChanged];
[self micVolumeSliderMoved:self.self.micVolumeSlider];
@@ -2387,6 +2391,10 @@ BOOL isCustomResolution(int resolutionSelected) {
});
}
+- (void)muteInBackgroundSwitchFlipped:(UISwitch* )sender{
+ Connection.muteInBackground = sender.isOn;
+}
+
- (void)redirectMicSwitchFlipped:(UISwitch* )sender{
if(sender.isOn) [self checkAndRequestMicPermission];
[self setHidden:!sender.isOn forStack:_useBuiltinMicStack];
@@ -2875,6 +2883,7 @@ BOOL isCustomResolution(int resolutionSelected) {
NSInteger audioEngine = self.audioEngineSelector.selectedSegmentIndex;
BOOL appendLeftClick = self.appendLeftClickSwitch.isOn;
BOOL duckOtherApps = self.duckOtherAppSwitch.isOn;
+ BOOL muteInBackground = self.muteInBackgroundSwitch.isOn;
NSInteger backgroundSessionTimer = self.backgroundSessionTimerSlider.value == self.backgroundSessionTimerSlider.maximumValue ? (uint32_t) INT16_MAX : (uint32_t)self.backgroundSessionTimerSlider.value;
[dataMan saveSettingsWithBitrate:_bitrate
@@ -2932,6 +2941,7 @@ BOOL isCustomResolution(int resolutionSelected) {
audioEngine:audioEngine
appendLeftClick:appendLeftClick
duckOtherApps:duckOtherApps
+ muteInBackground:muteInBackground
backgroundSessionTimer:backgroundSessionTimer];
}
diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m
index 0f722a2b..d5b72a18 100644
--- a/VoidLink/ViewControllers/StreamFrameViewController.m
+++ b/VoidLink/ViewControllers/StreamFrameViewController.m
@@ -374,7 +374,8 @@
}
else [micHandler stopTappingWithStopEngine:false];
- [Connection setUseSystemAudioEngine:_settings.audioEngine.intValue == SystemAudioEngine];
+ Connection.useSystemAudioEngine = _settings.audioEngine.intValue == SystemAudioEngine;
+ Connection.muteInBackground = _settings.muteInBackground;
if(!viewJustLoaded) [_controllerSupport updateControllerSupport:self.streamConfig delegate:self];
// reload controllerSupport obj, this is mandatory for OSC reload,especially when the stream view is launched without OSC
@@ -1033,7 +1034,7 @@
- (void)applicationWillResignActive:(NSNotification *)notification {
//[self.pipController startPictureInPicture];
//sleep(1);
- _streamMan.videoRenderer.appDidEnterBackgroundWithoutPiP = true;
+ appDidEnterBackgroundWithoutPip = true;
[_streamView saveRelocatedWidgetViews];
@@ -1050,7 +1051,7 @@
}
- (void)applicationDidBecomeActive:(NSNotification *)notification {
- _streamMan.videoRenderer.appDidEnterBackgroundWithoutPiP = false;
+ appDidEnterBackgroundWithoutPip = false;
// Stop the background timer, since we're foregrounded again
if (_inactivityTimer != nil) {
Log(LOG_I, @"Stopping inactivity timer after becoming active again");
@@ -1083,9 +1084,9 @@
NSLog(@"did enter background, %d, %@, %d", _settings.enablePIP, self.pipController, self.pipController.isPictureInPictureActive);
if (_settings.enablePIP && self.pipController && self.pipController.isPictureInPictureActive) {
//Log(LOG_I, @"PIP is active, not terminating stream");
- _streamMan.videoRenderer.appDidEnterBackgroundWithoutPiP = false;
+ appDidEnterBackgroundWithoutPip = false;
} else {
- _streamMan.videoRenderer.appDidEnterBackgroundWithoutPiP = true;
+ appDidEnterBackgroundWithoutPip = true;
if ([_settings.renderingBackend intValue] == RENDER_METAL && self.metalViewController) {
Log(LOG_I, @"Pausing Metal renderer on background");
diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings
index 1e58bfa1..72a90a02 100644
--- a/VoidLink/mul.lproj/iPad.xcstrings
+++ b/VoidLink/mul.lproj/iPad.xcstrings
@@ -2419,6 +2419,36 @@
}
}
},
+ "hPX-cJ-dgH.text" : {
+ "comment" : "Class = \"UILabel\"; text = \"Mute in Background\"; ObjectID = \"hPX-cJ-dgH\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Mute in Background"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "后台静音"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行静音"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行静音"
+ }
+ }
+ }
+ },
"hq8-dy-8BF.text" : {
"comment" : "Class = \"UILabel\"; text = \"Custom Resolution\"; ObjectID = \"hq8-dy-8BF\";",
"extractionState" : "extracted_with_value",
diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings
index 4ab8ec20..4b3cc398 100644
--- a/VoidLink/mul.lproj/iPhone.xcstrings
+++ b/VoidLink/mul.lproj/iPhone.xcstrings
@@ -3115,6 +3115,36 @@
}
}
},
+ "PaG-9w-YxB.text" : {
+ "comment" : "Class = \"UILabel\"; text = \"Mute in Background\"; ObjectID = \"PaG-9w-YxB\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Mute in Background"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "后台静音"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行静音"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行静音"
+ }
+ }
+ }
+ },
"Pdb-Bs-kMJ.text" : {
"comment" : "Class = \"UILabel\"; text = \"Statistics Overlay\"; ObjectID = \"Pdb-Bs-kMJ\";",
"extractionState" : "extracted_with_value",
diff --git a/moonlight-common/moonlight-common-c b/moonlight-common/moonlight-common-c
index 857026df..623adaae 160000
--- a/moonlight-common/moonlight-common-c
+++ b/moonlight-common/moonlight-common-c
@@ -1 +1 @@
-Subproject commit 857026df71792e97e3156948e1c440050bc579d0
+Subproject commit 623adaae5e138a7ed435e4a45ccc0f2c81befab0