579 lines
20 KiB
JavaScript
579 lines
20 KiB
JavaScript
/* eslint-disable no-unused-vars */
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const axios = require('axios');
|
|
const Sockette = require('sockette');
|
|
|
|
const { webFrame, ipcRenderer, shell } = require('electron');
|
|
const io = require('socket.io-client');
|
|
|
|
const GoogleTTS = require('node-google-tts-api');
|
|
|
|
const tts = new GoogleTTS();
|
|
const { Socket } = require('socket.io-client');
|
|
|
|
const main = ipcRenderer.sendSync('environment');
|
|
|
|
const resourcesPath = main.resourcesPath;
|
|
const settingsPath = main.settingsPath.toString();
|
|
const pythonPath = main.pythonPath.toString();
|
|
const settings = main.settings;
|
|
|
|
// TODO: remove gooogle voices txt and use api instead
|
|
const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n');
|
|
// TODO: remove amazon voices txt and use api instead (sakura project has it)
|
|
const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n');
|
|
const customEmotesListSavePath =
|
|
main.isPackaged === true ? path.join(resourcesPath, './custom-emotes.json') : path.join(resourcesPath, './config/custom-emotes.json');
|
|
|
|
// html elements
|
|
const root = document.documentElement;
|
|
const ttsSelector = document.body.querySelector('#TTSSelector');
|
|
const amazonVoiceSelect = document.querySelector('#amazonVoice'); // obtain the html reference of the amazon voices comboBox
|
|
const notificationAudioDevices = document.querySelector('#notificationAudioDevice'); // obtain the html reference of the installedTTS comboBox
|
|
const devicesDropdown = document.querySelector('#devicesDropdown');
|
|
const notificationSound = document.querySelector('#notification'); // obtain the html reference of the sound comboBox
|
|
const sttModel = document.querySelector('#sttModel'); // obtain the html reference of the sound comboBox
|
|
const ttsAudioDevices = document.querySelector('#ttsAudioDevice'); // obtain the html reference of the installedTTS comboBox
|
|
const notificationSoundAudioDevices = document.querySelector('#notificationSoundAudioDevice'); // obtain the html reference of the installedTTS comboBox
|
|
const emojiPicker = document.body.querySelector('emoji-picker');
|
|
const lol = document.body.querySelector('country-flag-emoji-polyfill');
|
|
|
|
// laod local javascript files
|
|
const chat = require(path.join(__dirname, './js/chat'));
|
|
|
|
const messageTemplates = require(path.join(__dirname, './js/messageTemplates'));
|
|
const languageObject = require(path.join(__dirname, './js/languages'));
|
|
const logger = require(path.join(__dirname, './js/logger'));
|
|
const sound = require(path.join(__dirname, './js/sound'));
|
|
const config = require(path.join(__dirname, './js/settings'));
|
|
const { TokenAutocomplete } = require(path.join(__dirname, './js/token-autocomplete'));
|
|
|
|
const betterTTVAutocomplete = new TokenAutocomplete({
|
|
name: 'sample',
|
|
selector: '#sample',
|
|
noMatchesText: 'No matching results...',
|
|
initialTokens: [...settings.TWITCH.BETTERTTV_CHANNELS]
|
|
});
|
|
|
|
const test = settings.TWITCH.BETTERTTV_CHANNELS;
|
|
console.log(test);
|
|
|
|
const mediaDevices = require(path.join(__dirname, './js/mediaDevices'));
|
|
|
|
const notificationSounds = path.join(resourcesPath, main.isPackaged ? './sounds/notifications' : '../sounds/notifications');
|
|
const sttModels = path.join(resourcesPath, main.isPackaged ? './speech_to_text_models' : '../speech_to_text_models');
|
|
|
|
function reset() {
|
|
ipcRenderer.send('restart');
|
|
}
|
|
|
|
const server = require(path.join(__dirname, './js/server'));
|
|
const backend = require(path.join(__dirname, './js/backend'));
|
|
const socket = io(`http://localhost:${settings.GENERAL.PORT}`); // Connect to your Socket.IO server
|
|
|
|
let twitch = null;
|
|
twitch = settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './js/twitch')) : '';
|
|
|
|
let dlive = null;
|
|
dlive = settings.DLIVE.USE_DLIVE ? require(path.join(__dirname, './js/dlive')) : '';
|
|
|
|
let youtube = null;
|
|
youtube = settings.YOUTUBE.USE_YOUTUBE ? require(path.join(__dirname, './js/youtube')) : '';
|
|
|
|
let trovo = null;
|
|
trovo = settings.TROVO.USE_TROVO ? require(path.join(__dirname, './js/trovo')) : '';
|
|
|
|
const Polly = settings.AMAZON.USE_AMAZON ? require(path.join(__dirname, './js/amazon')) : '';
|
|
const google = settings.GOOGLE.USE_GOOGLE ? require(path.join(__dirname, './js/google')) : '';
|
|
|
|
const theme = require(path.join(__dirname, './js/theme'));
|
|
const auth = require(path.join(__dirname, './js/auth'));
|
|
|
|
let ttsRequestCount = 0;
|
|
ttsRequestCount = 0;
|
|
let customEmojis = [];
|
|
customEmojis = [];
|
|
let messageId = 0;
|
|
messageId = 0;
|
|
let customEmojiList = [];
|
|
|
|
// initialize values
|
|
config.getGeneralSettings();
|
|
|
|
const TTSVolume = 1;
|
|
|
|
const notificationSoundVolume = 1;
|
|
const StartDateAndTime = Date.now();
|
|
const speakButton = document.querySelector('#speakBtn');
|
|
|
|
const amazonCredentials = {
|
|
accessKeyId: settings.AMAZON.ACCESS_KEY,
|
|
secretAccessKey: settings.AMAZON.ACCESS_SECRET
|
|
};
|
|
|
|
// Check for installed sounds
|
|
fs.readdir(notificationSounds, (err, files) => {
|
|
if (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
files.forEach((file, i) => {
|
|
// Create a new option element.
|
|
const option = document.createElement('option');
|
|
|
|
// Set the options value and text.
|
|
option.value = i;
|
|
option.innerHTML = file;
|
|
|
|
// Add the option to the sound selector.
|
|
notificationSound.appendChild(option);
|
|
});
|
|
|
|
// set the saved notification sound
|
|
notificationSound.selectedIndex = settings.AUDIO.NOTIFICATION_SOUND;
|
|
});
|
|
|
|
// Check for installed stt models
|
|
fs.readdir(sttModels, (err, files) => {
|
|
if (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
for (const file of files) {
|
|
if (file.includes('.txt')) {
|
|
continue;
|
|
}
|
|
// Create a new option element.
|
|
const option = document.createElement('option');
|
|
|
|
// Set the options value and text.
|
|
option.value = file;
|
|
option.innerHTML = file;
|
|
|
|
// Add the option to the sound selector.
|
|
sttModel.appendChild(option);
|
|
}
|
|
|
|
// set the saved notification sound
|
|
sttModel.value = settings.STT.LANGUAGE;
|
|
});
|
|
|
|
// TODO: refactor obtaining audio devices.
|
|
async function getAudioDevices() {
|
|
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
|
|
return;
|
|
}
|
|
|
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
const audioOutputDevices = devices.filter(device => device.kind === 'audiooutput');
|
|
|
|
audioOutputDevices.forEach(device => {
|
|
const option1 = document.createElement('option');
|
|
const option2 = document.createElement('option');
|
|
option1.text = device.label || `Output ${device.deviceId}`;
|
|
option2.text = device.label || `Output ${device.deviceId}`;
|
|
option1.value = device.deviceId;
|
|
option2.value = device.deviceId;
|
|
ttsAudioDevices.appendChild(option1);
|
|
notificationSoundAudioDevices.appendChild(option2);
|
|
});
|
|
|
|
ttsAudioDevices.selectedIndex = settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE;
|
|
notificationSoundAudioDevices.selectedIndex = settings.AUDIO.SELECTED_NOTIFICATION_AUDIO_DEVICE;
|
|
}
|
|
|
|
getAudioDevices();
|
|
|
|
function setSelectedLanguageinSelect(languageSelect, language) {
|
|
const button = languageSelect.querySelector('.SmallButton');
|
|
const languageElement = document.createElement('span');
|
|
languageElement.classList = `fi fi-${language.ISO3166} fis pop-selection`;
|
|
languageElement.setAttribute('tip', language.name);
|
|
button.innerHTML = '';
|
|
button.appendChild(languageElement);
|
|
addSingleTooltip(languageElement);
|
|
}
|
|
|
|
function setLanguagesinSelectx(languageSelector, language) {
|
|
const languageSelect = document.querySelector(languageSelector); // obtain the html reference of the google voices comboBox
|
|
const languageSelectContent = languageSelect.querySelector('.pop-content');
|
|
|
|
languageSelectContent.addEventListener('click', e => {
|
|
const parent = e.target.parentElement.id;
|
|
language = getLanguageProperties(e.target.getAttribute('value'));
|
|
|
|
if (parent === 'SEND_TRANSLATION_IN') {
|
|
settings.LANGUAGE.SEND_TRANSLATION_IN = language.IETF;
|
|
} else {
|
|
settings.LANGUAGE.SEND_TRANSLATION_OUT = language.IETF;
|
|
}
|
|
|
|
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
setSelectedLanguageinSelect(languageSelect, language);
|
|
});
|
|
|
|
for (const language in languageObject.languages) {
|
|
if (Object.prototype.hasOwnProperty.call(languageObject.languages, language)) {
|
|
const IETF = languageObject.languages[language].IETF;
|
|
const ISO639 = languageObject.languages[language].ISO639;
|
|
const ISO3166 = languageObject.languages[language].ISO3166;
|
|
|
|
const option = document.createElement('div');
|
|
option.classList = 'language-select';
|
|
|
|
const languageElement = document.createElement('span');
|
|
languageElement.classList = `fi fi-${ISO3166} fis`;
|
|
languageElement.style.pointerEvents = 'none';
|
|
option.setAttribute('tip', language);
|
|
|
|
const text = document.createElement('span');
|
|
text.style.pointerEvents = 'none';
|
|
text.innerHTML = ` - ${ISO639}`;
|
|
|
|
option.setAttribute('value', IETF);
|
|
|
|
languageSelectContent.appendChild(option);
|
|
option.appendChild(languageElement);
|
|
option.appendChild(text);
|
|
addSingleTooltip(option);
|
|
}
|
|
}
|
|
|
|
setSelectedLanguageinSelect(languageSelect, language);
|
|
}
|
|
|
|
setLanguagesinSelectx('.pop.in', getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_IN));
|
|
setLanguagesinSelectx('.pop.out', getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_OUT));
|
|
|
|
function setLanguagesinSelect(languageSelector, setting) {
|
|
const languageSelect = document.querySelector(languageSelector); // obtain the html reference of the google voices comboBox
|
|
|
|
for (const language in languageObject.languages) {
|
|
if (Object.prototype.hasOwnProperty.call(languageObject.languages, language)) {
|
|
const IETF = languageObject.languages[language].IETF;
|
|
const ISO639 = languageObject.languages[language].ISO639;
|
|
const option = document.createElement('option');
|
|
|
|
option.value = IETF;
|
|
option.innerHTML = `${ISO639} : ${language}`;
|
|
languageSelect.appendChild(option);
|
|
}
|
|
}
|
|
|
|
languageSelect.selectedIndex = setting;
|
|
}
|
|
|
|
setLanguagesinSelect('#language', settings.GENERAL.LANGUAGE_INDEX);
|
|
setLanguagesinSelect('#defaultLanguage', settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX);
|
|
setLanguagesinSelect('#secondaryLanguage', settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX);
|
|
setLanguagesinSelect('#TRANSLATE_TO', settings.LANGUAGE.TRANSLATE_TO_INDEX);
|
|
|
|
function addVoiceService(name) {
|
|
function addToselect(select) {
|
|
const ttsService = document.querySelector(select);
|
|
const option = document.createElement('option');
|
|
ttsService.appendChild(option);
|
|
|
|
option.value = name;
|
|
option.innerHTML = name;
|
|
}
|
|
addToselect('#primaryTTSService');
|
|
addToselect('#secondaryTTSService');
|
|
}
|
|
|
|
function determineTootlTipPosition(element) {
|
|
const horizontal = document.body.clientWidth / 2;
|
|
const vertical = document.body.clientHeight / 2;
|
|
|
|
element.tip.style.left = `${element.mouse.x}px`;
|
|
element.tip.style.top = `${element.mouse.y}px`;
|
|
|
|
const tipPosition = element.tip.getBoundingClientRect();
|
|
|
|
if (element.position.x < horizontal && element.position.y < vertical) {
|
|
element.tip.style.top = `${parseInt(element.tip.style.top) + 25}px`;
|
|
element.tip.style.left = `${parseInt(element.tip.style.left) + 10}px`;
|
|
}
|
|
|
|
if (element.position.x < horizontal && element.position.y > vertical) {
|
|
element.tip.style.top = `${parseInt(element.tip.style.top) - tipPosition.height}px`;
|
|
element.tip.style.left = `${parseInt(element.tip.style.left) + 10}px`;
|
|
}
|
|
|
|
if (element.position.x > horizontal && element.position.y < vertical) {
|
|
element.tip.style.top = `${parseInt(element.tip.style.top) + 25}px`;
|
|
element.tip.style.left = `${parseInt(element.tip.style.left) - tipPosition.width}px`;
|
|
}
|
|
|
|
if (element.position.x > horizontal && element.position.y > vertical) {
|
|
element.tip.style.top = `${parseInt(element.tip.style.top) - tipPosition.height}px`;
|
|
element.tip.style.left = `${parseInt(element.tip.style.left) - tipPosition.width}px`;
|
|
}
|
|
|
|
element.tip.style.visibility = 'visible';
|
|
}
|
|
|
|
// Small tooltip
|
|
function addSingleTooltip(el) {
|
|
const tip = document.createElement('div');
|
|
const body = document.querySelector('.container');
|
|
const element = el;
|
|
tip.classList.add('tooltip');
|
|
tip.innerText = el.getAttribute('tip');
|
|
if (el.src) {
|
|
const image = document.createElement('img');
|
|
image.src = el.src;
|
|
tip.appendChild(image);
|
|
}
|
|
body.appendChild(tip);
|
|
tip.pointerEvents = 'none';
|
|
element.onmousemove = e => {
|
|
determineTootlTipPosition({
|
|
position: element.getBoundingClientRect(),
|
|
mouse: { x: e.x, y: e.y },
|
|
tip
|
|
});
|
|
};
|
|
element.onmouseleave = e => {
|
|
tip.style.visibility = 'hidden';
|
|
};
|
|
}
|
|
|
|
Array.from(document.body.querySelectorAll('[tip]')).forEach(el => {
|
|
addSingleTooltip(el);
|
|
});
|
|
|
|
function showChatMessage(article) {
|
|
let body = null;
|
|
if (article !== undefined) {
|
|
body = document.getElementById('chatBox');
|
|
body.appendChild(article);
|
|
}
|
|
|
|
const messages = document.body.querySelectorAll('.msg-container');
|
|
|
|
const lastMessage = messages[messages.length - 1];
|
|
lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' });
|
|
|
|
// const messageId = article.id;
|
|
// languageElement.setAttribute('id', article.id);
|
|
|
|
// console.log(article);
|
|
const username = article.querySelector('.username').innerHTML;
|
|
const image = article.querySelector('.user-img').src;
|
|
const statusCircle = article.querySelector('.status-circle').src;
|
|
const message = article.querySelector('.msg-box').innerHTML;
|
|
const postTime = article.querySelector('.post-time').innerHTML;
|
|
socket.emit('chat-out', { messageId, username, image, statusCircle, message, postTime });
|
|
}
|
|
|
|
function getPostTime() {
|
|
const date = new Date();
|
|
document.body.querySelectorAll('.container').innerHTML = date.getHours();
|
|
const hours = date.getHours();
|
|
const ampm = hours >= 12 ? 'PM' : 'AM';
|
|
const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
|
|
const time = `${hours}:${minutes} ${ampm}`;
|
|
|
|
return time;
|
|
}
|
|
|
|
function showPreviewChatMessage() {
|
|
const message = messageTemplates.messageTemplate;
|
|
document.querySelector('#mini-mid').innerHTML += message;
|
|
const messages = Array.from(document.body.querySelectorAll('#mini-mid'));
|
|
const lastMessage = messages[messages.length - 1];
|
|
lastMessage.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
|
|
showPreviewChatMessage();
|
|
|
|
function hideText(button, field) {
|
|
document.body.querySelector(button).addEventListener('click', () => {
|
|
const passwordInput = document.querySelector(field);
|
|
if (passwordInput.type === 'password') {
|
|
passwordInput.type = 'lol';
|
|
} else {
|
|
passwordInput.type = 'password';
|
|
}
|
|
});
|
|
}
|
|
|
|
hideText('.password-toggle-btn1', '#TWITCH_OAUTH_TOKEN');
|
|
hideText('.password-toggle-btn2', '#TROVO_OAUTH_TOKEN');
|
|
hideText('.password-toggle-btn4', '#AMAZON_ACCESS_KEY');
|
|
hideText('.password-toggle-btn5', '#AMAZON_ACCESS_SECRET');
|
|
hideText('.password-toggle-btn6', '#GOOGLE_API_KEY');
|
|
|
|
function setZoomLevel(currentZoom, zoomIn) {
|
|
let newZoom = currentZoom.toFixed(2);
|
|
|
|
if (zoomIn === true && currentZoom < 4.95) {
|
|
newZoom = (currentZoom + 0.05).toFixed(2);
|
|
}
|
|
if (zoomIn === false && currentZoom > 0.25) {
|
|
newZoom = (currentZoom - 0.05).toFixed(2);
|
|
}
|
|
|
|
webFrame.setZoomFactor(parseFloat(newZoom));
|
|
settings.GENERAL.ZOOMLEVEL = newZoom;
|
|
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
document.body.querySelector('#ZOOMLEVEL').value = (settings.GENERAL.ZOOMLEVEL * 100).toFixed(0);
|
|
}
|
|
|
|
function getLanguageProperties(languageToDetect) {
|
|
try {
|
|
const filteredLanguage = Object.keys(languageObject.languages).reduce(function (accumulator, currentValue) {
|
|
if (
|
|
languageObject.languages[currentValue].IETF === languageToDetect ||
|
|
languageObject.languages[currentValue].ISO639 === languageToDetect ||
|
|
languageObject.languages[currentValue].ISO3166 === languageToDetect
|
|
) {
|
|
accumulator[currentValue] = languageObject.languages[currentValue];
|
|
}
|
|
return accumulator;
|
|
}, {});
|
|
|
|
const language = {
|
|
name: Object.getOwnPropertyNames(filteredLanguage)[0],
|
|
ISO3166: filteredLanguage[Object.keys(filteredLanguage)[0]].ISO3166,
|
|
ISO639: filteredLanguage[Object.keys(filteredLanguage)[0]].ISO639,
|
|
IETF: filteredLanguage[Object.keys(filteredLanguage)[0]].IETF
|
|
};
|
|
|
|
return language;
|
|
} catch (e) {
|
|
// console.error(error);
|
|
return 'error';
|
|
}
|
|
}
|
|
|
|
let customEmotes = null;
|
|
if (fs.existsSync(customEmotesListSavePath)) {
|
|
const file = fs.readFileSync(customEmotesListSavePath);
|
|
customEmotes = JSON.parse(file);
|
|
customEmojiList = [...customEmojiList, ...customEmotes];
|
|
}
|
|
|
|
emojiPicker.customEmoji = customEmojiList;
|
|
|
|
function saveCustomEmotesToFile(emotes) {
|
|
const data = JSON.stringify(emotes);
|
|
customEmojiList = [...customEmojiList, data];
|
|
const savePath =
|
|
main.isPackaged === true ? path.join(resourcesPath, './custom-emotes.json') : path.join(resourcesPath, './config/custom-emotes.json');
|
|
|
|
fs.writeFile(savePath, data, error => {
|
|
if (error) {
|
|
console.error(error);
|
|
|
|
throw error;
|
|
}
|
|
});
|
|
}
|
|
|
|
function countWords(str) {
|
|
return str.trim().split(/\s+/).length;
|
|
}
|
|
|
|
// function saveSettingsToFile(settings) {
|
|
// const data = JSON.stringify(settings);
|
|
// const savePath =
|
|
// main.isPackaged === true ? path.join(resourcesPath, './settings.json') : path.join(resourcesPath, './config/settings.json');
|
|
|
|
// fs.writeFile(savePath, data, error => {
|
|
// if (error) {
|
|
// console.error(error);
|
|
// throw error;
|
|
// }
|
|
// });
|
|
// }
|
|
|
|
/*
|
|
Copyright 2017 Google Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// var videoElement = document.querySelector('video');
|
|
// var audioSelect = document.querySelector('select#audioSource');
|
|
// var videoSelect = document.querySelector('select#videoSource');
|
|
|
|
// audioSelect.onchange = getStream;
|
|
// videoSelect.onchange = getStream;
|
|
|
|
// getStream().then(getDevices).then(gotDevices);
|
|
|
|
// function getDevices() {
|
|
// // AFAICT in Safari this only gets default devices until gUM is called :/
|
|
// return navigator.mediaDevices.enumerateDevices();
|
|
// }
|
|
|
|
// function gotDevices(deviceInfos) {
|
|
// window.deviceInfos = deviceInfos; // make available to console
|
|
// console.log('Available input and output devices:', deviceInfos);
|
|
// for (const deviceInfo of deviceInfos) {
|
|
// const option = document.createElement('option');
|
|
// option.value = deviceInfo.deviceId;
|
|
// if (deviceInfo.kind === 'audioinput') {
|
|
// option.text = deviceInfo.label || `Microphone ${audioSelect.length + 1}`;
|
|
// audioSelect.appendChild(option);
|
|
// } else if (deviceInfo.kind === 'videoinput') {
|
|
// option.text = deviceInfo.label || `Camera ${videoSelect.length + 1}`;
|
|
// videoSelect.appendChild(option);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// function getStream() {
|
|
// if (window.stream) {
|
|
// window.stream.getTracks().forEach(track => {
|
|
// track.stop();
|
|
// });
|
|
// }
|
|
// const audioSource = audioSelect.value;
|
|
// const videoSource = videoSelect.value;
|
|
// const constraints = {
|
|
// audio: { deviceId: audioSource ? { exact: audioSource } : undefined },
|
|
// video: { deviceId: videoSource ? { exact: videoSource } : undefined }
|
|
// };
|
|
// return navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(handleError);
|
|
// }
|
|
|
|
// function gotStream(stream) {
|
|
// window.stream = stream; // make stream available to console
|
|
// audioSelect.selectedIndex = [...audioSelect.options].findIndex(option => option.text === stream.getAudioTracks()[0].label);
|
|
// videoSelect.selectedIndex = [...videoSelect.options].findIndex(option => option.text === stream.getVideoTracks()[0].label);
|
|
// videoElement.srcObject = stream;
|
|
// }
|
|
|
|
// function handleError(error) {
|
|
// console.error('Error: ', error);
|
|
// }
|
|
|
|
// const settingxs = {
|
|
// video: true
|
|
// };
|
|
|
|
// navigator.mediaDevices
|
|
// .getUserMedia(settingxs)
|
|
// .then(stream => {
|
|
// const video = document.getElementById('video');
|
|
// video.srcObject = stream;
|
|
// video.play();
|
|
// })
|
|
// .catch(err => {
|
|
// console.log(err);
|
|
// alert('Não há permissões para acessar a webcam.');
|
|
// });
|