124 lines
3.4 kB
1
import { Patch } from "@moonlight-mod/types";
2
3
const logger = moonlight.getLogger("rocketship");
4
const getDisplayMediaOrig = navigator.mediaDevices.getDisplayMedia;
5
6
async function getVenmicStream() {
7
try {
8
const devices = await navigator.mediaDevices.enumerateDevices();
9
logger.debug("Devices:", devices);
10
11
// This isn't vencord :(
12
const id = devices.find((device) => device.label === "vencord-screen-share")?.deviceId;
13
if (!id) return null;
14
logger.debug("Got venmic device ID:", id);
15
16
const stream = await navigator.mediaDevices.getUserMedia({
17
audio: {
18
deviceId: {
19
exact: id
20
},
21
autoGainControl: false,
22
echoCancellation: false,
23
noiseSuppression: false
24
}
25
});
26
27
return stream.getAudioTracks();
28
} catch (error) {
29
logger.warn("Failed to get venmic stream:", error);
30
return null;
31
}
32
}
33
34
navigator.mediaDevices.getDisplayMedia = async function getDisplayMediaRedirect(options) {
35
const orig = await getDisplayMediaOrig.call(this, options);
36
37
const venmic = await getVenmicStream();
38
logger.debug("venmic", venmic);
39
if (venmic != null) {
40
// venmic will be proxying all audio, so we need to remove the original
41
// tracks to not cause overlap
42
for (const track of orig.getAudioTracks()) {
43
orig.removeTrack(track);
44
}
45
46
for (const track of venmic) {
47
orig.addTrack(track);
48
}
49
}
50
51
return orig;
52
};
53
54
export const patches: Patch[] = [
55
// "Ensure discord_voice is happy"
56
{
57
find: "RustAudioDeviceModule",
58
replace: [
59
{
60
match: /static supported\(\)\{.+?\}/,
61
replacement: "static supported(){return true}"
62
},
63
{
64
match: "supported(){return!0}",
65
replacement: "supported(){return true}"
66
}
67
]
68
},
69
// Remove Native media engine from list of choices
70
{
71
find: '.CAMERA_BACKGROUND_LIVE="cameraBackgroundLive"',
72
replace: {
73
match: /.\..{1,2}\.NATIVE,/,
74
replacement: ""
75
}
76
},
77
// Stub out browser checks to allow us to use WebRTC voice on Embedded
78
{
79
find: "Using Unified Plan (",
80
replace: {
81
match: /return .\..{1,2}\?\((.)\.info/,
82
replacement: (_, logger) => `return true?(${logger}.info`
83
}
84
},
85
{
86
find: '"UnifiedConnection("',
87
replace: {
88
match: /this\.videoSupported=.\..{1,2};/,
89
replacement: "this.videoSupported=true;"
90
}
91
},
92
{
93
find: "OculusBrowser",
94
replace: [
95
{
96
match: /"Firefox"===(.)\(\)\.name/g,
97
replacement: (orig, info) => `true||${orig}`
98
}
99
]
100
},
101
{
102
find: ".getMediaEngine().getDesktopSource",
103
replace: {
104
match: /.\.isPlatformEmbedded/,
105
replacement: "false"
106
}
107
},
108
{
109
// Matching MediaEngineStore
110
find: '"displayName","MediaEngineStore")',
111
replace: [
112
// Prevent loading of krisp native module by stubbing out desktop checks
113
{
114
match: /\(\(0,.\.isWindows\)\(\)\|\|\(0,.\.isLinux\)\(\)\|\|.+?&&!__OVERLAY__/,
115
replacement: (orig, macosPlatformCheck) => `false&&!__OVERLAY__`
116
},
117
// Enable loading of web krisp equivelant by replacing isWeb with true
118
{
119
match: /\(0,.\.isWeb\)\(\)&&(.{1,2}\.supports\(.{1,2}\..{1,2}.NOISE_CANCELLATION)/,
120
replacement: (orig, supportsNoiseCancellation) => `true&&${supportsNoiseCancellation}`
121
}
122
]
123
}
124
];
125