Created
August 30, 2021 01:24
-
-
Save dzeitman/7858e96222195d9cf3facd5985f2d75c to your computer and use it in GitHub Desktop.
Dolby.io Getting Started with Electron
This file contains hidden or 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
| const avengersNames = ['Thor', 'Cap', 'Tony Stark', 'Black Panther', 'Black Widow', 'Hulk', 'Spider-Man']; | |
| let randomName = avengersNames[Math.floor(Math.random() * avengersNames.length)] | |
| var config = function (){ | |
| return JSON.parse(decodeURIComponent(document.location.search.split('=')[1])) | |
| }() | |
| console.log(config) | |
| const customerKey = config.customerKey | |
| const customerSecret = config.customerSecret | |
| console.log(window.document) | |
| const main = async () => { | |
| /* Event handlers */ | |
| // When a stream is added to the conference | |
| VoxeetSDK.conference.on('streamAdded', (participant, stream) => { | |
| if (stream.type === 'ScreenShare') { | |
| return addScreenShareNode(stream); | |
| } | |
| if (stream.getVideoTracks().length) { | |
| // Only add the video node if there is a video track | |
| addVideoNode(participant, stream); | |
| } | |
| addParticipantNode(participant); | |
| }); | |
| // When a stream is updated | |
| VoxeetSDK.conference.on('streamUpdated', (participant, stream) => { | |
| if (stream.type === 'ScreenShare') return; | |
| if (stream.getVideoTracks().length) { | |
| // Only add the video node if there is a video track | |
| addVideoNode(participant, stream); | |
| } else { | |
| removeVideoNode(participant); | |
| } | |
| }); | |
| // When a stream is removed from the conference | |
| VoxeetSDK.conference.on('streamRemoved', (participant, stream) => { | |
| if (stream.type === 'ScreenShare') { | |
| return removeScreenShareNode(); | |
| } | |
| removeVideoNode(participant); | |
| removeParticipantNode(participant); | |
| }); | |
| try { | |
| // Initialize the Voxeet SDK | |
| // WARNING: It is best practice to use the VoxeetSDK.initializeToken function to initialize the SDK. | |
| // Please read the documentation at: | |
| // https://docs.dolby.io/interactivity/docs/initializing | |
| // VoxeetSDK.initialize('customerKey', 'customerSecret'); | |
| VoxeetSDK.initialize(customerKey, customerSecret); | |
| // Open a session for the user | |
| await VoxeetSDK.session.open({ name: randomName }); | |
| // Initialize the UI | |
| initUI(); | |
| } catch (e) { | |
| alert('Something went wrong : ' + e); | |
| } | |
| } | |
| main(); |
This file contains hidden or 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
| DOLBYAPIKEY=<customerKey> | |
| DOLBYAPISECRET=<customerSecret> |
This file contains hidden or 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
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>Basic Web Video Conference Application</title> | |
| <script type="text/javascript" src="https://unpkg.com/@voxeet/voxeet-web-sdk@3.3.0-beta.2/dist/voxeet-sdk.js"> | |
| </script> | |
| <script type="text/javascript" src="ui.js"></script> | |
| <meta http-equiv="Content-Security-Policy" | |
| content="default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;"> | |
| <!-- CSS only --> | |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" | |
| integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous"> | |
| <!-- JavaScript Bundle with Popper --> | |
| <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" | |
| integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"> | |
| </script> | |
| <script src="https://kit.fontawesome.com/d8d772b4af.js" crossorigin="anonymous"></script> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.5.0/font/bootstrap-icons.min.css" | |
| rel="stylesheet" crossorigin="anonymous"> | |
| </head> | |
| <body style="background-color: white;"> | |
| <div id="app"> | |
| <div class="container"> | |
| <h1 id="name-message" class="form-text">You are logged out.</h1> | |
| <!-- Join or Leave a Conference --> | |
| <div id="form"> | |
| <div class="mb-3"> | |
| <i class="fas fa-handshake"></i> | |
| <label for="alias-input" class="form-label" >Conference alias :</label> | |
| <input id="alias-input" value="dev-portal" class="form-control" aria-describedby="aliasHelp"/> | |
| <div id="aliasHelp" class="form-text">Enter a unique conference name</div> | |
| </div> | |
| <div class="mb-3"> | |
| <button id="join-btn" class="btn btn-primary" disabled>Join</button> | |
| <button id="leave-btn" class="btn btn-info" disabled>Leave</button> | |
| </div> | |
| <div class="mb-3"> | |
| <label class="form-text" id="label-dolby-voice"></label> | |
| </div> | |
| <div id="actions"></div> | |
| <div class="mb-3"> | |
| <!-- Actions on Video and Screen Share --> | |
| <button id="start-video-btn" disabled><i class="bi bi-play-btn-fill"></i> Start Video</button> | |
| <button id="stop-video-btn" disabled><i class="bi bi-stop-btn-fill"></i> Stop Video</button> | |
| </div> | |
| <div class="mb-3"> | |
| <button id="start-audio-btn" disabled><i class="bi bi-speaker"></i> Start audio</button> | |
| <button id="stop-audio-btn" disabled> <i class="bi bi-speaker-fill"></i> Stop audio</button> | |
| </div> | |
| <div class="mb-3"> | |
| <button id="start-screenshare-btn" disabled><i class="bi bi-pip"></i> Start screen share</button> | |
| <button id="stop-screenshare-btn" disabled><i class="bi bi-pip-fill"></i> Stop screen share</button> | |
| </div> | |
| <div class="mb-3"> | |
| <!-- Recording Actions and Status --> | |
| <div id="recording"> | |
| <button id="start-recording-btn" disabled><i class="bi bi-record-circle"></i> Start recording</button> | |
| <button id="stop-recording-btn" disabled><i class="bi bi-record-circle-fill"></i> Stop recording</button> | |
| <p id="record-status" style="color: red;"></p> | |
| </div> | |
| </div> | |
| <div class="mb-3"> | |
| <!-- Display the list of participants --> | |
| <div id="participants"> | |
| <h3 class="form-text">Participants</h3> | |
| <ul id="participants-list"></ul> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Container for the video streams --> | |
| <div id="video-container"></div> | |
| <!-- Container for the Screen Share --> | |
| <div id="screenshare-container"></div> | |
| </div> | |
| </div> | |
| <script type="text/javascript" src="client.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or 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
| // Modules to control application life and create native browser window | |
| require('dotenv').config({ path: './env.js' }); | |
| const { app, BrowserWindow } = require('electron') | |
| const data = { | |
| "customerKey": `${process.env.DOLBYAPIKEY}`, | |
| "customerSecret": `${process.env.DOLBYAPISECRET}` | |
| } | |
| const path = require('path') | |
| function createWindow() { | |
| // Create the browser window. | |
| const mainWindow = new BrowserWindow({ | |
| width: 800, | |
| height: 600, | |
| webPreferences: { | |
| nodeIntegration: true, | |
| preload: path.join(__dirname, 'preload.js'), | |
| }, | |
| }) | |
| // and load the index.html of the app. | |
| mainWindow.loadFile('index.html', { query: { "data": JSON.stringify(data) } }) | |
| // Open the DevTools. | |
| // mainWindow.webContents.openDevTools() | |
| } | |
| // This method will be called when Electron has finished | |
| // initialization and is ready to create browser windows. | |
| // Some APIs can only be used after this event occurs. | |
| app.whenReady().then(() => { | |
| createWindow() | |
| app.on('activate', function () { | |
| // On macOS it's common to re-create a window in the app when the | |
| // dock icon is clicked and there are no other windows open. | |
| if (BrowserWindow.getAllWindows().length === 0) createWindow() | |
| }) | |
| }) | |
| // Quit when all windows are closed, except on macOS. There, it's common | |
| // for applications and their menu bar to stay active until the user quits | |
| // explicitly with Cmd + Q. | |
| app.on('window-all-closed', function () { | |
| if (process.platform !== 'darwin') app.quit() | |
| }) | |
| // In this file you can include the rest of your app's specific main process | |
| // code. You can also put them in separate files and require them here. |
This file contains hidden or 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
| { | |
| "name": "Dolby-io-getting-started-with-electron", | |
| "productName": "Dolby-io-getting-started-with-electron", | |
| "description": "My Electron application description", | |
| "keywords": [], | |
| "main": "./main.js", | |
| "version": "1.0.0", | |
| "author": "danzeitman", | |
| "scripts": { | |
| "start": "electron ." | |
| }, | |
| "dependencies": { | |
| "dotenv": "*" | |
| }, | |
| "devDependencies": { | |
| "electron": "13.1.7" | |
| } | |
| } |
This file contains hidden or 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
| // All of the Node.js APIs are available in the preload process. | |
| // It has the same sandbox as a Chrome extension. | |
| window.addEventListener('DOMContentLoaded', () => { | |
| const replaceText = (selector, text) => { | |
| const element = document.getElementById(selector) | |
| if (element) element.innerText = text | |
| } | |
| for (const type of ['chrome', 'node', 'electron']) { | |
| replaceText(`${type}-version`, process.versions[type]) | |
| } | |
| // document.createAttribute("customerKey", `${process.env.DOLBYAPIKEY}`) | |
| // document.createAttribute("customerSecret", `${process.env.DOLBYAPISECRET}`) | |
| // var myData = { | |
| // "customerKey": `${process.env.DOLBYAPIKEY}`, | |
| // "customerSecret": `${process.env.DOLBYAPISECRET}` | |
| // } | |
| }) |
This file contains hidden or 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
| // This file is required by the index.html file and will | |
| // be executed in the renderer process for that window. | |
| // No Node.js APIs are available in this process because | |
| // `nodeIntegration` is turned off. Use `preload.js` to | |
| // selectively enable features needed in the rendering | |
| // process. | |
This file contains hidden or 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
| /* Empty */ | |
This file contains hidden or 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
| const initUI = () => { | |
| const nameMessage = document.getElementById('name-message'); | |
| const joinButton = document.getElementById('join-btn'); | |
| const conferenceAliasInput = document.getElementById('alias-input'); | |
| const nameInput = document.getElementById('name-input'); | |
| const leaveButton = document.getElementById('leave-btn'); | |
| const lblDolbyVoice = document.getElementById('label-dolby-voice'); | |
| const startVideoBtn = document.getElementById('start-video-btn'); | |
| const stopVideoBtn = document.getElementById('stop-video-btn'); | |
| const startAudioBtn = document.getElementById('start-audio-btn'); | |
| const stopAudioBtn = document.getElementById('stop-audio-btn'); | |
| const startScreenShareBtn = document.getElementById('start-screenshare-btn'); | |
| const stopScreenShareBtn = document.getElementById('stop-screenshare-btn'); | |
| const startRecordingBtn = document.getElementById('start-recording-btn'); | |
| const stopRecordingBtn = document.getElementById('stop-recording-btn'); | |
| // Update the login message with the name of the user | |
| nameMessage.innerHTML = `You are logged in as ${randomName}`; | |
| joinButton.disabled = false; | |
| joinButton.onclick = () => { | |
| // Default conference parameters | |
| // See: https://docs.dolby.io/interactivity/docs/js-client-sdk-model-conferenceparameters | |
| let conferenceParams = { | |
| liveRecording: false, | |
| rtcpMode: "average", // worst, average, max | |
| ttl: 0, | |
| videoCodec: "H264", // H264, VP8 | |
| dolbyVoice: true | |
| }; | |
| // See: https://docs.dolby.io/interactivity/docs/js-client-sdk-model-conferenceoptions | |
| let conferenceOptions = { | |
| alias: conferenceAliasInput.value, | |
| params: conferenceParams | |
| }; | |
| // 1. Create a conference room with an alias | |
| VoxeetSDK.conference.create(conferenceOptions) | |
| .then((conference) => { | |
| // See: https://docs.dolby.io/interactivity/docs/js-client-sdk-model-joinoptions | |
| const joinOptions = { | |
| constraints: { | |
| audio: true, | |
| video: false | |
| }, | |
| simulcast: false | |
| }; | |
| // 2. Join the conference | |
| VoxeetSDK.conference.join(conference, joinOptions) | |
| .then((conf) => { | |
| lblDolbyVoice.innerHTML = `Dolby Voice is ${conf.params.dolbyVoice ? 'On' : 'Off'}.`; | |
| conferenceAliasInput.disabled = true; | |
| joinButton.disabled = true; | |
| leaveButton.disabled = false; | |
| startVideoBtn.disabled = false; | |
| startAudioBtn.disabled = true; | |
| stopAudioBtn.disabled = false; | |
| startScreenShareBtn.disabled = false; | |
| startRecordingBtn.disabled = false; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| leaveButton.onclick = () => { | |
| // Leave the conference | |
| VoxeetSDK.conference.leave() | |
| .then(() => { | |
| lblDolbyVoice.innerHTML = ''; | |
| conferenceAliasInput.disabled = false; | |
| joinButton.disabled = false; | |
| leaveButton.disabled = true; | |
| startVideoBtn.disabled = true; | |
| stopVideoBtn.disabled = true; | |
| startAudioBtn.disabled = true; | |
| stopAudioBtn.disabled = true; | |
| startScreenShareBtn.disabled = true; | |
| stopScreenShareBtn.disabled = true; | |
| startRecordingBtn.disabled = true; | |
| stopRecordingBtn.disabled = true; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| startVideoBtn.onclick = () => { | |
| // Start sharing the video with the other participants | |
| VoxeetSDK.conference.startVideo(VoxeetSDK.session.participant) | |
| .then(() => { | |
| startVideoBtn.disabled = true; | |
| stopVideoBtn.disabled = false; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| stopVideoBtn.onclick = () => { | |
| // Stop sharing the video with the other participants | |
| VoxeetSDK.conference.stopVideo(VoxeetSDK.session.participant) | |
| .then(() => { | |
| stopVideoBtn.disabled = true; | |
| startVideoBtn.disabled = false; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| startAudioBtn.onclick = () => { | |
| // Start sharing the Audio with the other participants | |
| VoxeetSDK.conference.startAudio(VoxeetSDK.session.participant) | |
| .then(() => { | |
| startAudioBtn.disabled = true; | |
| stopAudioBtn.disabled = false; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| stopAudioBtn.onclick = () => { | |
| // Stop sharing the Audio with the other participants | |
| VoxeetSDK.conference.stopAudio(VoxeetSDK.session.participant) | |
| .then(() => { | |
| stopAudioBtn.disabled = true; | |
| startAudioBtn.disabled = false; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| startScreenShareBtn.onclick = () => { | |
| // Start the Screen Sharing with the other participants | |
| VoxeetSDK.conference.startScreenShare() | |
| .then(() => { | |
| startScreenShareBtn.disabled = true; | |
| stopScreenShareBtn.disabled = false; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| stopScreenShareBtn.onclick = () => { | |
| // Stop the Screen Sharing | |
| VoxeetSDK.conference.stopScreenShare() | |
| .catch((e) => console.log(e)); | |
| }; | |
| startRecordingBtn.onclick = () => { | |
| let recordStatus = document.getElementById('record-status'); | |
| // Start recording the conference | |
| VoxeetSDK.recording.start() | |
| .then(() => { | |
| recordStatus.innerText = 'Recording...'; | |
| startRecordingBtn.disabled = true; | |
| stopRecordingBtn.disabled = false; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| stopRecordingBtn.onclick = () => { | |
| let recordStatus = document.getElementById('record-status'); | |
| // Stop recording the conference | |
| VoxeetSDK.recording.stop() | |
| .then(() => { | |
| recordStatus.innerText = ''; | |
| startRecordingBtn.disabled = false; | |
| stopRecordingBtn.disabled = true; | |
| }) | |
| .catch((e) => console.log(e)); | |
| }; | |
| }; | |
| // Add a video stream to the web page | |
| const addVideoNode = (participant, stream) => { | |
| let videoNode = document.getElementById('video-' + participant.id); | |
| if (!videoNode) { | |
| videoNode = document.createElement('video'); | |
| videoNode.setAttribute('id', 'video-' + participant.id); | |
| videoNode.setAttribute('height', 240); | |
| videoNode.setAttribute('width', 320); | |
| videoNode.setAttribute("playsinline", true); | |
| videoNode.muted = true; | |
| videoNode.setAttribute("autoplay", 'autoplay'); | |
| videoNode.style = 'background: gray;'; | |
| const videoContainer = document.getElementById('video-container'); | |
| videoContainer.appendChild(videoNode); | |
| } | |
| navigator.attachMediaStream(videoNode, stream); | |
| }; | |
| // Remove the video streem from the web page | |
| const removeVideoNode = (participant) => { | |
| let videoNode = document.getElementById('video-' + participant.id); | |
| if (videoNode) { | |
| videoNode.parentNode.removeChild(videoNode); | |
| } | |
| }; | |
| // Add a new participant to the list | |
| const addParticipantNode = (participant) => { | |
| // If the participant is the current session user, don't add himself to the list | |
| if (participant.id === VoxeetSDK.session.participant.id) return; | |
| let participantNode = document.createElement('li'); | |
| participantNode.setAttribute('id', 'participant-' + participant.id); | |
| participantNode.innerText = `${participant.info.name}`; | |
| const participantsList = document.getElementById('participants-list'); | |
| participantsList.appendChild(participantNode); | |
| }; | |
| // Remove a participant from the list | |
| const removeParticipantNode = (participant) => { | |
| let participantNode = document.getElementById('participant-' + participant.id); | |
| if (participantNode) { | |
| participantNode.parentNode.removeChild(participantNode); | |
| } | |
| }; | |
| // Add a screen share stream to the web page | |
| const addScreenShareNode = (stream) => { | |
| let screenShareNode = document.getElementById('screenshare'); | |
| if (screenShareNode) { | |
| return alert('There is already a participant sharing a screen!'); | |
| } | |
| screenShareNode = document.createElement('video'); | |
| screenShareNode.setAttribute('id', 'screenshare'); | |
| screenShareNode.autoplay = 'autoplay'; | |
| navigator.attachMediaStream(screenShareNode, stream); | |
| const screenShareContainer = document.getElementById('screenshare-container'); | |
| screenShareContainer.appendChild(screenShareNode); | |
| } | |
| // Remove the screen share stream from the web page | |
| const removeScreenShareNode = () => { | |
| let screenShareNode = document.getElementById('screenshare'); | |
| if (screenShareNode) { | |
| screenShareNode.parentNode.removeChild(screenShareNode); | |
| } | |
| const startScreenShareBtn = document.getElementById('start-screenshare-btn'); | |
| startScreenShareBtn.disabled = false; | |
| const stopScreenShareBtn = document.getElementById('stop-screenshare-btn'); | |
| stopScreenShareBtn.disabled = true; | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dolby.io Getting Started with Electron