В настоящее время я пишу программу, которая использует смесь Electron и React-Redux для создания окна наложения поверх экранов/приложений. Мне удалось успешно создать прозрачное окно наложения и перечислить все допустимые медиапотоки. Но я не могу понять, как я могу заставить это новое окно наложения соответствовать размеру / местоположению выбранного потока и динамически изменять размер. Кроме того, я хотел бы, чтобы оверлей был только поверх выбранного потока.
Любые советы приветствуются :)
// In MainProcess
ipcMain.on(ELECTRON_CREATE_OVERLAY_WINDOW, (event, windowSettings) => {
if (overlayWindow !== null) {
console.error('Trying to create an Overlay window when there is already one!')
return
}
console.info('Creating the Overlay window')
overlayWindow = new BrowserWindow({
width: windowSettings.width,
height: windowSettings.height,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
},
transparent: true,
frame: false,
alwaysOnTop: true,
});
overlayWindow.setIgnoreMouseEvents(true);
overlayWindow.loadURL("http://localhost:3000/overlay");
overlayWindow.on('closed', () => {
console.info('Overlay window closed')
overlayWindow = null
})
});
// In React page / RendererProcess
React.useEffect(async () => {
desktopCapturer
.getSources({
types: ["window", "screen"],
})
.then((inputSources) => {
for (let i = 0; i < inputSources.length; i++) {
let source = inputSources[i];
const constraints = {
audio: false,
video: {
mandatory: {
chromeMediaSource: "desktop",
chromeMediaSourceId: source.id,
},
},
};
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
inputSources[i].stream = stream;
console.info('stream', stream)
// When we got all streams, update the state
if (i == inputSources.length - 1) {
setSources([...inputSources]);
}
});
}
});
}, []);
...
const launchOverlay = (source) => {
const streamSettings = source.stream.getVideoTracks()[0].getSettings();
console.info(source)
console.info(source.stream)
console.info(streamSettings)
createOverlayWindow({ width: streamSettings.width, height: streamSettings.height })
};
Для этого можно использовать пакет electron-overlay-window .
В Readme говорится, что он поддерживает Windows и Linux.
Он отслеживает целевые окна по их заголовку и держит окно вашего приложения прямо над ним. Он также повторно присоединяется, если вы перезапустите целевое приложение/игру. Единственный недостаток - это не очень документировано. Но основная демонстрация проста.
// ...
import { overlayWindow as OW } from 'electron-overlay-window'
// ...
const win = new BrowserWindow({
...OW.WINDOW_OPTS, // pay attention here
width: 800,
height: 600,
resizable: false,
webPreferences: {
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
},
})
// ... when ready
OW.attachTo(window, 'Untitled - Notepad')
// listen for lifecycle events
OW.on('attach', ev => { console.info('WO: attach', ev) })
OW.on('detach', ev => { console.info('WO: detach', ev) })
OW.on('blur', ev => { console.info('WO: blur', ev)})
OW.on('focus', ev => { console.info('WO: focus', ev)})
OW.on('fullscreen', ev => console.info('WO: fullscreen', ev))
OW.on('moveresize', ev => console.info('WO: fullscreen', ev))
Вы можете посмотреть больше примеров здесь: