-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Colin Troisemaine
authored and
Colin Troisemaine
committed
Oct 21, 2024
1 parent
aa62046
commit e622583
Showing
10 changed files
with
164 additions
and
107 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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);}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}); |