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(path.join(path.dirname(moonlightHost.asarPath), "..", "venmic.node")) as {
11 PatchBay: new () => PatchBay;
12 };
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: [{ "application.process.id": pid }, { "media.class": "Stream/Input/Audio" }],
39 ignore_devices: true,
40 only_speakers: true,
41 only_default_speakers: true
42 });
43 } catch (error) {
44 logger.error("Failed to link venmic:", error);
45 return false;
46 }
47}
48
49moonlightHost.events.on("window-created", (window: BrowserWindow, isMainWindow: boolean) => {
50 if (!isMainWindow) return;
51 const windowSession = window.webContents.session;
52
53 // @ts-expect-error these types ancient
54 windowSession.setDisplayMediaRequestHandler(
55 (request: any, callback: any) => {
56 const linked = linkVenmic();
57 desktopCapturer.getSources({ types: ["screen", "window"] }).then((sources) => {
58 //logger.debug("desktopCapturer.getSources", sources);
59 logger.debug("Linked to venmic:", linked);
60
61 callback({
62 video: sources[0],
63 audio: "loopback"
64 });
65 });
66 },
67 { useSystemPicker: true }
68 );
69});