this repo has no description
1import type { BrowserWindow } from "electron";
2import { app, desktopCapturer } from "electron";
3import path from "node:path";
4import { type PatchBay } from "./types";
5
6const logger = moonlightHost.getLogger("rocketship");
7
8function getPatchbay() {
9 try {
10 const venmic = require(
11 path.join(path.dirname(moonlightHost.asarPath), "..", "venmic.node")
12 ) as { PatchBay: new () => PatchBay };
13 const patchbay = new venmic.PatchBay();
14 return patchbay;
15 } catch (error) {
16 logger.error("Failed to load venmic.node:", error);
17 return null;
18 }
19}
20
21const patchbay = getPatchbay();
22
23// TODO: figure out how to map source to window with venmic
24function linkVenmic() {
25 if (patchbay == null) return false;
26
27 try {
28 const pid =
29 app
30 .getAppMetrics()
31 .find((proc) => proc.name === "Audio Service")
32 ?.pid?.toString() ?? "";
33
34 logger.info("Audio Service PID:", pid);
35
36 patchbay.unlink();
37 return patchbay.link({
38 exclude: [
39 { "application.process.id": pid },
40 { "media.class": "Stream/Input/Audio" }
41 ],
42 ignore_devices: true,
43 only_speakers: true,
44 only_default_speakers: true
45 });
46 } catch (error) {
47 logger.error("Failed to link venmic:", error);
48 return false;
49 }
50}
51
52moonlightHost.events.on(
53 "window-created",
54 (window: BrowserWindow, isMainWindow: boolean) => {
55 if (!isMainWindow) return;
56 const windowSession = window.webContents.session;
57
58 // @ts-expect-error these types ancient
59 windowSession.setDisplayMediaRequestHandler(
60 (request: any, callback: any) => {
61 const linked = linkVenmic();
62 desktopCapturer
63 .getSources({ types: ["screen", "window"] })
64 .then((sources) => {
65 //logger.debug("desktopCapturer.getSources", sources);
66 logger.debug("Linked to venmic:", linked);
67
68 callback({
69 video: sources[0],
70 audio: "loopback"
71 });
72 });
73 },
74 { useSystemPicker: true }
75 );
76 }
77);