project-client/src/main/screenShare.ts

85 lines
2.9 KiB
TypeScript
Raw Normal View History

2023-06-22 03:52:56 +09:00
/*
* SPDX-License-Identifier: GPL-3.0
2023-07-14 02:03:13 +09:00
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
2023-06-22 03:52:56 +09:00
* Copyright (c) 2023 Vendicated and Vencord contributors
*/
import { desktopCapturer, session, Streams } from "electron";
2023-06-22 03:52:56 +09:00
import type { StreamPick } from "renderer/components/ScreenSharePicker";
import { IpcEvents } from "shared/IpcEvents";
import { handle } from "./utils/ipcWrappers";
const isWayland =
process.platform === "linux" && (process.env.XDG_SESSION_TYPE === "wayland" || !!process.env.WAYLAND_DISPLAY);
2023-06-22 03:52:56 +09:00
export function registerScreenShareHandler() {
handle(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, async (_, id: string) => {
2023-06-22 03:52:56 +09:00
const sources = await desktopCapturer.getSources({
types: ["window", "screen"],
thumbnailSize: {
width: 1920,
height: 1080
}
});
return sources.find(s => s.id === id)?.thumbnail.toDataURL();
});
session.defaultSession.setDisplayMediaRequestHandler(async (request, callback) => {
// request full resolution on wayland right away because we always only end up with one result anyway
const width = isWayland ? 1920 : 176;
const sources = await desktopCapturer
.getSources({
types: ["window", "screen"],
thumbnailSize: {
width,
height: width * (9 / 16)
}
})
.catch(err => console.error("Error during screenshare picker", err));
2023-06-22 03:52:56 +09:00
if (!sources) return callback({});
2023-06-22 03:52:56 +09:00
const data = sources.map(({ id, name, thumbnail }) => ({
id,
name,
url: thumbnail.toDataURL()
}));
2023-08-07 07:48:23 +09:00
if (isWayland) {
const video = data[0];
if (video) {
const stream = await request.frame
.executeJavaScript(
`Vesktop.Components.ScreenShare.openScreenSharePicker(${JSON.stringify([video])},true)`
)
.catch(() => null);
if (stream === null) return callback({});
}
callback(video ? { video: sources[0] } : {});
2023-08-07 07:48:23 +09:00
return;
}
2023-06-22 03:52:56 +09:00
const choice = await request.frame
2023-07-14 02:03:13 +09:00
.executeJavaScript(`Vesktop.Components.ScreenShare.openScreenSharePicker(${JSON.stringify(data)})`)
2023-06-22 03:52:56 +09:00
.then(e => e as StreamPick)
.catch(e => {
console.error("Error during screenshare picker", e);
return null;
});
2023-06-22 03:52:56 +09:00
if (!choice) return callback({});
const source = sources.find(s => s.id === choice.id);
if (!source) return callback({});
const streams: Streams = {
video: source
};
if (choice.audio && process.platform === "win32") streams.audio = "loopback";
callback(streams);
});
}