mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-06 23:57:19 +02:00
Rewrite volume control feature
This commit is contained in:
parent
23fb50cb6f
commit
e852b246d3
@ -459,6 +459,29 @@ BxLogger.info('patchRemotePlayMkb', ${configsVar});
|
|||||||
return str;
|
return str;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
patchAudioMediaStream(str: string) {
|
||||||
|
const text = '.srcObject=this.audioMediaStream,';
|
||||||
|
if (!str.includes(text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newCode = `window.BX_EXPOSED.setupGainNode(arguments[1], this.audioMediaStream),`;
|
||||||
|
|
||||||
|
str = str.replace(text, text + newCode);
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
|
||||||
|
patchCombinedAudioVideoMediaStream(str: string) {
|
||||||
|
const text = '.srcObject=this.combinedAudioVideoStream';
|
||||||
|
if (!str.includes(text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newCode = `,window.BX_EXPOSED.setupGainNode(arguments[0], this.combinedAudioVideoStream)`;
|
||||||
|
str = str.replace(text, text + newCode);
|
||||||
|
return str;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let PATCH_ORDERS: PatchArray = [
|
let PATCH_ORDERS: PatchArray = [
|
||||||
@ -501,6 +524,12 @@ let PLAYING_PATCH_ORDERS: PatchArray = [
|
|||||||
'patchStreamHud',
|
'patchStreamHud',
|
||||||
'playVibration',
|
'playVibration',
|
||||||
|
|
||||||
|
// Patch volume control for normal stream
|
||||||
|
getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && !getPref(PrefKey.STREAM_COMBINE_SOURCES) && 'patchAudioMediaStream',
|
||||||
|
// Patch volume control for combined audio+video stream
|
||||||
|
getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && getPref(PrefKey.STREAM_COMBINE_SOURCES) && 'patchCombinedAudioVideoMediaStream',
|
||||||
|
|
||||||
|
|
||||||
STATES.hasTouchSupport && getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === 'all' && 'exposeTouchLayoutManager',
|
STATES.hasTouchSupport && getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === 'all' && 'exposeTouchLayoutManager',
|
||||||
STATES.hasTouchSupport && (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === 'off' || getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) && 'disableTakRenderer',
|
STATES.hasTouchSupport && (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === 'off' || getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) && 'disableTakRenderer',
|
||||||
|
|
||||||
|
@ -91,5 +91,26 @@ export const BxExposed = {
|
|||||||
BxEvent.dispatch(window, BxEvent.TITLE_INFO_READY);
|
BxEvent.dispatch(window, BxEvent.TITLE_INFO_READY);
|
||||||
|
|
||||||
return titleInfo;
|
return titleInfo;
|
||||||
|
},
|
||||||
|
|
||||||
|
setupGainNode: ($media: HTMLMediaElement, audioStream: MediaStream) => {
|
||||||
|
if ($media instanceof HTMLAudioElement) {
|
||||||
|
$media.muted = true;
|
||||||
|
$media.addEventListener('playing', e => {
|
||||||
|
$media.muted = true;
|
||||||
|
$media.pause();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$media.muted = true;
|
||||||
|
$media.addEventListener('playing', e => {
|
||||||
|
$media.muted = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const audioCtx = STATES.currentStream.audioContext!;
|
||||||
|
const source = audioCtx.createMediaStreamSource(audioStream);
|
||||||
|
|
||||||
|
const gainNode = audioCtx.createGain(); // call monkey-patched createGain() in BxAudioContext
|
||||||
|
source.connect(gainNode).connect(audioCtx.destination);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { BxEvent } from "@utils/bx-event";
|
import { BxEvent } from "@utils/bx-event";
|
||||||
import { getPref, PrefKey } from "@utils/preferences";
|
import { getPref, PrefKey } from "@utils/preferences";
|
||||||
import { STATES } from "@utils/global";
|
import { STATES } from "@utils/global";
|
||||||
import { UserAgent } from "@utils/user-agent";
|
|
||||||
import { BxLogger } from "@utils/bx-logger";
|
import { BxLogger } from "@utils/bx-logger";
|
||||||
|
|
||||||
export function patchVideoApi() {
|
export function patchVideoApi() {
|
||||||
@ -104,10 +103,6 @@ export function patchRtcPeerConnection() {
|
|||||||
STATES.currentStream.peerConnection = conn;
|
STATES.currentStream.peerConnection = conn;
|
||||||
|
|
||||||
conn.addEventListener('connectionstatechange', e => {
|
conn.addEventListener('connectionstatechange', e => {
|
||||||
if (conn.connectionState === 'connecting') {
|
|
||||||
STATES.currentStream.audioGainNode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BxLogger.info('connectionstatechange', conn.connectionState);
|
BxLogger.info('connectionstatechange', conn.connectionState);
|
||||||
});
|
});
|
||||||
return conn;
|
return conn;
|
||||||
@ -115,46 +110,23 @@ export function patchRtcPeerConnection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function patchAudioContext() {
|
export function patchAudioContext() {
|
||||||
if (UserAgent.isSafari(true)) {
|
const OrgAudioContext = window.AudioContext;
|
||||||
const nativeCreateGain = window.AudioContext.prototype.createGain;
|
const nativeCreateGain = OrgAudioContext.prototype.createGain;
|
||||||
window.AudioContext.prototype.createGain = function() {
|
|
||||||
|
// @ts-ignore
|
||||||
|
window.AudioContext = function(options?: AudioContextOptions | undefined): AudioContext {
|
||||||
|
const ctx = new OrgAudioContext(options);
|
||||||
|
BxLogger.info('patchAudioContext', ctx, options);
|
||||||
|
|
||||||
|
ctx.createGain = function() {
|
||||||
const gainNode = nativeCreateGain.apply(this);
|
const gainNode = nativeCreateGain.apply(this);
|
||||||
gainNode.gain.value = getPref(PrefKey.AUDIO_VOLUME) / 100;
|
gainNode.gain.value = getPref(PrefKey.AUDIO_VOLUME) / 100;
|
||||||
|
|
||||||
STATES.currentStream.audioGainNode = gainNode;
|
STATES.currentStream.audioGainNode = gainNode;
|
||||||
return gainNode;
|
return gainNode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const OrgAudioContext = window.AudioContext;
|
|
||||||
// @ts-ignore
|
|
||||||
window.AudioContext = function() {
|
|
||||||
const ctx = new OrgAudioContext();
|
|
||||||
STATES.currentStream.audioContext = ctx;
|
STATES.currentStream.audioContext = ctx;
|
||||||
STATES.currentStream.audioGainNode = null;
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nativePlay = HTMLAudioElement.prototype.play;
|
|
||||||
HTMLAudioElement.prototype.play = function() {
|
|
||||||
this.muted = true;
|
|
||||||
|
|
||||||
const promise = nativePlay.apply(this);
|
|
||||||
if (STATES.currentStream.audioGainNode) {
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.addEventListener('playing', e => (e.target as HTMLAudioElement).pause());
|
|
||||||
|
|
||||||
const audioCtx = STATES.currentStream.audioContext!;
|
|
||||||
// TOOD: check srcObject
|
|
||||||
const audioStream = audioCtx.createMediaStreamSource(this.srcObject as any);
|
|
||||||
const gainNode = audioCtx.createGain();
|
|
||||||
|
|
||||||
audioStream.connect(gainNode);
|
|
||||||
gainNode.connect(audioCtx.destination);
|
|
||||||
gainNode.gain.value = getPref(PrefKey.AUDIO_VOLUME) / 100;
|
|
||||||
STATES.currentStream.audioGainNode = gainNode;
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user