Skip to content

Commit

Permalink
Working video source selection
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin Troisemaine authored and Colin Troisemaine committed Oct 21, 2024
1 parent aa62046 commit e622583
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 107 deletions.
28 changes: 0 additions & 28 deletions electron_app/control_menu.html

This file was deleted.

40 changes: 0 additions & 40 deletions electron_app/main.js

This file was deleted.

38 changes: 0 additions & 38 deletions electron_app/renderer.js

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "live_desktop_translator",
"version": "0.0.1",
"main": "electron_app/main.js",
"main": "src/main.js",
"scripts": {
"start": "electron-forge start",
"test": "echo \"Error: no test specified\" && exit 1",
Expand Down
3 changes: 3 additions & 0 deletions src/bulma.min.css

Large diffs are not rendered by default.

File renamed without changes.
31 changes: 31 additions & 0 deletions src/control_menu.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy"
content="img-src 'self' data: filesystem:; default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; script-src-elem 'self' 'unsafe-eval' https://unpkg.com">

<title>Live Desktop Translator</title>
<link rel="stylesheet" href="bulma.min.css">
<link rel="stylesheet" href="control_menu.html">
<script defer src="renderer.js"></script>
</head>

<body>
<section class="section">
<div class="container" style="text-align: center;">
<button id="startButton" class="button">Start</button>
<button id="stopButton" class="button">Stop</button>

<hr/>

<video width="800" height="450" autoplay></video>

<hr/>

<button id="videoSelectButton" class="button">Choose a Video Source</button>
</div>
</section>
</body>
</html>
73 changes: 73 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const { app, BrowserWindow, ipcMain, desktopCapturer, session, Menu } = require('electron')
const path = require('node:path')

let selectedSourceId = null; // Store the selected source ID

app.whenReady().then(() => {
const win = new BrowserWindow({
width: 1000,
height: 700,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
enableRemoteModule: false,
nodeIntegration: false,
}
});

win.loadFile(path.join(__dirname, 'control_menu.html'));

session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
if (selectedSourceId) {
desktopCapturer.getSources({ types: ['screen', 'window'] }).then((sources) => {
const selectedSource = sources.find(source => source.id === selectedSourceId);
if (selectedSource) {
// Grant access to the selected screen or window
callback({ video: selectedSource });
} else {
console.log("Selected source not found!");
}
}).catch(err => console.error("Error getting sources: ", err));
} else {
console.log("No source selected.");
}
}, { useSystemPicker: true });

// Save the selected source ID when it's chosen from the menu
ipcMain.on('select-source', (event, sourceId) => {
selectedSourceId = sourceId; // Update the selected source ID
console.log(`Source selected: ${sourceId}`);
});

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

ipcMain.handle('DESKTOP_CAPTURER_GET_SOURCES', async (event, opts) => {
return await desktopCapturer.getSources(opts);
});

// Handle showing the popup menu
ipcMain.on('show-popup-menu', (event, menuTemplate) => {
const menu = Menu.buildFromTemplate(menuTemplate.map(item => ({
label: item.label,
click: () => {
// console.log("Selected source with ID: " + item.id + " and name: " + item.label);
win.webContents.send('source-selected', item.id)
selectedSourceId = item.id;
}
})));

// Show the popup menu in the appropriate window
menu.popup(BrowserWindow.fromWebContents(event.sender));
});

win.removeMenu()
win.webContents.openDevTools()
});

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
7 changes: 7 additions & 0 deletions src/preload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electron', {
getSources: (opts) => ipcRenderer.invoke('DESKTOP_CAPTURER_GET_SOURCES', opts),
showPopupMenu: (menuTemplate) => ipcRenderer.send('show-popup-menu', menuTemplate),
onSourceSelected: (callback) => ipcRenderer.on('source-selected', (event, sourceId) => {callback(sourceId);})
});
49 changes: 49 additions & 0 deletions src/renderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const video = document.querySelector('video')
const startButton = document.getElementById('startButton')
const stopButton = document.getElementById('stopButton')
const videoSelectButton = document.getElementById('videoSelectButton')

let selectedSourceId = null; // Track the selected source ID

startButton.addEventListener('click', () => {
// Prevent starting if no source is selected
if (!selectedSourceId) {
console.log("No source selected!");
alert("Please select a source first!");
return;
}

navigator.mediaDevices.getDisplayMedia({
audio: false,
video: {
width: 800,
height: 450,
frameRate: 30
}
}).then(stream => {
video.srcObject = stream
video.onloadedmetadata = (e) => video.play()
}).catch(e => console.log(e))
})

stopButton.addEventListener('click', () => {
video.pause()
})

videoSelectButton.addEventListener('click', async () => {
// Use the exposed API from preload.js to get the sources from the main process
const inputSources = await window.electron.getSources({ types: ['window', 'screen'] });

// Create a menu with only serializable properties: source `name` and `id`
const menuTemplate = inputSources.map(source => ({
label: source.name,
id: source.id
}));

// Show the popup menu
window.electron.showPopupMenu(menuTemplate);
});

window.electron.onSourceSelected((sourceId) => {
selectedSourceId = sourceId;
});

0 comments on commit e622583

Please sign in to comment.