mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-05 23:42:58 +02:00
fixed the ordering of selects
This commit is contained in:
parent
c6c9059a29
commit
9ebe7067c5
5 changed files with 321 additions and 251 deletions
|
@ -2,7 +2,7 @@
|
|||
"name": "highfidelity_screenshare",
|
||||
"version": "1.0.0",
|
||||
"description": "High Fidelity Screenshare",
|
||||
"main": "src/main.js",
|
||||
"main": "src/screenshareMainProcess.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"packager": "node packager.js"
|
||||
|
|
|
@ -1,247 +0,0 @@
|
|||
// Helpers
|
||||
function handleError(error) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
/* SOURCE EXAMPLE
|
||||
[23584:1028/110448.237:INFO:CONSOLE(67)] "{
|
||||
"id": "screen:0:0",
|
||||
"name": "Screen 1",
|
||||
"thumbnail": {},
|
||||
"display_id": "2528732444",
|
||||
"appIcon": null
|
||||
}"
|
||||
*/
|
||||
|
||||
const imageWidth = 265;
|
||||
const imageHeight = 165;
|
||||
|
||||
var images = 10;
|
||||
var testImage = "resources/test.jpg";
|
||||
function MakeSource(name, thumbnail, id, newWidth, newHeight){
|
||||
this.name = name;
|
||||
this.thumbnail = thumbnail;
|
||||
this.id = id;
|
||||
this.width = newWidth;
|
||||
this.height = newHeight;
|
||||
}
|
||||
|
||||
let testSources = [];
|
||||
|
||||
for (let index = 0; index < images; index++) {
|
||||
let test = new MakeSource("REALLY LONG LONG title" + index, testImage, index, imageWidth, imageHeight);
|
||||
testSources.push(test);
|
||||
}
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
let currentScreensharePickID = "";
|
||||
function screensharePicked(id){
|
||||
currentScreensharePickID = id;
|
||||
document.getElementById("share_pick").innerHTML = "";
|
||||
addSource(sourceMap[id], "share_pick");
|
||||
togglePage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function screenConfirmed(isConfirmed){
|
||||
if (isConfirmed === true){
|
||||
onAccessApproved(currentScreensharePickID);
|
||||
}
|
||||
togglePage();
|
||||
}
|
||||
|
||||
|
||||
let currentPage = "mainPage";
|
||||
function togglePage(){
|
||||
if (currentPage === "mainPage") {
|
||||
currentPage = "confirmationPage";
|
||||
document.getElementById("select_screen").style.display = "none";
|
||||
document.getElementById("subtitle").innerHTML = "Confirm that you'd like to share this content.";
|
||||
document.getElementById("confirmation_screen").style.display = "block";
|
||||
} else {
|
||||
currentPage = "mainPage";
|
||||
document.getElementById("select_screen").style.display = "block";
|
||||
document.getElementById("subtitle").innerHTML = "Please select the content you'd like to share.";
|
||||
document.getElementById("confirmation_screen").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
// UI
|
||||
function addSource(source, type) {
|
||||
let sourceBody = document.createElement('div')
|
||||
let thumbnail = source.thumbnail.toDataURL();
|
||||
sourceBody.classList.add("box")
|
||||
if (type === "share_pick") {
|
||||
sourceBody.style.marginLeft = "0px";
|
||||
}
|
||||
|
||||
let image = "";
|
||||
if (source.appIcon) {
|
||||
image = `<img class="icon" src="${source.appIcon.toDataURL()}" />`;
|
||||
}
|
||||
sourceBody.innerHTML = `
|
||||
<div class="heading">
|
||||
${image}
|
||||
<span class="screen_label">${source.name}</span>
|
||||
</div>
|
||||
<div class="${type === "share_pick" ? "image_no_hover" : "image"}" onclick="screensharePicked('${source.id}')">
|
||||
<img src="${thumbnail}" />
|
||||
</div>
|
||||
`
|
||||
if (type === "selects") {
|
||||
document.getElementById("selects").appendChild(sourceBody);
|
||||
} else {
|
||||
document.getElementById("share_pick").appendChild(sourceBody);
|
||||
document.getElementById("content_name").innerHTML = source.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let sourceMap = {};
|
||||
function showSources() {
|
||||
document.getElementById("selects").innerHTML="";
|
||||
electron.desktopCapturer.getSources({
|
||||
types:['window', 'screen'],
|
||||
thumbnailSize: {
|
||||
width: imageWidth,
|
||||
height: imageHeight
|
||||
},
|
||||
fetchWindowIcons: true
|
||||
}, (error, sources) => {
|
||||
if (error) {
|
||||
console.log("Error getting sources", error);
|
||||
}
|
||||
|
||||
// MN TODO:
|
||||
// Add all sources to array, sort array by type, then call `addSource()`
|
||||
// for all of those sources.
|
||||
|
||||
for (let source of sources) {
|
||||
sourceMap[source.id] = source;
|
||||
addSource(source, "selects");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
let localStream;
|
||||
function stopSharing(){
|
||||
desktopSharing = false;
|
||||
|
||||
if (localStream) {
|
||||
localStream.getTracks()[0].stop();
|
||||
localStream = null;
|
||||
}
|
||||
|
||||
document.getElementById('screenshare').style.display = "none";
|
||||
stopTokBoxPublisher();
|
||||
}
|
||||
|
||||
function gotStream(stream) {
|
||||
localStream = stream;
|
||||
startTokboxPublisher(localStream);
|
||||
|
||||
stream.onended = () => {
|
||||
if (desktopSharing) {
|
||||
toggle();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function onAccessApproved(desktop_id) {
|
||||
if (!desktop_id) {
|
||||
console.log('Desktop Capture access rejected.');
|
||||
return;
|
||||
}
|
||||
showSources();
|
||||
document.getElementById('screenshare').style.visibility = "block";
|
||||
desktopSharing = true;
|
||||
navigator.webkitGetUserMedia({
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: desktop_id,
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
}
|
||||
}
|
||||
}, gotStream, handleError);
|
||||
}
|
||||
|
||||
// Tokbox
|
||||
|
||||
function initializeTokboxSession() {
|
||||
session = OT.initSession(projectAPIKey, sessionID);
|
||||
session.on('sessionDisconnected', (event) => {
|
||||
console.log('You were disconnected from the session.', event.reason);
|
||||
});
|
||||
|
||||
// Connect to the session
|
||||
session.connect(token, (error) => {
|
||||
if (error) {
|
||||
handleError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var publisher;
|
||||
function startTokboxPublisher(stream){
|
||||
publisher = document.createElement("div");
|
||||
var publisherOptions = {
|
||||
videoSource: stream.getVideoTracks()[0],
|
||||
audioSource: null,
|
||||
insertMode: 'append',
|
||||
width: 1280,
|
||||
height: 720
|
||||
};
|
||||
|
||||
publisher = OT.initPublisher(publisher, publisherOptions, function(error){
|
||||
if (error) {
|
||||
console.log("ERROR: " + error);
|
||||
} else {
|
||||
session.publish(publisher, function(error) {
|
||||
if (error) {
|
||||
console.log("ERROR FROM Session.publish: " + error);
|
||||
return;
|
||||
}
|
||||
console.log("MADE IT TO PUBLISH")
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function stopTokBoxPublisher(){
|
||||
publisher.destroy();
|
||||
}
|
||||
|
||||
|
||||
// main TODO:
|
||||
const ipcRenderer = electron.ipcRenderer;
|
||||
let projectAPIKey;
|
||||
let sessionID;
|
||||
let token;
|
||||
let session;
|
||||
|
||||
ipcRenderer.on('connectionInfo', function(event, message){
|
||||
const connectionInfo = JSON.parse(message);
|
||||
projectAPIKey = connectionInfo.projectAPIKey;
|
||||
sessionID = connectionInfo.sessionID;
|
||||
token = connectionInfo.token;
|
||||
|
||||
initializeTokboxSession();
|
||||
})
|
||||
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
showSources();
|
||||
})
|
|
@ -1,3 +1,15 @@
|
|||
<!--
|
||||
|
||||
screenshareApp.html
|
||||
|
||||
Created by Milad Nazeri, Rebecca Stankus, and Zach Fox 2019/11/13
|
||||
Copyright 2019 High Fidelity, Inc.
|
||||
|
||||
Distributed under the Apache License, Version 2.0.
|
||||
See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<link href="styles.css" rel="stylesheet">
|
||||
|
@ -49,7 +61,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div> <!-- confirmation screen -->
|
||||
<script src="app.js"></script>
|
||||
<script src="screenshareApp.js"></script>
|
||||
<script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
|
||||
</body>
|
||||
</html>
|
297
screenshare/src/screenshareApp.js
Normal file
297
screenshare/src/screenshareApp.js
Normal file
|
@ -0,0 +1,297 @@
|
|||
//
|
||||
// screenshareApp.js
|
||||
//
|
||||
// Created by Milad Nazeri, Rebecca Stankus, and Zach Fox 2019/11/13
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
// Helpers
|
||||
function handleError(error) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// When an application is picked, make sure we clear out the previous pick, toggle the page,
|
||||
// and add the correct source
|
||||
let currentScreensharePickID = "";
|
||||
function screensharePicked(id){
|
||||
currentScreensharePickID = id;
|
||||
document.getElementById("share_pick").innerHTML = "";
|
||||
togglePage();
|
||||
addSource(sourceMap[id], "share_pick");
|
||||
}
|
||||
|
||||
|
||||
// Once we have confirmed that we want to share, prepare the tokbox publishing initiating
|
||||
// and toggle back to the selects page
|
||||
function screenConfirmed(isConfirmed){
|
||||
document.getElementById("selects").innerHTML="";
|
||||
if (isConfirmed === true){
|
||||
onAccessApproved(currentScreensharePickID);
|
||||
}
|
||||
togglePage();
|
||||
}
|
||||
|
||||
|
||||
// Hide/show the select page or the confirmation page
|
||||
let currentPage = "mainPage";
|
||||
function togglePage(){
|
||||
if (currentPage === "mainPage") {
|
||||
currentPage = "confirmationPage";
|
||||
document.getElementById("select_screen").style.display = "none";
|
||||
document.getElementById("subtitle").innerHTML = "Confirm that you'd like to share this content.";
|
||||
document.getElementById("confirmation_screen").style.display = "block";
|
||||
} else {
|
||||
showSources();
|
||||
currentPage = "mainPage";
|
||||
document.getElementById("select_screen").style.display = "block";
|
||||
document.getElementById("subtitle").innerHTML = "Please select the content you'd like to share.";
|
||||
document.getElementById("confirmation_screen").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// UI
|
||||
|
||||
// Render the html properly and append that to the correct parent
|
||||
function addSource(source, type) {
|
||||
let renderedHTML = renderSourceHTML(source);
|
||||
if (type === "selects") {
|
||||
document.getElementById("selects").appendChild(renderedHTML);
|
||||
} else {
|
||||
document.getElementById("share_pick").appendChild(renderedHTML);
|
||||
document.getElementById("content_name").innerHTML = source.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the html created from the source. Alter slightly depending on whether this source
|
||||
// is on the selects screen, or the confirmation screen. Mainly removing highlighting.
|
||||
// If there is an app Icon, then add it.
|
||||
function renderSourceHTML(source){
|
||||
let type = currentPage === "confirmationPage" ? "share_pick" : "selects";
|
||||
let sourceBody = document.createElement('div')
|
||||
let thumbnail = source.thumbnail.toDataURL();
|
||||
sourceBody.classList.add("box")
|
||||
if (type === "share_pick") {
|
||||
sourceBody.style.marginLeft = "0px";
|
||||
}
|
||||
|
||||
let image = "";
|
||||
if (source.appIcon) {
|
||||
image = `<img class="icon" src="${source.appIcon.toDataURL()}" />`;
|
||||
}
|
||||
sourceBody.innerHTML = `
|
||||
<div class="heading">
|
||||
${image}
|
||||
<span class="screen_label">${source.name}</span>
|
||||
</div>
|
||||
<div class="${type === "share_pick" ? "image_no_hover" : "image"}" onclick="screensharePicked('${source.id}')">
|
||||
<img src="${thumbnail}" />
|
||||
</div>
|
||||
`
|
||||
return sourceBody;
|
||||
}
|
||||
|
||||
|
||||
// Separate out the screenshares and applications
|
||||
// Make sure the screens are labeled in order
|
||||
// Concact the two arrays back together and return
|
||||
function sortSources(){
|
||||
let screenSources = [];
|
||||
let applicationSources = [];
|
||||
// Difference with Mac selects:
|
||||
// 1 screen = "Enitre Screen", more than one like PC "Screen 1, Screen 2..."
|
||||
screenshareSourceArray.forEach((source) => {
|
||||
if (source.name.match(/(entire )?screen( )?([0-9]?)/i)) {
|
||||
screenSources.push(source);
|
||||
} else {
|
||||
applicationSources.push(source)
|
||||
}
|
||||
})
|
||||
screenSources.sort( (a, b) => {
|
||||
let aNumber = a.name.replace(/[^\d]/, "");
|
||||
let bNumber = b.name.replace(/[^\d]/, "");
|
||||
return aNumber - bNumber;
|
||||
})
|
||||
let finalSources = [...screenSources, ...applicationSources];
|
||||
return finalSources;
|
||||
}
|
||||
|
||||
|
||||
// Setup sorting the selection array, add individual sources, and update the sourceMap
|
||||
function addSources(){
|
||||
screenshareSourceArray = sortSources();
|
||||
for (let i = 0; i < screenshareSourceArray.length; i++) {
|
||||
addSource(screenshareSourceArray[i], "selects");
|
||||
sourceMap[screenshareSourceArray[i].id] = screenshareSourceArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 1. Get the screens and window that are available from electron
|
||||
// 2. Remove the screenshare app itself
|
||||
// 3. Create a source map to help grab the correct source when picked
|
||||
// 4. push all the sources for sorting to the source array
|
||||
// 5. Add thse sources
|
||||
const electron = require('electron');
|
||||
const SCREENSHARE_TITLE = "Screen share";
|
||||
const IMAGE_WIDTH = 265;
|
||||
const IMAGE_HEIGHT = 165;
|
||||
let screenshareSourceArray = [];
|
||||
let sourceMap = {};
|
||||
function showSources() {
|
||||
screenshareSourceArray = [];
|
||||
electron.desktopCapturer.getSources({
|
||||
types:['window', 'screen'],
|
||||
thumbnailSize: {
|
||||
width: IMAGE_WIDTH,
|
||||
height: IMAGE_HEIGHT
|
||||
},
|
||||
fetchWindowIcons: true
|
||||
}, (error, sources) => {
|
||||
if (error) {
|
||||
console.log("Error getting sources", error);
|
||||
}
|
||||
for (let source of sources) {
|
||||
if (source.name.indexOf(SCREENSHARE_TITLE) > -1){
|
||||
continue;
|
||||
}
|
||||
sourceMap[source.id] = source;
|
||||
screenshareSourceArray.push(source);
|
||||
}
|
||||
addSources();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Stop the localstream and end the tokrok publishing
|
||||
let localStream;
|
||||
function stopSharing(){
|
||||
desktopSharing = false;
|
||||
|
||||
if (localStream) {
|
||||
localStream.getTracks()[0].stop();
|
||||
localStream = null;
|
||||
}
|
||||
|
||||
document.getElementById('screenshare').style.display = "none";
|
||||
stopTokBoxPublisher();
|
||||
}
|
||||
|
||||
|
||||
// Callback to start publishing after we have setup the chromium stream
|
||||
function gotStream(stream) {
|
||||
localStream = stream;
|
||||
startTokboxPublisher(localStream);
|
||||
|
||||
stream.onended = () => {
|
||||
if (desktopSharing) {
|
||||
toggle();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// After we grant access to electron, create a stream and using the callback
|
||||
// start the tokbox publisher
|
||||
function onAccessApproved(desktop_id) {
|
||||
if (!desktop_id) {
|
||||
console.log('Desktop Capture access rejected.');
|
||||
return;
|
||||
}
|
||||
document.getElementById('screenshare').style.visibility = "block";
|
||||
desktopSharing = true;
|
||||
navigator.webkitGetUserMedia({
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: desktop_id,
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
}
|
||||
}
|
||||
}, gotStream, handleError);
|
||||
}
|
||||
|
||||
|
||||
// Tokbox
|
||||
|
||||
// Once we have the connection info, this will create the session which will allow
|
||||
// us to publish a stream when we are ready
|
||||
function initializeTokboxSession() {
|
||||
session = OT.initSession(projectAPIKey, sessionID);
|
||||
session.on('sessionDisconnected', (event) => {
|
||||
console.log('You were disconnected from the session.', event.reason);
|
||||
});
|
||||
|
||||
// Connect to the session
|
||||
session.connect(token, (error) => {
|
||||
if (error) {
|
||||
handleError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Init the tokbox publisher with our newly created stream
|
||||
var publisher;
|
||||
function startTokboxPublisher(stream){
|
||||
publisher = document.createElement("div");
|
||||
var publisherOptions = {
|
||||
videoSource: stream.getVideoTracks()[0],
|
||||
audioSource: null,
|
||||
insertMode: 'append',
|
||||
width: 1280,
|
||||
height: 720
|
||||
};
|
||||
|
||||
publisher = OT.initPublisher(publisher, publisherOptions, function(error){
|
||||
if (error) {
|
||||
console.log("ERROR: " + error);
|
||||
} else {
|
||||
session.publish(publisher, function(error) {
|
||||
if (error) {
|
||||
console.log("ERROR FROM Session.publish: " + error);
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Kills the streaming being sent to tokbox
|
||||
function stopTokBoxPublisher(){
|
||||
publisher.destroy();
|
||||
}
|
||||
|
||||
|
||||
// When the app is ready, we get this info from the command line arguments.
|
||||
const ipcRenderer = electron.ipcRenderer;
|
||||
let projectAPIKey;
|
||||
let sessionID;
|
||||
let token;
|
||||
let session;
|
||||
ipcRenderer.on('connectionInfo', function(event, message){
|
||||
const connectionInfo = JSON.parse(message);
|
||||
projectAPIKey = connectionInfo.projectAPIKey;
|
||||
sessionID = connectionInfo.sessionID;
|
||||
token = connectionInfo.token;
|
||||
|
||||
initializeTokboxSession();
|
||||
})
|
||||
|
||||
|
||||
// Show the initial sources after the dom has loaded
|
||||
// Sources come from electron.desktopCapturer
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
showSources();
|
||||
})
|
|
@ -1,4 +1,12 @@
|
|||
'use strict';
|
||||
//
|
||||
// screenshareMainProcess.js
|
||||
//
|
||||
// Created by Milad Nazeri, and Zach Fox 2019/11/13
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
const {app, BrowserWindow, ipcMain} = require('electron');
|
||||
const gotTheLock = app.requestSingleInstanceLock()
|
||||
|
@ -53,15 +61,15 @@ function createWindow(){
|
|||
// as the screenshare executable during a post-build step
|
||||
//icon: "hifi-screenshare-icon.png"
|
||||
});
|
||||
window.loadURL('file://' + __dirname + '/index.html');
|
||||
window.loadURL('file://' + __dirname + '/screenshareApp.html');
|
||||
window.setMenu(null);
|
||||
|
||||
window.webContents.on("did-finish-load", () => {
|
||||
window.webContents.send('connectionInfo', JSON.stringify(connectionInfo));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
app.on('ready', function() {
|
Loading…
Reference in a new issue