Created
February 11, 2020 15:44
-
-
Save aberenyi/eb431adc064e6dd1807f51964d5383b6 to your computer and use it in GitHub Desktop.
Stream to a Jitsi room using an RPi and a webcam
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
// Based on https://code.saghul.net/2017/09/streaming-a-webcam-to-a-jitsi-meet-room/ | |
// extended to work on ARM (RPi) | |
const puppeteer = require('puppeteer'); | |
// Streams the first webcam in the system to the specified Jitsi Meet room. Audio is currently | |
// not sent, but it can be easily enabled by disabling the corresponding setting in `meetArgs`. | |
// | |
// TODO | |
// - Detect if we are kicked from the room | |
// - Support authenticated deployments | |
// | |
// NOTE: only tested on GNU/Linux. | |
async function main(room, baseUrl='https://meet.jit.si') | |
{ | |
const chromeArgs = | |
[ | |
// Disable sandboxing, gives an error on Linux | |
'--no-sandbox', | |
'--disable-setuid-sandbox', | |
// Automatically give permission to use media devices | |
'--use-fake-ui-for-media-stream', | |
// Silence all output, just in case | |
'--alsa-output-device=plug:null', | |
// additional args from https://github.com/puppeteer/puppeteer/issues/550 | |
'--display=:1', | |
'--disable-extensions' | |
]; | |
const meetArgs = | |
[ | |
// Disable receiving of video | |
'config.channelLastN=0', | |
// Mute our audio | |
'config.startWithAudioMuted=true', | |
// Don't use simulcast to save resources on the sender (our) side | |
'config.disableSimulcast=true', | |
// No need to process audio levels | |
'config.disableAudioLevels=true', | |
// Disable P2P mode due to a bug in Jitsi Meet | |
'config.p2p.enabled=false' | |
]; | |
const url = `${baseUrl}/${room}#${meetArgs.join('&')}`; | |
console.log(`Loading ${url}`); | |
const browser = await puppeteer.launch | |
({ | |
args: chromeArgs, | |
handleSIGINT: false, | |
defaultViewport: {width: 1920, height: 1080}, | |
headless: false, | |
// make sure it's there | |
executablePath: '/usr/bin/chromium-browser' | |
}); | |
const page = await browser.newPage(); | |
// Manual handling on SIGINT to gracefully hangup and exit | |
process.on('SIGINT', async () => | |
{ | |
console.log('Exiting...'); | |
await page.evaluate('APP.conference.hangup();'); | |
await page.close(); | |
browser.close(); | |
console.log('Done!'); | |
process.exit(); | |
}); | |
await page.goto(url); | |
try | |
{ | |
const watchDog = page.waitForFunction('window.APP.conference._room !== undefined'); | |
await watchDog | |
await page.evaluate('APP.conference._room.setDisplayName("Streamer");'); | |
} | |
catch(e) { console.error(e) } | |
console.log('Running...'); | |
} | |
main(process.argv[2] || 'test123'); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment