NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Webcamdarts recording & design // @name:fr Webcamdarts enregistrement design // @namespace http://tampermonkey.net/ // @version 1 // @description To see your webcam and the opponent webcam in equal size. Webcamdarts Dual view for Joiner in this case and activate this one. // @description:fr design de l'espace match - votre cible est score sont a gauche (quand c'est vous qui invité un joueur) // @author Antoine Maingeot // @match https://game.webcamdarts.com/game // @grant none // @require https://www.webrtc-experiment.com/RecordRTC.js // @require https://www.webrtc-experiment.com/DetectRTC.js // @license MIT // @copyright 2020, maingeot (https://openuserjs.org/users/maingeot) // ==/UserScript== ////////////Record ///////////////////// (function () { 'use strict'; function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } addGlobalStyle('#start-stop{ position:fixed;bottom: 4px ;right:385px;}'); addGlobalStyle('#save-option{ position:fixed;bottom: 4px ;right:520px;}'); addGlobalStyle('#upload-to-php, #youtube, #recording-player > div.media-container > div.media-box > section > video{ display:none}'); addGlobalStyle('#recording-player > div.media-container > div.media-box > h2{bottom: 36px ;right:4px;}') addGlobalStyle('.recording-media, #content > div > div > div:nth-child(14) { display:none;}'); addGlobalStyle('#time-slice{ position:fixed;bottom: 36px ;right:392px;}'); addGlobalStyle('#video-status{position:fixed; bottom:36px; left;4px;}'); addGlobalStyle('#save-to-disk{ background-color:#d54248;}'); })(); (function () { 'use strict'; // add Selectmedia var Selectmedia = document.createElement('div'); Selectmedia.innerHTML = '<select class="recording-media">-<option value="record-screen">Full Screen</option><option value="record-audio-plus-video" style="display: none;">Microphone+Camera</option><option value="record-audio" style="display: none;">Microphone</option><option value="record-audio-plus-screen">Microphone+Screen</option></select>'; var posSelectmedia = document.querySelector('.wrapper-sm'); posSelectmedia.after(Selectmedia); // add Selectformat var Selectformat = document.createElement('div'); Selectformat.innerHTML = '<select class="media-container-format" style="display: none;"><option>default</option><option>vp8</option><option>vp9</option><option>h264</option><option>mkv</option><option disabled="">opus</option><option disabled="">ogg</option><option disabled="">pcm</option><option>gif</option><option>whammy</option><option>WebAssembly</option></select>'; var posSelectformat = document.querySelector('.wrapper-sm'); posSelectformat.after(Selectformat); // add Selecttimeslice var Selecttimeslice = document.createElement('div'); Selecttimeslice.innerHTML = '<div id="time-slice"><input type="checkbox" id="chk-timeSlice" style="margin:0;width:auto;opacity: 0.4;vertical-align: middle;" title="Use intervals based recording"><label for="chk-timeSlice" style="font-size: 12px;margin:0;width: auto;opacity: 0.4cursor: pointer;-webkit-user-select:none;user-select:none;" title="Use intervals based recording">Use timeSlice?</label></div>'; var posSelecttimeslice = document.querySelector('.wrapper-sm'); posSelecttimeslice.after(Selecttimeslice); // add Selectbitrates var Selectbitrates = document.createElement('div'); Selectbitrates.innerHTML = '<select class="media-bitrates" style="display: none;"><option value="default">Default bitrates</option><option value="8000000000">1 GB bps</option><option value="800000000">100 MB bps</option><option value="8000000">1 MB bps</option><option value="800000">100 KB bps</option><option value="8000">1 KB bps</option><option value="800">100 Bytes bps</option></select>'; var posSelectbitrates = document.querySelector('.wrapper-sm'); posSelectbitrates.after(Selectbitrates); // add Selectframerates var Selectframerates = document.createElement('div'); Selectframerates.innerHTML = '<select class="media-framerates" style="display: none;"><option value="default">Default framerates</option><option value="5">5 fps</option><option value="15">15 fps</option><option value="24">24 fps</option><option value="30">30 fps</option><option value="60">60 fps</option></select>'; var posSelectframerates = document.querySelector('.wrapper-sm'); posSelectframerates.after(Selectframerates); // add Selectresolutions var Selectresolutions = document.createElement('div'); Selectresolutions.innerHTML = '<select class="media-resolutions" style="display: none;"><option value="default">Default resolutions</option><option value="1920x1080">1080p</option><option value="1280x720">720p</option><option value="640x480">480p</option><option value="3840x2160">4K Ultra HD (3840x2160)</option></select>'; var posSelectresolutions = document.querySelector('.wrapper-sm'); posSelectresolutions.after(Selectresolutions); // add fixSeeking var fixSeeking = document.createElement('div'); fixSeeking.innerHTML = '<div style="display: none;"><input type="checkbox" id="chk-fixSeeking" style="margin:0;width:auto;" title="Fix video seeking issues?"><label for="chk-fixSeeking" style="font-size: 15px;margin:0;width: auto;cursor: pointer;-webkit-user-select:none;user-select:none;" title="Fix video seeking issues?">Fix Seeking Issues?</label></div>'; var posfixSeeking = document.querySelector('.wrapper-sm'); posfixSeeking.after(fixSeeking); // add button StartStop var StartStop = document.createElement('div'); StartStop.innerHTML = '<div id="start-stop"><button class="btn btn-primary" id="btn-start-recording" class="btn btn-primary"style="margin-right:3px;">Start Recording</button><button id="btn-pause-recording" class="btn btn-primary" style="display: none; ">Pause</button></div>'; var posStartStop = document.querySelector('.wrapper-sm'); posStartStop.after(StartStop); // add button Save record var buttonrecord = document.createElement('div'); buttonrecord.innerHTML = '<div id="save-option" style="text-align: center; display: none;"><button id="save-to-disk"class="btn btn-primary"style="margin-right:5px;">Save</button><button id="open-new-tab" class="btn btn-primary">Preview Video</button><button id="upload-to-php">Upload to PHP</button></div>'; var posbuttonrecord = document.querySelector('.wrapper-sm'); posbuttonrecord.after(buttonrecord); // add button to view video on screen var viewvideo = document.createElement('div'); viewvideo.innerHTML = '<div class="media-controls"></div><div class="control zoom-in"></div><div class="volume-control"></div><div id="recording-player"></div><div class="media-box"></div>'; var posviewvideo = document.querySelector('.wrapper-sm'); posviewvideo.after(viewvideo); // add button YouTube var buttonYouTube = document.createElement('div'); buttonYouTube.innerHTML = '<div id="youtube" style="margin-top: 10px;"><span id="signinButton" class="pre-sign-in"><spanclass="g-signin"data-callback="signinCallback"data-clientid="41556190767-115ifahd55lk4ln5pop4jus55cr4l7oh.apps.googleusercontent.com"data-cookiepolicy="single_host_origin"data-scope="https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtube"></span></span><button id="upload-to-youtube" style="vertical-align:top;">Upload to YouTube</button></div></div>'; var posbuttonYouTube = document.querySelector('.wrapper-sm'); posbuttonYouTube.after(buttonYouTube); // add divAutoplay var divAutoplay = document.createElement('div'); divAutoplay.innerHTML = '<section><video autoplay="" style="max-height: 880px;"></video></section>'; var posdivAutoplay = document.querySelector('.wrapper-sm'); posdivAutoplay.after(divAutoplay); // // /*// add button to view video on screen var videotime = document.createElement('div'); videotime.innerHTML = '<div id="video-status"><label>State preview: </label><h5 id="state-preview" style="color: red;">inactive</h5></div>'; var posvideotime = document.querySelector('.wrapper-sm'); posvideotime.after(videotime); */ })(); (function () { var params = {}, r = /([^&=]+)=?([^&]*)/g; function d(s) { return decodeURIComponent(s.replace(/\+/g, ' ')); } var match, search = window.location.search; while (match = r.exec(search.substring(1))) { params[d(match[1])] = d(match[2]); if (d(match[2]) === 'true' || d(match[2]) === 'false') { params[d(match[1])] = d(match[2]) === 'true' ? true : false; } } window.params = params; })(); function addStreamStopListener(stream, callback) { stream.addEventListener('ended', function () { callback(); callback = function () {}; }, false); stream.addEventListener('inactive', function () { callback(); callback = function () {}; }, false); stream.getTracks().forEach(function (track) { track.addEventListener('ended', function () { callback(); callback = function () {}; }, false); track.addEventListener('inactive', function () { callback(); callback = function () {}; }, false); }); } var video = document.createElement('video'); video.controls = false; var mediaElement = getHTMLMediaElement(video, { title: ' ', buttons: ['full-screen' /*, 'take-snapshot'*/ ], showOnMouseEnter: false, width: 360, onTakeSnapshot: function () { var canvas = document.createElement('canvas'); canvas.width = mediaElement.clientWidth; canvas.height = mediaElement.clientHeight; var context = canvas.getContext('2d'); context.drawImage(recordingPlayer, 0, 0, canvas.width, canvas.height); window.open(canvas.toDataURL('image/png')); } }); document.getElementById('recording-player').appendChild(mediaElement); var div = document.createElement('section'); mediaElement.media.parentNode.appendChild(div); mediaElement.media.muted = false; mediaElement.media.autoplay = true; mediaElement.media.playsinline = true; div.appendChild(mediaElement.media); var recordingPlayer = mediaElement.media; var recordingMedia = document.querySelector('.recording-media'); var mediaContainerFormat = document.querySelector('.media-container-format'); var mimeType = 'video/webm'; var fileExtension = 'webm'; var type = 'video'; var recorderType; var defaultWidth; var defaultHeight; var btnStartRecording = document.querySelector('#btn-start-recording'); window.onbeforeunload = function () { btnStartRecording.disabled = false; recordingMedia.disabled = false; mediaContainerFormat.disabled = false; chkFixSeeking.parentNode.style.display = 'inline-block'; }; btnStartRecording.onclick = function (event) { var button = btnStartRecording; if (button.innerHTML === 'Stop Recording') { btnPauseRecording.style.display = 'none'; button.disabled = true; button.disableStateWaiting = true; setTimeout(function () { button.disabled = false; button.disableStateWaiting = false; }, 2000); button.innerHTML = 'Start Recording'; function stopStream() { if (button.stream && button.stream.stop) { button.stream.stop(); button.stream = null; } if (button.stream instanceof Array) { button.stream.forEach(function (stream) { stream.stop(); }); button.stream = null; } videoBitsPerSecond = null; var html = 'Recording status: stopped - '; html += 'Size: ' + bytesToSize(button.recordRTC.getBlob().size); recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = html; } if (button.recordRTC) { if (button.recordRTC.length) { button.recordRTC[0].stopRecording(function (url) { if (!button.recordRTC[1]) { button.recordingEndedCallback(url); stopStream(); saveToDiskOrOpenNewTab(button.recordRTC[0]); return; } button.recordRTC[1].stopRecording(function (url) { button.recordingEndedCallback(url); stopStream(); }); }); } else { button.recordRTC.stopRecording(function (url) { if (button.blobs && button.blobs.length) { var blob = new File(button.blobs, getFileName(fileExtension), { type: mimeType }); button.recordRTC.getBlob = function () { return blob; }; url = URL.createObjectURL(blob); } if (chkFixSeeking.checked === true) { // to fix video seeking issues getSeekableBlob(button.recordRTC.getBlob(), function (seekableBlob) { button.recordRTC.getBlob = function () { return seekableBlob; }; url = URL.createObjectURL(seekableBlob); button.recordingEndedCallback(url); saveToDiskOrOpenNewTab(button.recordRTC); stopStream(); }) return; } button.recordingEndedCallback(url); saveToDiskOrOpenNewTab(button.recordRTC); stopStream(); }); } } return; } if (!event) return; button.disabled = true; var commonConfig = { onMediaCaptured: function (stream) { button.stream = stream; if (button.mediaCapturedCallback) { button.mediaCapturedCallback(); } button.innerHTML = 'Stop Recording'; button.disabled = false; chkFixSeeking.parentNode.style.display = 'none'; }, onMediaStopped: function () { button.innerHTML = 'Start Recording'; if (!button.disableStateWaiting) { button.disabled = false; } chkFixSeeking.parentNode.style.display = 'inline-block'; }, onMediaCapturingFailed: function (error) { console.error('onMediaCapturingFailed:', error); if (error.toString().indexOf('no audio or video tracks available') !== -1) { alert('RecordRTC failed to start because there are no audio or video tracks available.'); } if (error.name === 'PermissionDeniedError' && DetectRTC.browser.name === 'Firefox') { alert('Firefox requires version >= 52. Firefox also requires HTTPs.'); } commonConfig.onMediaStopped(); } }; if (mediaContainerFormat.value === 'h264') { mimeType = 'video/webm\;codecs=h264'; fileExtension = 'mp4'; // video/mp4;codecs=avc1 if (isMimeTypeSupported('video/mpeg')) { mimeType = 'video/mpeg'; } } if (mediaContainerFormat.value === 'mkv' && isMimeTypeSupported('video/x-matroska;codecs=avc1')) { mimeType = 'video/x-matroska;codecs=avc1'; fileExtension = 'mkv'; } if (mediaContainerFormat.value === 'vp8' && isMimeTypeSupported('video/webm\;codecs=vp8')) { mimeType = 'video/webm\;codecs=vp8'; fileExtension = 'webm'; recorderType = null; type = 'video'; } if (mediaContainerFormat.value === 'vp9' && isMimeTypeSupported('video/webm\;codecs=vp9')) { mimeType = 'video/webm\;codecs=vp9'; fileExtension = 'webm'; recorderType = null; type = 'video'; } if (mediaContainerFormat.value === 'pcm') { mimeType = 'audio/wav'; fileExtension = 'wav'; recorderType = StereoAudioRecorder; type = 'audio'; } if (mediaContainerFormat.value === 'opus' || mediaContainerFormat.value === 'ogg') { if (isMimeTypeSupported('audio/webm')) { mimeType = 'audio/webm'; fileExtension = 'webm'; // webm } if (isMimeTypeSupported('audio/ogg')) { mimeType = 'audio/ogg; codecs=opus'; fileExtension = 'ogg'; // ogg } recorderType = null; type = 'audio'; } if (mediaContainerFormat.value === 'whammy') { mimeType = 'video/webm'; fileExtension = 'webm'; recorderType = WhammyRecorder; type = 'video'; } if (mediaContainerFormat.value === 'WebAssembly') { mimeType = 'video/webm'; fileExtension = 'webm'; recorderType = WebAssemblyRecorder; type = 'video'; } if (mediaContainerFormat.value === 'gif') { mimeType = 'image/gif'; fileExtension = 'gif'; recorderType = GifRecorder; type = 'gif'; } if (mediaContainerFormat.value === 'default') { mimeType = 'video/webm\;codecs=h264'; fileExtension = 'mp4'; recorderType = null; type = 'video'; } if (recordingMedia.value === 'record-audio') { captureAudio(commonConfig); button.mediaCapturedCallback = function () { var options = { type: type, mimeType: mimeType, leftChannel: params.leftChannel || false, disableLogs: params.disableLogs || false }; if (params.sampleRate) { options.sampleRate = parseInt(params.sampleRate); } if (params.bufferSize) { options.bufferSize = parseInt(params.bufferSize); } if (recorderType) { options.recorderType = recorderType; } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } if (DetectRTC.browser.name === 'Edge') { options.numberOfAudioChannels = 1; } options.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; }; } if (recordingMedia.value === 'record-audio-plus-video') { captureAudioPlusVideo(commonConfig); button.mediaCapturedCallback = function () { if (typeof MediaRecorder === 'undefined') { // opera or chrome etc. button.recordRTC = []; if (!params.bufferSize) { // it fixes audio issues whilst recording 720p params.bufferSize = 16384; } var options = { type: 'audio', // hard-code to set "audio" leftChannel: params.leftChannel || false, disableLogs: params.disableLogs || false, video: recordingPlayer }; if (params.sampleRate) { options.sampleRate = parseInt(params.sampleRate); } if (params.bufferSize) { options.bufferSize = parseInt(params.bufferSize); } if (params.frameInterval) { options.frameInterval = parseInt(params.frameInterval); } if (recorderType) { options.recorderType = recorderType; } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } options.ignoreMutedMedia = false; var audioRecorder = RecordRTC(button.stream, options); options.type = type; var videoRecorder = RecordRTC(button.stream, options); // to sync audio/video playbacks in browser! videoRecorder.initRecorder(function () { audioRecorder.initRecorder(function () { audioRecorder.startRecording(); videoRecorder.startRecording(); btnPauseRecording.style.display = ''; }); }); button.recordRTC.push(audioRecorder, videoRecorder); button.recordingEndedCallback = function () { var audio = new Audio(); audio.src = audioRecorder.toURL(); audio.controls = true; audio.autoplay = true; recordingPlayer.parentNode.appendChild(document.createElement('hr')); recordingPlayer.parentNode.appendChild(audio); if (audio.paused) audio.play(); }; return; } var options2 = { type: type, mimeType: mimeType, disableLogs: params.disableLogs || false, getNativeBlob: false, // enable it for longer recordings video: recordingPlayer }; if (recorderType) { options2.recorderType = recorderType; if (recorderType == WhammyRecorder || recorderType == GifRecorder || recorderType == WebAssemblyRecorder) { options2.canvas = options2.video = { width: defaultWidth || 320, height: defaultHeight || 240 }; } } if (videoBitsPerSecond) { options2.videoBitsPerSecond = videoBitsPerSecond; } if (timeSlice && typeof MediaRecorder !== 'undefined') { options2.timeSlice = timeSlice; button.blobs = []; options2.ondataavailable = function (blob) { button.blobs.push(blob); }; } options2.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options2); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = '<img src="https://www.webrtc-experiment.com/images/progress.gif">'; }; } if (recordingMedia.value === 'record-screen') { captureScreen(commonConfig); button.mediaCapturedCallback = function () { var options = { type: type, mimeType: mimeType, disableLogs: params.disableLogs || false, getNativeBlob: false, // enable it for longer recordings video: recordingPlayer }; if (recorderType) { options.recorderType = recorderType; if (recorderType == WhammyRecorder || recorderType == GifRecorder || recorderType == WebAssemblyRecorder) { options.canvas = options.video = { width: defaultWidth || 320, height: defaultHeight || 240 }; } } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } options.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; }; } // note: audio+tab is supported in Chrome 50+ // todo: add audio+tab recording if (recordingMedia.value === 'record-audio-plus-screen') { captureAudioPlusScreen(commonConfig); button.mediaCapturedCallback = function () { var options = { type: type, mimeType: mimeType, disableLogs: params.disableLogs || false, getNativeBlob: false, // enable it for longer recordings video: recordingPlayer }; if (recorderType) { options.recorderType = recorderType; if (recorderType == WhammyRecorder || recorderType == GifRecorder || recorderType == WebAssemblyRecorder) { options.canvas = options.video = { width: defaultWidth || 320, height: defaultHeight || 240 }; } } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } options.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; }; } }; function captureVideo(config) { captureUserMedia({ video: true }, function (videoStream) { config.onMediaCaptured(videoStream); addStreamStopListener(videoStream, function () { config.onMediaStopped(); }); }, function (error) { config.onMediaCapturingFailed(error); }); } function captureAudio(config) { captureUserMedia({ audio: true }, function (audioStream) { config.onMediaCaptured(audioStream); addStreamStopListener(audioStream, function () { config.onMediaStopped(); }); }, function (error) { config.onMediaCapturingFailed(error); }); } function captureAudioPlusVideo(config) { captureUserMedia({ video: true, audio: true }, function (audioVideoStream) { config.onMediaCaptured(audioVideoStream); if (audioVideoStream instanceof Array) { audioVideoStream.forEach(function (stream) { addStreamStopListener(stream, function () { config.onMediaStopped(); }); }); return; } addStreamStopListener(audioVideoStream, function () { config.onMediaStopped(); }); }, function (error) { config.onMediaCapturingFailed(error); }); } var MY_DOMAIN = 'webrtc-experiment.com'; function isMyOwnDomain() { // replace "webrtc-experiment.com" with your own domain name return document.domain.indexOf(MY_DOMAIN) !== -1; } function isLocalHost() { // "chrome.exe" --enable-usermedia-screen-capturing // or firefox => about:config => "media.getusermedia.screensharing.allowed_domains" => add "localhost" return document.domain === 'localhost' || document.domain === '127.0.0.1'; } var videoBitsPerSecond; function setVideoBitrates() { var select = document.querySelector('.media-bitrates'); var value = select.value; if (value == 'default') { videoBitsPerSecond = null; return; } videoBitsPerSecond = parseInt(value); } function getFrameRates(mediaConstraints) { if (!mediaConstraints.video) { return mediaConstraints; } var select = document.querySelector('.media-framerates'); var value = select.value; if (value == 'default') { return mediaConstraints; } value = parseInt(value); if (DetectRTC.browser.name === 'Firefox') { mediaConstraints.video.frameRate = value; return mediaConstraints; } if (!mediaConstraints.video.mandatory) { mediaConstraints.video.mandatory = {}; mediaConstraints.video.optional = []; } var isScreen = recordingMedia.value.toString().toLowerCase().indexOf('screen') != -1; if (isScreen) { mediaConstraints.video.mandatory.maxFrameRate = value; } else { mediaConstraints.video.mandatory.minFrameRate = value; } return mediaConstraints; } function setGetFromLocalStorage(selectors) { selectors.forEach(function (selector) { var storageItem = selector.replace(/\.|#/g, ''); if (localStorage.getItem(storageItem)) { document.querySelector(selector).value = localStorage.getItem(storageItem); } addEventListenerToUploadLocalStorageItem(selector, ['change', 'blur'], function () { localStorage.setItem(storageItem, document.querySelector(selector).value); }); }); } function addEventListenerToUploadLocalStorageItem(selector, arr, callback) { arr.forEach(function (event) { document.querySelector(selector).addEventListener(event, callback, false); }); } setGetFromLocalStorage(['.media-resolutions', '.media-framerates', '.media-bitrates', '.recording-media', '.media-container-format']); function getVideoResolutions(mediaConstraints) { if (!mediaConstraints.video) { return mediaConstraints; } var select = document.querySelector('.media-resolutions'); var value = select.value; if (value == 'default') { return mediaConstraints; } value = value.split('x'); if (value.length != 2) { return mediaConstraints; } defaultWidth = parseInt(value[0]); defaultHeight = parseInt(value[1]); if (DetectRTC.browser.name === 'Firefox') { mediaConstraints.video.width = defaultWidth; mediaConstraints.video.height = defaultHeight; return mediaConstraints; } if (!mediaConstraints.video.mandatory) { mediaConstraints.video.mandatory = {}; mediaConstraints.video.optional = []; } var isScreen = recordingMedia.value.toString().toLowerCase().indexOf('screen') != -1; if (isScreen) { mediaConstraints.video.mandatory.maxWidth = defaultWidth; mediaConstraints.video.mandatory.maxHeight = defaultHeight; } else { mediaConstraints.video.mandatory.minWidth = defaultWidth; mediaConstraints.video.mandatory.minHeight = defaultHeight; } return mediaConstraints; } function captureUserMedia(mediaConstraints, successCallback, errorCallback) { if (mediaConstraints.video == true) { mediaConstraints.video = {}; } setVideoBitrates(); mediaConstraints = getVideoResolutions(mediaConstraints); mediaConstraints = getFrameRates(mediaConstraints); var isBlackBerry = !!(/BB10|BlackBerry/i.test(navigator.userAgent || '')); if (isBlackBerry && !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia)) { navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; navigator.getUserMedia(mediaConstraints, successCallback, errorCallback); return; } navigator.mediaDevices.getUserMedia(mediaConstraints).then(function (stream) { successCallback(stream); setVideoURL(stream, true); }).catch(function (error) { if (error && (error.name === 'ConstraintNotSatisfiedError' || error.name === 'OverconstrainedError')) { alert('Your camera or browser does NOT supports selected resolutions or frame-rates. \n\nPlease select "default" resolutions.'); } else if (error && error.message) { alert(error.message); } else { alert('Unable to make getUserMedia request. Please check browser console logs.'); } errorCallback(error); }); } function setMediaContainerFormat(arrayOfOptionsSupported) { var options = Array.prototype.slice.call( mediaContainerFormat.querySelectorAll('option') ); var localStorageItem; if (localStorage.getItem('media-container-format')) { localStorageItem = localStorage.getItem('media-container-format'); } var selectedItem; options.forEach(function (option) { option.disabled = true; if (arrayOfOptionsSupported.indexOf(option.value) !== -1) { option.disabled = false; if (localStorageItem && arrayOfOptionsSupported.indexOf(localStorageItem) != -1) { if (option.value != localStorageItem) return; option.selected = true; selectedItem = option; return; } if (!selectedItem) { option.selected = true; selectedItem = option; } } }); } function isMimeTypeSupported(mimeType) { if (typeof MediaRecorder === 'undefined') { return false; } if (typeof MediaRecorder.isTypeSupported !== 'function') { return true; } return MediaRecorder.isTypeSupported(mimeType); } recordingMedia.onchange = function () { if (recordingMedia.value === 'record-audio') { var recordingOptions1 = []; if (isMimeTypeSupported('audio/webm')) { recordingOptions1.push('opus'); } if (isMimeTypeSupported('audio/ogg')) { recordingOptions1.push('ogg'); } recordingOptions1.push('pcm'); setMediaContainerFormat(recordingOptions1); return; } var isChrome = !!window.chrome && !(!!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0); var recordingOptions = ['vp8']; // MediaStreamRecorder with vp8 if (isMimeTypeSupported('video/webm\;codecs=vp9')) { recordingOptions.push('vp9'); // MediaStreamRecorder with vp9 } if (isMimeTypeSupported('video/webm\;codecs=h264')) { recordingOptions.push('h264'); // MediaStreamRecorder with h264 } if (isMimeTypeSupported('video/x-matroska;codecs=avc1')) { recordingOptions.push('mkv'); // MediaStreamRecorder with mkv/matroska } recordingOptions.push('gif'); // GifRecorder if (DetectRTC.browser.name == 'Chrome') { recordingOptions.push('whammy'); // WhammyRecorder } if (DetectRTC.browser.name == 'Chrome') { recordingOptions.push('WebAssembly'); // WebAssemblyRecorder } recordingOptions.push('default'); // Default mimeType for MediaStreamRecorder setMediaContainerFormat(recordingOptions); }; recordingMedia.onchange(); if (typeof MediaRecorder === 'undefined' && (DetectRTC.browser.name === 'Edge' || DetectRTC.browser.name === 'Safari')) { // webp isn't supported in Microsoft Edge // neither MediaRecorder API // so lets disable both video/screen recording options console.warn('Neither MediaRecorder API nor webp is supported in ' + DetectRTC.browser.name + '. You cam merely record audio.'); recordingMedia.innerHTML = '<option value="record-audio">Audio</option>'; setMediaContainerFormat(['pcm']); } function stringify(obj) { var result = ''; Object.keys(obj).forEach(function (key) { if (typeof obj[key] === 'function') { return; } if (result.length) { result += ','; } result += key + ': ' + obj[key]; }); return result; } function mediaRecorderToStringify(mediaRecorder) { var result = ''; result += 'mimeType: ' + mediaRecorder.mimeType; result += ', state: ' + mediaRecorder.state; result += ', audioBitsPerSecond: ' + mediaRecorder.audioBitsPerSecond; result += ', videoBitsPerSecond: ' + mediaRecorder.videoBitsPerSecond; if (mediaRecorder.stream) { result += ', streamid: ' + mediaRecorder.stream.id; result += ', stream-active: ' + mediaRecorder.stream.active; } return result; } function getFailureReport() { var info = 'RecordRTC seems failed. \n\n' + stringify(DetectRTC.browser) + '\n\n' + DetectRTC.osName + ' ' + DetectRTC.osVersion + '\n'; if (typeof recorderType !== 'undefined' && recorderType) { info += '\nrecorderType: ' + recorderType.name; } if (typeof mimeType !== 'undefined') { info += '\nmimeType: ' + mimeType; } Array.prototype.slice.call(document.querySelectorAll('select')).forEach(function (select) { info += '\n' + (select.id || select.className) + ': ' + select.value; }); if (btnStartRecording.recordRTC) { info += '\n\ninternal-recorder: ' + btnStartRecording.recordRTC.getInternalRecorder().name; if (btnStartRecording.recordRTC.getInternalRecorder().getAllStates) { info += '\n\nrecorder-states: ' + btnStartRecording.recordRTC.getInternalRecorder().getAllStates(); } } if (btnStartRecording.stream) { info += '\n\naudio-tracks: ' + getTracks(btnStartRecording.stream, 'audio').length; info += '\nvideo-tracks: ' + getTracks(btnStartRecording.stream, 'video').length; info += '\nstream-active? ' + !!btnStartRecording.stream.active; btnStartRecording.stream.getTracks().forEach(function (track) { info += '\n' + track.kind + '-track-' + (track.label || track.id) + ': (enabled: ' + !!track.enabled + ', readyState: ' + track.readyState + ', muted: ' + !!track.muted + ')'; if (track.getConstraints && Object.keys(track.getConstraints()).length) { info += '\n' + track.kind + '-track-getConstraints: ' + stringify(track.getConstraints()); } if (track.getSettings && Object.keys(track.getSettings()).length) { info += '\n' + track.kind + '-track-getSettings: ' + stringify(track.getSettings()); } }); } if (timeSlice && btnStartRecording.recordRTC) { info += '\ntimeSlice: ' + timeSlice; if (btnStartRecording.recordRTC.getInternalRecorder().getArrayOfBlobs) { var blobSizes = []; btnStartRecording.recordRTC.getInternalRecorder().getArrayOfBlobs().forEach(function (blob) { blobSizes.push(blob.size); }); info += '\nblobSizes: ' + blobSizes; } } else if (btnStartRecording.recordRTC && btnStartRecording.recordRTC.getBlob()) { info += '\n\nblobSize: ' + bytesToSize(btnStartRecording.recordRTC.getBlob().size); } if (btnStartRecording.recordRTC && btnStartRecording.recordRTC.getInternalRecorder() && btnStartRecording.recordRTC.getInternalRecorder().getInternalRecorder && btnStartRecording.recordRTC.getInternalRecorder().getInternalRecorder()) { info += '\n\ngetInternalRecorder: ' + mediaRecorderToStringify(btnStartRecording.recordRTC.getInternalRecorder().getInternalRecorder()); } return info; } function saveToDiskOrOpenNewTab(recordRTC) { if (!recordRTC.getBlob().size) { var info = getFailureReport(); console.log('blob', recordRTC.getBlob()); console.log('recordrtc instance', recordRTC); console.log('report', info); if (mediaContainerFormat.value !== 'default') { alert('RecordRTC seems failed recording using ' + mediaContainerFormat.value + '. Please choose "default" option from the drop down and record again.'); } else { alert('RecordRTC seems failed. Unexpected issue. You can read the email in your console log. \n\nPlease report using disqus chat below.'); } if (mediaContainerFormat.value !== 'vp9' && DetectRTC.browser.name === 'Chrome') { alert('Please record using VP9 encoder. (select from the dropdown)'); } } var fileName = getFileName(fileExtension); document.querySelector('#save-to-disk').parentNode.style.display = 'block'; document.querySelector('#save-to-disk').onclick = function () { if (!recordRTC) return alert('No recording found.'); var file = new File([recordRTC.getBlob()], fileName, { type: mimeType }); invokeSaveAsDialog(file, file.name); }; document.querySelector('#open-new-tab').onclick = function () { if (!recordRTC) return alert('No recording found.'); var file = new File([recordRTC.getBlob()], fileName, { type: mimeType }); window.open(URL.createObjectURL(file)); }; // upload to PHP server if (isMyOwnDomain()) { document.querySelector('#upload-to-php').disabled = true; document.querySelector('#upload-to-php').style.display = 'none'; } else { document.querySelector('#upload-to-php').disabled = true; } document.querySelector('#upload-to-php').onclick = function () { if (isMyOwnDomain()) { alert('PHP Upload is not available on this domain.'); return; } if (!recordRTC) return alert('No recording found.'); this.disabled = true; var button = this; uploadToPHPServer(fileName, recordRTC, function (progress, fileURL) { if (progress === 'ended') { button.disabled = false; button.innerHTML = 'Click to download from server'; button.onclick = function () { SaveFileURLToDisk(fileURL, fileName); }; setVideoURL(fileURL); var html = 'Uploaded to PHP.<br>Download using below link:<br>'; html += '<a href="' + fileURL + '" download="' + fileName + '" style="color: yellow; display: block; margin-top: 15px;">' + fileName + '</a>'; recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = html; return; } button.innerHTML = progress; recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = progress; }); }; // upload to YouTube! document.querySelector('#upload-to-youtube').disabled = false; document.querySelector('#upload-to-youtube').onclick = function () { if (!recordRTC) return alert('No recording found.'); this.disabled = true; if (isLocalHost()) { alert('This feature is NOT available on localhost.'); return; } if (isMyOwnDomain() === false) { var url = 'https://github.com/muaz-khan/RecordRTC/wiki/Upload-to-YouTube'; alert('YouTube API key is configured to work only on webrtc-experiment.com. Please create your own YouTube key + oAuth client-id and use it instead.\n\nWiki page: ' + url); // check instructions on the wiki page location.href = url; return; } var button = this; uploadToYouTube(fileName, recordRTC, function (percentageComplete, fileURL) { if (percentageComplete == 'uploaded') { button.disabled = false; button.innerHTML = 'Uploaded. However YouTube is still processing.'; button.onclick = function () { window.open(fileURL); }; return; } if (percentageComplete == 'processed') { button.disabled = false; button.innerHTML = 'Uploaded & Processed. Click to open YouTube video.'; button.onclick = function () { window.open(fileURL); }; document.querySelector('h1').innerHTML = 'Your video has been uploaded.'; window.scrollTo(0, 0); alert('Your video has been uploaded.'); return; } if (percentageComplete == 'failed') { button.disabled = false; button.innerHTML = 'YouTube failed transcoding the video.'; button.onclick = function () { window.open(fileURL); }; return; } button.innerHTML = percentageComplete + '% uploaded to YouTube.'; }); }; } function uploadToPHPServer(fileName, recordRTC, callback) { var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.getBlob(); blob = new File([blob], getFileName(fileExtension), { type: mimeType }); // create FormData var formData = new FormData(); formData.append('video-filename', fileName); formData.append('video-blob', blob); callback('Uploading recorded-file to server.'); // var upload_url = 'https://your-domain.com/files-uploader/'; var upload_url = 'RecordRTC-to-PHP/save.php'; // var upload_directory = upload_url; var upload_directory = 'RecordRTC-to-PHP/uploads/'; makeXMLHttpRequest(upload_url, formData, function (progress) { if (progress !== 'upload-ended') { callback(progress); return; } callback('ended', upload_directory + fileName); }); } function makeXMLHttpRequest(url, data, callback) { var request = new XMLHttpRequest(); request.onreadystatechange = function () { if (request.readyState == 4 && request.status == 200) { if (request.responseText === 'success') { callback('upload-ended'); return; } document.querySelector('.header').parentNode.style = 'text-align: left; color: red; padding: 5px 10px;'; document.querySelector('.header').parentNode.innerHTML = request.responseText; } }; request.upload.onloadstart = function () { callback('Upload started...'); }; request.upload.onprogress = function (event) { callback('Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%"); }; request.upload.onload = function () { callback('progress-about-to-end'); }; request.upload.onload = function () { callback('Getting File URL..'); }; request.upload.onerror = function (error) { callback('Failed to upload to server'); }; request.upload.onabort = function (error) { callback('Upload aborted.'); }; request.open('POST', url); request.send(data); } function getRandomString() { if (window.crypto && window.crypto.getRandomValues && navigator.userAgent.indexOf('Safari') === -1) { var a = window.crypto.getRandomValues(new Uint32Array(3)), token = ''; for (var i = 0, l = a.length; i < l; i++) { token += a[i].toString(36); } return token; } else { return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, ''); } } function getFileName(fileExtension) { var d = new Date(); var year = d.getUTCFullYear(); var month = d.getUTCMonth(); var date = d.getUTCDate(); return 'RecordRTC-' + year + month + date + '-' + getRandomString() + '.' + fileExtension; } function SaveFileURLToDisk(fileUrl, fileName) { var hyperlink = document.createElement('a'); hyperlink.href = fileUrl; hyperlink.target = '_blank'; hyperlink.download = fileName || fileUrl; (document.body || document.documentElement).appendChild(hyperlink); hyperlink.onclick = function () { (document.body || document.documentElement).removeChild(hyperlink); // required for Firefox window.URL.revokeObjectURL(hyperlink.href); }; var mouseEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); hyperlink.dispatchEvent(mouseEvent); } function getURL(arg) { var url = arg; if (arg instanceof Blob || arg instanceof File) { url = URL.createObjectURL(arg); } if (arg instanceof RecordRTC || arg.getBlob) { url = URL.createObjectURL(arg.getBlob()); } if (arg instanceof MediaStream || arg.getTracks) { // url = URL.createObjectURL(arg); } return url; } function setVideoURL(arg, forceNonImage) { var url = getURL(arg); var parentNode = recordingPlayer.parentNode; parentNode.removeChild(recordingPlayer); parentNode.innerHTML = ''; var elem = 'video'; if (type == 'gif' && !forceNonImage) { elem = 'img'; } if (type == 'audio') { elem = 'audio'; } recordingPlayer = document.createElement(elem); if (arg instanceof MediaStream) { recordingPlayer.muted = true; } recordingPlayer.addEventListener('loadedmetadata', function () { if (navigator.userAgent.toLowerCase().indexOf('android') == -1) return; // android setTimeout(function () { if (typeof recordingPlayer.play === 'function') { recordingPlayer.play(); } }, 2000); }, false); recordingPlayer.poster = ''; if (arg instanceof MediaStream) { recordingPlayer.srcObject = arg; } else { recordingPlayer.src = url; } if (typeof recordingPlayer.play === 'function') { recordingPlayer.play(); } recordingPlayer.addEventListener('ended', function () { url = getURL(arg); if (arg instanceof MediaStream) { recordingPlayer.srcObject = arg; } else { recordingPlayer.src = url; } }); parentNode.appendChild(recordingPlayer); } function captureScreen(config) { if (navigator.getDisplayMedia) { navigator.getDisplayMedia({ video: true }).then(screenStream => { config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia({ video: true }).then(screenStream => { config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else { var error = 'getDisplayMedia API are not supported in this browser.'; config.onMediaCapturingFailed(error); alert(error); } } function captureAudioPlusScreen(config) { if (navigator.getDisplayMedia) { navigator.getDisplayMedia({ video: true }).then(screenStream => { navigator.mediaDevices.getUserMedia({ audio: true }).then(function (mic) { screenStream.addTrack(mic.getTracks()[0]); config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia({ video: true }).then(screenStream => { navigator.mediaDevices.getUserMedia({ audio: true }).then(function (mic) { screenStream.addTrack(mic.getTracks()[0]); config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else { var error = 'getDisplayMedia API are not supported in this browser.'; config.onMediaCapturingFailed(error); alert(error); } } /* upload_youtube_video.js Copyright 2017 Google Inc. All Rights Reserved. */ function uploadToYouTube(fileName, recordRTC, callback) { var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.getBlob(); blob = new File([blob], getFileName(fileExtension), { type: mimeType }); if (!uploadVideo) { alert('YouTube API are not available.'); return; } uploadVideo.callback = callback; uploadVideo.uploadFile(fileName, blob); } var uploadVideo; var signinCallback = function (result) { if (result.access_token) { uploadVideo = new UploadVideo(); uploadVideo.ready(result.access_token); } else { // console.error('YouTube error', result); // document.querySelector('#upload-to-youtube').style.display = 'none'; } }; var STATUS_POLLING_INTERVAL_MILLIS = 60 * 1000; // One minute. var UploadVideo = function () { this.tags = ['recordrtc']; this.categoryId = 28; // via: http://stackoverflow.com/a/35877512/552182 this.videoId = ''; this.uploadStartTime = 0; }; UploadVideo.prototype.ready = function (accessToken) { this.accessToken = accessToken; this.gapi = gapi; this.authenticated = true; false && this.gapi.client.request({ path: '/youtube/v3/channels', params: { part: 'snippet', mine: true }, callback: function (response) { if (!response.error) { // response.items[0].snippet.title -- channel title // response.items[0].snippet.thumbnails.default.url -- channel thumbnail } }.bind(this) }); }; UploadVideo.prototype.uploadFile = function (fileName, file) { var metadata = { snippet: { title: fileName, description: fileName, tags: this.tags, categoryId: this.categoryId }, status: { privacyStatus: 'public' } }; var uploader = new MediaUploader({ baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos', file: file, token: this.accessToken, metadata: metadata, params: { part: Object.keys(metadata).join(',') }, onError: function (data) { var message = data; try { var errorResponse = JSON.parse(data); message = errorResponse.error.message; } finally { alert(message); } }.bind(this), onProgress: function (data) { var bytesUploaded = data.loaded; var totalBytes = parseInt(data.total); var percentageComplete = parseInt((bytesUploaded * 100) / totalBytes); uploadVideo.callback(percentageComplete); }.bind(this), onComplete: function (data) { var uploadResponse = JSON.parse(data); this.videoId = uploadResponse.id; this.videoURL = 'https://www.youtube.com/watch?v=' + this.videoId; uploadVideo.callback('uploaded', this.videoURL); setTimeout(this.pollForVideoStatus, 2000); }.bind(this) }); this.uploadStartTime = Date.now(); uploader.upload(); }; UploadVideo.prototype.pollForVideoStatus = function () { this.gapi.client.request({ path: '/youtube/v3/videos', params: { part: 'status,player', id: this.videoId }, callback: function (response) { if (response.error) { uploadVideo.pollForVideoStatus(); } else { var uploadStatus = response.items[0].status.uploadStatus; switch (uploadStatus) { case 'uploaded': uploadVideo.callback('uploaded', uploadVideo.videoURL); uploadVideo.pollForVideoStatus(); break; case 'processed': uploadVideo.callback('processed', uploadVideo.videoURL); break; default: uploadVideo.callback('failed', uploadVideo.videoURL); break; } } }.bind(this) }); }; /* cors_upload.js Copyright 2015 Google Inc. All Rights Reserved. */ var DRIVE_UPLOAD_URL = 'https://www.googleapis.com/upload/drive/v2/files/'; var RetryHandler = function () { this.interval = 1000; // Start at one second this.maxInterval = 60 * 1000; // Don't wait longer than a minute }; RetryHandler.prototype.retry = function (fn) { setTimeout(fn, this.interval); this.interval = this.nextInterval_(); }; RetryHandler.prototype.reset = function () { this.interval = 1000; }; RetryHandler.prototype.nextInterval_ = function () { var interval = this.interval * 2 + this.getRandomInt_(0, 1000); return Math.min(interval, this.maxInterval); }; RetryHandler.prototype.getRandomInt_ = function (min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }; var MediaUploader = function (options) { var noop = function () {}; this.file = options.file; this.contentType = options.contentType || this.file.type || 'application/octet-stream'; this.metadata = options.metadata || { 'title': this.file.name, 'mimeType': this.contentType }; this.token = options.token; this.onComplete = options.onComplete || noop; this.onProgress = options.onProgress || noop; this.onError = options.onError || noop; this.offset = options.offset || 0; this.chunkSize = options.chunkSize || 0; this.retryHandler = new RetryHandler(); this.url = options.url; if (!this.url) { var params = options.params || {}; params.uploadType = 'resumable'; this.url = this.buildUrl_(options.fileId, params, options.baseUrl); } this.httpMethod = options.fileId ? 'PUT' : 'POST'; }; MediaUploader.prototype.upload = function () { var self = this; var xhr = new XMLHttpRequest(); xhr.open(this.httpMethod, this.url, true); xhr.setRequestHeader('Authorization', 'Bearer ' + this.token); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.setRequestHeader('X-Upload-Content-Length', this.file.size); xhr.setRequestHeader('X-Upload-Content-Type', this.contentType); xhr.onload = function (e) { if (e.target.status < 400) { var location = e.target.getResponseHeader('Location'); this.url = location; this.sendFile_(); } else { this.onUploadError_(e); } }.bind(this); xhr.onerror = this.onUploadError_.bind(this); xhr.send(JSON.stringify(this.metadata)); }; MediaUploader.prototype.sendFile_ = function () { var content = this.file; var end = this.file.size; if (this.offset || this.chunkSize) { // Only bother to slice the file if we're either resuming or uploading in chunks if (this.chunkSize) { end = Math.min(this.offset + this.chunkSize, this.file.size); } content = content.slice(this.offset, end); } var xhr = new XMLHttpRequest(); xhr.open('PUT', this.url, true); xhr.setRequestHeader('Content-Type', this.contentType); xhr.setRequestHeader('Content-Range', 'bytes ' + this.offset + '-' + (end - 1) + '/' + this.file.size); xhr.setRequestHeader('X-Upload-Content-Type', this.file.type); if (xhr.upload) { xhr.upload.addEventListener('progress', this.onProgress); } xhr.onload = this.onContentUploadSuccess_.bind(this); xhr.onerror = this.onContentUploadError_.bind(this); xhr.send(content); }; MediaUploader.prototype.resume_ = function () { var xhr = new XMLHttpRequest(); xhr.open('PUT', this.url, true); xhr.setRequestHeader('Content-Range', 'bytes */' + this.file.size); xhr.setRequestHeader('X-Upload-Content-Type', this.file.type); if (xhr.upload) { xhr.upload.addEventListener('progress', this.onProgress); } xhr.onload = this.onContentUploadSuccess_.bind(this); xhr.onerror = this.onContentUploadError_.bind(this); xhr.send(); }; MediaUploader.prototype.extractRange_ = function (xhr) { var range = xhr.getResponseHeader('Range'); if (range) { this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1; } }; MediaUploader.prototype.onContentUploadSuccess_ = function (e) { if (e.target.status == 200 || e.target.status == 201) { this.onComplete(e.target.response); } else if (e.target.status == 308) { this.extractRange_(e.target); this.retryHandler.reset(); this.sendFile_(); } }; MediaUploader.prototype.onContentUploadError_ = function (e) { if (e.target.status && e.target.status < 500) { this.onError(e.target.response); } else { this.retryHandler.retry(this.resume_.bind(this)); } }; MediaUploader.prototype.onUploadError_ = function (e) { this.onError(e.target.response); // TODO - Retries for initial upload }; MediaUploader.prototype.buildQuery_ = function (params) { params = params || {}; return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); }).join('&'); }; MediaUploader.prototype.buildUrl_ = function (id, params, baseUrl) { var url = baseUrl || DRIVE_UPLOAD_URL; if (id) { url += id; } var query = this.buildQuery_(params); if (query) { url += '?' + query; } return url; }; var chkFixSeeking = document.querySelector('#chk-fixSeeking'); chkFixSeeking.onchange = function () { if (this.checked === true) { localStorage.setItem(this.id, 'true'); } else { localStorage.removeItem(this.id); } }; if (localStorage.getItem(chkFixSeeking.id) === 'true') { chkFixSeeking.checked = true; } var chkTimeSlice = document.querySelector('#chk-timeSlice'); var timeSlice = false; if (typeof MediaRecorder === 'undefined') { chkTimeSlice.disabled = true; } chkTimeSlice.addEventListener('change', function () { if (chkTimeSlice.checked === true) { var _timeSlice = prompt('Please enter timeSlice in milliseconds e.g. 1000 or 2000 or 3000.', 1000); _timeSlice = parseInt(_timeSlice); if (!_timeSlice || _timeSlice == NaN || typeof _timeSlice === 'undefined') { timeSlice = false; return; } timeSlice = _timeSlice; } else { timeSlice = false; } }, false); var btnPauseRecording = document.querySelector('#btn-pause-recording'); btnPauseRecording.onclick = function () { if (!btnStartRecording.recordRTC) { btnPauseRecording.style.display = 'none'; return; } btnPauseRecording.disabled = true; if (btnPauseRecording.innerHTML === 'Pause') { btnStartRecording.disabled = true; chkFixSeeking.parentNode.style.display = 'none'; btnStartRecording.style.fontSize = '12px'; btnStartRecording.recordRTC.pauseRecording(); recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = 'Recording status: paused'; recordingPlayer.pause(); btnPauseRecording.style.fontSize = '12px'; setTimeout(function () { btnPauseRecording.innerHTML = 'Resume Recording'; btnPauseRecording.disabled = false; }, 2000); } if (btnPauseRecording.innerHTML === 'Resume Recording') { btnStartRecording.disabled = false; chkFixSeeking.parentNode.style.display = 'none'; btnStartRecording.style.fontSize = '12px'; btnStartRecording.recordRTC.resumeRecording(); recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = 'Recording status: active'; recordingPlayer.play(); btnPauseRecording.style.fontSize = '12px'; btnPauseRecording.innerHTML = 'Pause'; setTimeout(function () { btnPauseRecording.disabled = false; }, 2000); } }; // getHTMLMediaElement.js function getHTMLMediaElement(mediaElement, config) { config = config || {}; if (!mediaElement.nodeName || (mediaElement.nodeName.toLowerCase() != 'audio' && mediaElement.nodeName.toLowerCase() != 'video')) { if (!mediaElement.getVideoTracks().length) { return getAudioElement(mediaElement, config); } var mediaStream = mediaElement; mediaElement = document.createElement(mediaStream.getVideoTracks().length ? 'video' : 'audio'); if ('srcObject' in mediaElement) { mediaElement.srcObject = mediaStream; } else { mediaElement[!!navigator.mozGetUserMedia ? 'mozSrcObject' : 'src'] = !!navigator.mozGetUserMedia ? mediaStream : window.webkitURL.createObjectURL(mediaStream); } } if (mediaElement.nodeName && mediaElement.nodeName.toLowerCase() == 'audio') { return getAudioElement(mediaElement, config); } mediaElement.controls = false; var buttons = config.buttons || ['mute-audio', 'mute-video', 'full-screen', 'volume-slider', 'stop']; buttons.has = function (element) { return buttons.indexOf(element) !== -1; }; config.toggle = config.toggle || []; config.toggle.has = function (element) { return config.toggle.indexOf(element) !== -1; }; var mediaElementContainer = document.createElement('div'); mediaElementContainer.className = 'media-container'; var mediaControls = document.createElement('div'); mediaControls.className = 'media-controls'; mediaElementContainer.appendChild(mediaControls); if (buttons.has('mute-audio')) { var muteAudio = document.createElement('div'); muteAudio.className = 'control ' + (config.toggle.has('mute-audio') ? 'unmute-audio selected' : 'mute-audio'); mediaControls.appendChild(muteAudio); muteAudio.onclick = function () { if (muteAudio.className.indexOf('unmute-audio') != -1) { muteAudio.className = muteAudio.className.replace('unmute-audio selected', 'mute-audio'); mediaElement.muted = false; mediaElement.volume = 1; if (config.onUnMuted) config.onUnMuted('audio'); } else { muteAudio.className = muteAudio.className.replace('mute-audio', 'unmute-audio selected'); mediaElement.muted = true; mediaElement.volume = 0; if (config.onMuted) config.onMuted('audio'); } }; } if (buttons.has('mute-video')) { var muteVideo = document.createElement('div'); muteVideo.className = 'control ' + (config.toggle.has('mute-video') ? 'unmute-video selected' : 'mute-video'); mediaControls.appendChild(muteVideo); muteVideo.onclick = function () { if (muteVideo.className.indexOf('unmute-video') != -1) { muteVideo.className = muteVideo.className.replace('unmute-video selected', 'mute-video'); mediaElement.muted = false; mediaElement.volume = 1; mediaElement.play(); if (config.onUnMuted) config.onUnMuted('video'); } else { muteVideo.className = muteVideo.className.replace('mute-video', 'unmute-video selected'); mediaElement.muted = true; mediaElement.volume = 0; mediaElement.pause(); if (config.onMuted) config.onMuted('video'); } }; } if (buttons.has('take-snapshot')) { var takeSnapshot = document.createElement('div'); takeSnapshot.className = 'control take-snapshot'; mediaControls.appendChild(takeSnapshot); takeSnapshot.onclick = function () { if (config.onTakeSnapshot) config.onTakeSnapshot(); }; } if (buttons.has('stop')) { var stop = document.createElement('div'); stop.className = 'control stop'; mediaControls.appendChild(stop); stop.onclick = function () { mediaElementContainer.style.opacity = 0; setTimeout(function () { if (mediaElementContainer.parentNode) { mediaElementContainer.parentNode.removeChild(mediaElementContainer); } }, 800); if (config.onStopped) config.onStopped(); }; } var volumeControl = document.createElement('div'); volumeControl.className = 'volume-control'; if (buttons.has('record-audio')) { var recordAudio = document.createElement('div'); recordAudio.className = 'control ' + (config.toggle.has('record-audio') ? 'stop-recording-audio selected' : 'record-audio'); volumeControl.appendChild(recordAudio); recordAudio.onclick = function () { if (recordAudio.className.indexOf('stop-recording-audio') != -1) { recordAudio.className = recordAudio.className.replace('stop-recording-audio selected', 'record-audio'); if (config.onRecordingStopped) config.onRecordingStopped('audio'); } else { recordAudio.className = recordAudio.className.replace('record-audio', 'stop-recording-audio selected'); if (config.onRecordingStarted) config.onRecordingStarted('audio'); } }; } if (buttons.has('record-video')) { var recordVideo = document.createElement('div'); recordVideo.className = 'control ' + (config.toggle.has('record-video') ? 'stop-recording-video selected' : 'record-video'); volumeControl.appendChild(recordVideo); recordVideo.onclick = function () { if (recordVideo.className.indexOf('stop-recording-video') != -1) { recordVideo.className = recordVideo.className.replace('stop-recording-video selected', 'record-video'); if (config.onRecordingStopped) config.onRecordingStopped('video'); } else { recordVideo.className = recordVideo.className.replace('record-video', 'stop-recording-video selected'); if (config.onRecordingStarted) config.onRecordingStarted('video'); } }; } if (buttons.has('volume-slider')) { var volumeSlider = document.createElement('div'); volumeSlider.className = 'control volume-slider'; volumeControl.appendChild(volumeSlider); var slider = document.createElement('input'); slider.type = 'range'; slider.min = 0; slider.max = 100; slider.value = 100; slider.onchange = function () { mediaElement.volume = '.' + slider.value.toString().substr(0, 1); }; volumeSlider.appendChild(slider); } if (buttons.has('full-screen')) { var zoom = document.createElement('div'); zoom.className = 'control ' + (config.toggle.has('zoom-in') ? 'zoom-out selected' : 'zoom-in'); if (!slider && !recordAudio && !recordVideo && zoom) { mediaControls.insertBefore(zoom, mediaControls.firstChild); } else volumeControl.appendChild(zoom); zoom.onclick = function () { if (zoom.className.indexOf('zoom-out') != -1) { zoom.className = zoom.className.replace('zoom-out selected', 'zoom-in'); exitFullScreen(); } else { zoom.className = zoom.className.replace('zoom-in', 'zoom-out selected'); launchFullscreen(mediaElementContainer); } }; function launchFullscreen(element) { if (element.requestFullscreen) { element.requestFullscreen(); } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); } } function exitFullScreen() { if (document.fullscreen) { document.cancelFullScreen(); } if (document.mozFullScreen) { document.mozCancelFullScreen(); } if (document.webkitIsFullScreen) { document.webkitCancelFullScreen(); } } function screenStateChange(e) { if (e.srcElement != mediaElementContainer) return; var isFullScreeMode = document.webkitIsFullScreen || document.mozFullScreen || document.fullscreen; mediaElementContainer.style.width = (isFullScreeMode ? (window.innerWidth - 20) : config.width) + 'px'; mediaElementContainer.style.display = isFullScreeMode ? 'block' : 'inline-block'; if (config.height) { mediaBox.style.height = (isFullScreeMode ? (window.innerHeight - 20) : config.height) + 'px'; } if (!isFullScreeMode && config.onZoomout) config.onZoomout(); if (isFullScreeMode && config.onZoomin) config.onZoomin(); if (!isFullScreeMode && zoom.className.indexOf('zoom-out') != -1) { zoom.className = zoom.className.replace('zoom-out selected', 'zoom-in'); if (config.onZoomout) config.onZoomout(); } setTimeout(adjustControls, 1000); } document.addEventListener('fullscreenchange', screenStateChange, false); document.addEventListener('mozfullscreenchange', screenStateChange, false); document.addEventListener('webkitfullscreenchange', screenStateChange, false); } if (buttons.has('volume-slider') || buttons.has('full-screen') || buttons.has('record-audio') || buttons.has('record-video')) { mediaElementContainer.appendChild(volumeControl); } var mediaBox = document.createElement('div'); mediaBox.className = 'media-box'; mediaElementContainer.appendChild(mediaBox); if (config.title) { var h2 = document.createElement('h2'); h2.innerHTML = config.title; h2.setAttribute('style', 'position: absolute;color:white;font-size:12px;text-shadow: 1px 1px black;padding:0;margin:0;text-align: left; margin-top: 10px; margin-left: 10px; display: block; border: 0;line-height:1.5;z-index:1;'); h2.setAttribute('id', 'recording-status'); mediaBox.appendChild(h2); } mediaBox.appendChild(mediaElement); if (!config.width) config.width = (innerWidth / 2) - 50; mediaElementContainer.style.width = config.width + 'px'; if (config.height) { mediaBox.style.height = config.height + 'px'; } mediaBox.querySelector('video').style.maxHeight = innerHeight + 'px'; var times = 0; function adjustControls() { mediaControls.style.marginLeft = (mediaElementContainer.clientWidth - mediaControls.clientWidth - 2) + 'px'; if (slider) { slider.style.width = (mediaElementContainer.clientWidth / 3) + 'px'; volumeControl.style.marginLeft = (mediaElementContainer.clientWidth / 3 - 30) + 'px'; if (zoom) zoom.style['border-top-right-radius'] = '5px'; } else { volumeControl.style.marginLeft = (mediaElementContainer.clientWidth - volumeControl.clientWidth - 2) + 'px'; } volumeControl.style.marginTop = (mediaElementContainer.clientHeight - volumeControl.clientHeight - 2) + 'px'; if (times < 10) { times++; setTimeout(adjustControls, 1000); } else times = 0; } if (config.showOnMouseEnter || typeof config.showOnMouseEnter === 'undefined') { mediaElementContainer.onmouseenter = mediaElementContainer.onmousedown = function () { adjustControls(); mediaControls.style.opacity = 1; volumeControl.style.opacity = 1; }; mediaElementContainer.onmouseleave = function () { mediaControls.style.opacity = 0; volumeControl.style.opacity = 0; }; } else { setTimeout(function () { adjustControls(); setTimeout(function () { mediaControls.style.opacity = 1; volumeControl.style.opacity = 1; }, 300); }, 700); } adjustControls(); mediaElementContainer.toggle = function (clasName) { if (typeof clasName != 'string') { for (var i = 0; i < clasName.length; i++) { mediaElementContainer.toggle(clasName[i]); } return; } if (clasName == 'mute-audio' && muteAudio) muteAudio.onclick(); if (clasName == 'mute-video' && muteVideo) muteVideo.onclick(); if (clasName == 'record-audio' && recordAudio) recordAudio.onclick(); if (clasName == 'record-video' && recordVideo) recordVideo.onclick(); if (clasName == 'stop' && stop) stop.onclick(); return this; }; mediaElementContainer.media = mediaElement; return mediaElementContainer; } // ==/UserScript== //Creer un bouton pour record // Create a new element /* $('div#myvideo').show(); // $('button').on('click',function(){ $('div#myvideo').on('click', function() { $(this).css("max-width","100%"); //event.stopPropagation(); //$('div#modal').toggle(); //$('div#modal').hide(); });*/ ////////////switchcamera///////////////////// // add button for switch var button_switchCam = document.createElement('div'); button_switchCam.innerHTML = '<button id="switchbtn" class="btn btn-primary" type="button">Switch Camera</button>'; //button_switchCam.setAttribute('z-index', '120'); //button_switchCam.setAttribute('position', 'absolute'); //button_switchCam.setAttribute('left', '50%'); //button_switchCam.style.width = 'fit-content'; var position3 = document.querySelector('.wrapper-sm'); position3.after(button_switchCam); var savechange = document.getElementById('switchbtn').addEventListener('click', function (poswitch) { postionCamID1('myvideo'); postionCamID2('remotevideo'); postionCamID2Position('remotevideo'); postionCamID2Position2('remotevideo'); postionCamID2Position1('myvideo'); }); // add fucntion postion camera function postionCamID1(id) { if (document.getElementById(id).style.left == '100%') document.getElementById(id).style.left = '0px'; else document.getElementById(id).style.left = '100%' } function postionCamID2(id) { if (document.getElementById(id).style.right == '100%') document.getElementById(id).style.right = '0%'; else document.getElementById(id).style.right = '100%' } /* function postionCamID1Position(id){ if(document.getElementById(id).style.position == 'fixed') document.getElementById(id).style.position = 'relative'; else document.getElementById(id).style.position = 'fixed' } function postionCamID2Position(id){ if(document.getElementById(id).style.position == 'fixed') document.getElementById(id).style.position = 'relative'; else document.getElementById(id).style.position = 'fixed' }*/ function postionCamID2Position2(id) { if (document.getElementById(id).style.width == '50%') document.getElementById(id).style.width = '100%'; else document.getElementById(id).style.width = '50%' } //addGlobalStyle('#myvideo{ float:left;left:0px;height: auto;'); //addGlobalStyle('#remotevideo { float:right; right:0px; height:auto;}'); ////////////END switch camera ///////////////////// ////////////switchcamera///////////////////// // add button for switch var button_hideMyCam = document.createElement('div'); button_hideMyCam.innerHTML = '<button id="hidecambtn" class="btn btn-primary" type="button">Hide My Camera</button>'; //button_hideMyCam.setAttribute('z-index', '120'); //button_hideMyCam.setAttribute('position', 'absolute'); //button_hideMyCam.setAttribute('left', '50%'); //button_hideMyCam.style.width = 'fit-content'; var position4 = document.querySelector('.wrapper-sm'); position4.after(button_hideMyCam); var saveHideCam = document.getElementById('hidecambtn').addEventListener('click', function () { positionMyVideo('myvideo'); positionRemoteVideo('remotevideo'); }); // add fucntion postion camera function positionMyVideo(id) { if (document.getElementById(id).style.width == '100%') document.getElementById(id).style.width = '50%'; else document.getElementById(id).style.width = '100%' } function positionRemoteVideo(id) { if (document.getElementById(id).style.width == '100vh') document.getElementById(id).style.width = ''; else document.getElementById(id).style.width = '100vh' } // add button for full var button_fullScreen = document.createElement('div'); button_fullScreen.innerHTML = '<button id="button_fullScreen" class="btn btn-primary" type="button_fullScreen">Fullsrceen</button>'; //button_fullScreen.setAttribute('z-index', '120'); //button_fullScreen.setAttribute('position', 'absolute'); //button_fullScreen.setAttribute('left', '50%'); //button_fullScreen.style.width = 'fit-content'; var position5 = document.querySelector('.wrapper-sm'); position5.after(button_fullScreen); var gofull = document.getElementById('button_fullScreen').addEventListener('click', function () { fullscreen(button_fullScreen); }); let fullscreen = function () { let enter = function () { let body = document.body; if (body.requestFullscreen) body.requestFullscreen(); else if (body.webkitRequestFullscreen) body.webkitRequestFullscreen(); else if (body.mozRequestFullScreen) body.mozRequestFullScreen(); else if (body.msRequestFullscreen) body.msRequestFullscreen(); }; let exit = function () { if (document.exitFullscreen) document.exitFullscreen(); else if (document.webkitExitFullscreen) document.webkitExitFullscreen(); else if (document.mozCancelFullScreen) document.mozCancelFullScreen(); else if (document.msExitFullscreen) document.msExitFullscreen(); }; let attemptToGetState = element => element && element !== null; return function (action = undefined) { if (action === true) enter(); else if (action === false) exit(); else { let currentlyFullscreen = ( attemptToGetState(document.fullscreenElement) || attemptToGetState(document.webkitFullscreenElement) || attemptToGetState(document.mozFullScreenElement) || attemptToGetState(document.msFullscreenElement) ); if (action === undefined) return !!currentlyFullscreen; else currentlyFullscreen ? exit() : enter(); } }; }(); /*function requestFullScreen(element) { // Supports most browsers and their versions. var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen; if (requestMethod) { // Native full screen. requestMethod.call(element); } else if (typeof window.ActiveXObject !== "undefined") { // Older IE. var wscript = new ActiveXObject("WScript.Shell"); if (wscript !== null) { wscript.SendKeys("{F11}"); } } } var elem = document.body; // Make the body go full screen. requestFullScreen(elem);*/ ////////////END switch camera ///////////////////// /*button_switchCam.onclick = function postionCamID1(id){ if(document.getElementById(id).style.left == '0px') document.getElementById(id).style.right = '0px'; else document.getElementById(id).style.left = '0px' function postionCamID2(id){ if(document.getElementById(id).style.right == '0px') document.getElementById(id).style.left = '0px'; else document.getElementById(id).style.right = '0px' } }; */ ////////////END switch camera ///////////////////// (function () { 'use strict'; function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div:nth-child(3) > div:nth-child(2) > div > div.ng-hide {width: 50%;right: 0;top: 177px;position: fixed;padding:0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div.col-xs-12.col-sm-12.col-md-8.col-lg-8.bg-black.dker.max.text-center.ng-hide > div {width: 50%;left: 0;top: 177px;position: fixed;padding:0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div:nth-child(3) > div:nth-child(2) > div > div:nth-child(2){width: 50%;left: 0;top: 177px;position: fixed;padding:0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(4){width: 50%;right: 0;top: 177px;position: fixed;padding:0;}'); addGlobalStyle('#content > div {padding:0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope {height: 15%; background:white}'); addGlobalStyle(' #content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div {position: fixed;top:0px;height:177px;}'); addGlobalStyle('.row {margin-right: 0;margin-left: 0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) {padding:0px;}'); ///////Nom player addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div.h4,{background-color: #B90014;color: #FFF;width: 100%;height: 25%;position: relative;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div.h4 > div > div > div.h4{background-color: #B90014;color: #FFF;width: 100%;height: 25%;position: relative;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div.h1.font-bold.text-scores{height: 75%; position: relative; width: 100%;background:#131e26}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div.h1.font-bold.text-scores{ background-color: #FFF;height: 75%; position: relative; width: 100%;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div.h4, #content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div.h4 {background-color: #B90014;color: #FFF;width: 100%;height: 25%;position: relative;}'); addGlobalStyle('.wrapper-sm, #content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker,#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div{ padding:0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(2), .bg-black ,.dker, .bg-black.dker{ background-color:#ffffff00;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div, #content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player,{position: fixed;right: 0px;width: 40%;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div, #content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1){ padding:0;}'); //active player addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player,#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div{padding:0;float:left;display: block;position: relative;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div.h1.font-bold.text-scores{background: #131e26;}'); addGlobalStyle('{ background: #131e26;}'); addGlobalStyle('#error-container > div {width: 30%;left: 35%;position: relative;}'); addGlobalStyle('.btn { font-size: 12px; padding: 5px;}'); //////////Video position addGlobalStyle('button#switchbtn { position:fixed;bottom: 4px ;float: right;right: 120px;}'); addGlobalStyle('button#hidecambtn { position:fixed;bottom: 4px ;float: right;right: 210px;}'); addGlobalStyle('button#button_fullScreen { position:fixed;bottom: 4px ;float: right;right: 306px;}'); addGlobalStyle('button#button_fullScreen:hover { position:fixed;bottom: 4px ;float: right;right: 306px;}'); addGlobalStyle('#myvideo{position:relative; float:none;left:0px;height:auto;width:50%;}'); addGlobalStyle('#remotevideo {position:relative; float:right; right:0px; height:auto;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div:nth-child(3) > div:nth-child(2){width: 50%;top: 17%;position: fixed;left: 0;padding: 0;}'); addGlobalStyle('div.col-xs-7.col-sm-7.col-md-7.col-lg-7, div.col-xs-5.col-sm-5.col-md-5.col-lg-5 ,div.col-xs-2.col-sm-2.col-md-2.col-lg-2, div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player, div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player{color: #FFF;font-size: larger;font-weight: 400;line-height: 23px;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div.h1.font-bold.text-scores > span{ color: #7793a7;z-index: 2;position: relative;}'); ////////////////////historique///////////////// addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select{color:#dcddde;background-color:#131e26}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select > option{height:30px;color:#000;display: inline-table;padding-right: 5px;padding-left: 5px;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select > option{height:30px;color:#FFF;display: inline-table;padding-right: 5px;padding-left: 5px;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select > option{color:#FFF;display: inline-table;padding-right: 5px;padding-left: 5px;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select > option{color:#000;display: inline-table;padding-right: 5px;padding-left: 5px;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select,#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select,#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select,#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select{height:30px;overflow:hidden; cursor: grabbing;}'); addGlobalStyle('div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select,div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select { padding: 0px 1px; height:120px; display:block;border: 1px solid var(--baseFg);overflow: hidden;font-size: 1.5em;background-color:var(--baseBg);}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker{padding:0;width: 50%;position:fixed; right:0;height:30px;display: contents;bottom:40px;color:#000;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div {padding:0; right:0;height:30px;z-index:0;color:#000; background-color: #dcddde; }'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5{padding:0;width: 50%;position:fixed; height:30px;display: contents;bottom:40px;color:#000;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div{padding:0;width: 50%;position:fixed; left:0;;height:30px;display: contents;bottom:40px;color:#000;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5{padding:0;display: contents; left:0;color:#FFF;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select {color: red;height: 30px;overflow: hidden;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select:-internal-list-box {background:#FFF;}'); addGlobalStyle('#div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select, div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select{display: block;font-size:1.2em;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-2.col-sm-2.col-md-2.col-lg-2 > div > div:nth-child(1){display:none}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-2.col-sm-2.col-md-2.col-lg-2 > div > div.h4 {display:none}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-2.col-sm-2.col-md-2.col-lg-2 > div > div.h3.font-bold.wrapper-sm{display:none}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-2.col-sm-2.col-md-2.col-lg-2 > div > div.h3.font-bold.wrapper-sm{display:none}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-2.col-sm-2.col-md-2.col-lg-2 > div > div.h1.font-bold.text-scores{display:none}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div:nth-child(1){float:left;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div.wrapper-sm{display:flex}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div.wrapper-sm > button {top: 147px;position: fixed;right:50%;margin-right:5px;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div > div:nth-child(2) > button:nth-child(2){top: 147px; position: fixed;right:50%;margin-right:5px;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div > div:nth-child(2) > button:nth-child(2){top: 147px; position: fixed;right:50%;margin-right:66px;}'); addGlobalStyle('input#correctscore {top: 147px;position: fixed;width:60px;left:50%;height: 29px; padding: 0;text-align: center;}'); addGlobalStyle('input#enterdarts {top: 147px;position: fixed;width:60px;left:50%;height: 29px; padding: 0;text-align: center;font-weight: bolder; font-size: xx-large;}'); addGlobalStyle('input#enterscore {top: 147px;position: fixed;width:60px;height:29px;left:50%; padding: 0;text-align: center;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player,#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player {border: 2px solid #B90013; border-bottom-right-radius: 3px;padding: 2px;background: #B90013;border-bottom-left-radius: 3px;}'); //active player color addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div.h4{background-color:#B90014; color:#FFF;z-index:2;position:relative;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div.h1.font-bold.text-scores > span {color:#000;z-index:2;position:relative;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div.h4, #content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div.h4{background-color:#B90014; color:#FFF;text-transform: uppercase;z-index:2;position:relative;}'); //opponent player color addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div.h4{background-color:#B90014; color:#FFF;z-index:2;position:relative;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div.h1.font-bold.text-scores > span{color:#000;z-index:2;position:relative;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div.h1.font-bold.text-scores{background-color:#FFF;position:relative;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) {background-color: transparent;}'); //addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div:nth-child(1) > img{position:relative;top:0px;right:50%;width:75px;height:75px;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div:nth-child(1) > img, #content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div:nth-child(1) > img{position:relative;top:14px;right:0;width:revert;height:71%;z-index:1;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div:nth-child(1),#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div:nth-child(1) {position: absolute;top: 0px;left: 0%;width:fit-content;height: 100%;background: transparent;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div:nth-child(1) {position: absolute;top: 0px;right: 0%;width:fit-content;height: 100%;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div:nth-child(1) > img{text-align:left;position:relative;top:14px;left:0;width:revert;height:71%;z-index:1;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(2) > div.col-xs-7.col-sm-7.col-md-7.col-lg-7.bg-black.dker{text-align:left;top:0px;position: fixed;top: 0px;float: right;right: 44%;width:fit-content;padding:0 0 0 0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div.col-xs-7.col-sm-7.col-md-7.col-lg-7{text-align:right;top:0px;position: fixed;top: 0px;float: left;left: 44%;width:fit-content;padding:0 0 0 0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(2) > div.col-xs-7.col-sm-7.col-md-7.col-lg-7.bg-black.dker{text-align:left;top:0px;position: fixed;top: 0px;float: right;right: 44%;width:fit-content;padding:0 0 0 0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-7.col-sm-7.col-md-7.col-lg-7{text-align:right;top:0px;position: fixed;top: 0px;float: right;right: 44%;width:fit-content;padding:0 0 0 0;}'); //addGlobalStyle('.max { height: unset; width:unset}'); addGlobalStyle('.active-player{ border: none;}'); addGlobalStyle(' #content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div:nth-child(1), #content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div:nth-child(1) { position: absolute;top: 0px;left: 0%;width: fit-content;height: 100%; background:transparent;}'); addGlobalStyle(' #content > div > div > div > div:nth-child(1) > div.row.ng-scope > div {z-index:1;padding:0;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div{position:relative;}'); // checkout addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div.h3.font-bold.wrapper-sm > span{}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div.h3.font-bold.wrapper-smsm > span {}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div.h3.font-bold.wrapper-sm{background-color: #131E26; color:#FFF}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div.h3.font-bold.wrapper-sm > span{color:#B90013}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div.h3.font-bold.wrapper-sm > span{color:#B90013}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(1) > div > div > div.h3.font-bold.wrapper-sm{background: #131E26; background-color:#FFF}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div.h3.font-bold.wrapper-sm{color:#FFF;background-color: #FFF;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div > div > div.h3.font-bold.wrapper-sm {color:#FFF;background-color: #131E26;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(1) > div > div.h3.font-bold.wrapper-sm{color:FFF;background-color: #b90013;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(1) > div > div.h3.font-bold.wrapper-sm {}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div:nth-child(3) > div:nth-child(1) > div > div:nth-child(1) > button:hover{background-color:#000}'); addGlobalStyle('.btn-primary{background-color:#131e26;cursor:pointer;}'); //waiting turn addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div:nth-child(1) > div{margin-bottom:-20px;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1){padding:0px;}'); //Cancel addGlobalStyle('#content > div > div > div > div:nth-child(1) > div:nth-child(3){ display:block;width:fit-content;bottom:4px; position:fixed;right:0px;padding-left:0px}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div:nth-child(3) > div:nth-child(1){ float: right;padding-right:0px;padding-left:0px;width: fit-content;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div:nth-child(3) > div:nth-child(1) > div{padding:0px;}'); addGlobalStyle('#content > div > div > div.row.text-center.wrapper-sm > div:nth-child(1) > div:nth-child(3) > div:nth-child(1) > div > div:nth-child(1){ display:block;width:fit-content;bottom:4px; position:fixed;right:2px;padding-left:0px}'); addGlobalStyle('#correctscore,#enterscore{font-weight: bolder;font-size: xx-large;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(2) > div > div:nth-child(1) > div > div > div:nth-child(1) > div > span{margin-bottom:-20px;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5 > div > select{background:#FFF;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker.active-player > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select{background:#fff;}'); addGlobalStyle('#content > div > div > div > div:nth-child(1) > div.row.ng-scope > div > div:nth-child(1) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div:nth-child(2) > div.col-xs-5.col-sm-5.col-md-5.col-lg-5.bg-black.dker > div > select{color:#FFF;background:#131e26;font-size:1.2em;}'); })(); ////////////Record ///////////////////// (function () { 'use strict'; function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } addGlobalStyle('#start-stop{ position:fixed;bottom: 4px ;right:385px;}'); addGlobalStyle('#save-option{ position:fixed;bottom: 4px ;right:520px;}'); addGlobalStyle('#upload-to-php, #youtube, #recording-player > div.media-container > div.media-box > section > video{ display:none}'); addGlobalStyle('#recording-player > div.media-container > div.media-box > h2{bottom: 36px ;right:4px;}') addGlobalStyle('.recording-media, #content > div > div > div:nth-child(14) { display:none;}'); addGlobalStyle('#time-slice{ position:fixed;bottom: 36px ;right:392px;}'); addGlobalStyle('#video-status{position:fixed; bottom:36px; left;4px;}'); addGlobalStyle('#save-to-disk{ background-color:#d54248;}'); })(); (function () { 'use strict'; // add Selectmedia var Selectmedia = document.createElement('div'); Selectmedia.innerHTML = '<select class="recording-media">-<option value="record-screen">Full Screen</option><option value="record-audio-plus-video" style="display: none;">Microphone+Camera</option><option value="record-audio" style="display: none;">Microphone</option><option value="record-audio-plus-screen">Microphone+Screen</option></select>'; var posSelectmedia = document.querySelector('.wrapper-sm'); posSelectmedia.after(Selectmedia); // add Selectformat var Selectformat = document.createElement('div'); Selectformat.innerHTML = '<select class="media-container-format" style="display: none;"><option>default</option><option>vp8</option><option>vp9</option><option>h264</option><option>mkv</option><option disabled="">opus</option><option disabled="">ogg</option><option disabled="">pcm</option><option>gif</option><option>whammy</option><option>WebAssembly</option></select>'; var posSelectformat = document.querySelector('.wrapper-sm'); posSelectformat.after(Selectformat); // add Selecttimeslice var Selecttimeslice = document.createElement('div'); Selecttimeslice.innerHTML = '<div id="time-slice"><input type="checkbox" id="chk-timeSlice" style="margin:0;width:auto;opacity: 0.4;vertical-align: middle;" title="Use intervals based recording"><label for="chk-timeSlice" style="font-size: 12px;margin:0;width: auto;opacity: 0.4cursor: pointer;-webkit-user-select:none;user-select:none;" title="Use intervals based recording">Use timeSlice?</label></div>'; var posSelecttimeslice = document.querySelector('.wrapper-sm'); posSelecttimeslice.after(Selecttimeslice); // add Selectbitrates var Selectbitrates = document.createElement('div'); Selectbitrates.innerHTML = '<select class="media-bitrates" style="display: none;"><option value="default">Default bitrates</option><option value="8000000000">1 GB bps</option><option value="800000000">100 MB bps</option><option value="8000000">1 MB bps</option><option value="800000">100 KB bps</option><option value="8000">1 KB bps</option><option value="800">100 Bytes bps</option></select>'; var posSelectbitrates = document.querySelector('.wrapper-sm'); posSelectbitrates.after(Selectbitrates); // add Selectframerates var Selectframerates = document.createElement('div'); Selectframerates.innerHTML = '<select class="media-framerates" style="display: none;"><option value="default">Default framerates</option><option value="5">5 fps</option><option value="15">15 fps</option><option value="24">24 fps</option><option value="30">30 fps</option><option value="60">60 fps</option></select>'; var posSelectframerates = document.querySelector('.wrapper-sm'); posSelectframerates.after(Selectframerates); // add Selectresolutions var Selectresolutions = document.createElement('div'); Selectresolutions.innerHTML = '<select class="media-resolutions" style="display: none;"><option value="default">Default resolutions</option><option value="1920x1080">1080p</option><option value="1280x720">720p</option><option value="640x480">480p</option><option value="3840x2160">4K Ultra HD (3840x2160)</option></select>'; var posSelectresolutions = document.querySelector('.wrapper-sm'); posSelectresolutions.after(Selectresolutions); // add fixSeeking var fixSeeking = document.createElement('div'); fixSeeking.innerHTML = '<div style="display: none;"><input type="checkbox" id="chk-fixSeeking" style="margin:0;width:auto;" title="Fix video seeking issues?"><label for="chk-fixSeeking" style="font-size: 15px;margin:0;width: auto;cursor: pointer;-webkit-user-select:none;user-select:none;" title="Fix video seeking issues?">Fix Seeking Issues?</label></div>'; var posfixSeeking = document.querySelector('.wrapper-sm'); posfixSeeking.after(fixSeeking); // add button StartStop var StartStop = document.createElement('div'); StartStop.innerHTML = '<div id="start-stop"><button class="btn btn-primary" id="btn-start-recording" class="btn btn-primary"style="margin-right:3px;">Start Recording</button><button id="btn-pause-recording" class="btn btn-primary" style="display: none; ">Pause</button></div>'; var posStartStop = document.querySelector('.wrapper-sm'); posStartStop.after(StartStop); // add button Save record var buttonrecord = document.createElement('div'); buttonrecord.innerHTML = '<div id="save-option" style="text-align: center; display: none;"><button id="save-to-disk"class="btn btn-primary"style="margin-right:5px;">Save</button><button id="open-new-tab" class="btn btn-primary">Preview Video</button><button id="upload-to-php">Upload to PHP</button></div>'; var posbuttonrecord = document.querySelector('.wrapper-sm'); posbuttonrecord.after(buttonrecord); // add button to view video on screen var viewvideo = document.createElement('div'); viewvideo.innerHTML = '<div class="media-controls"></div><div class="control zoom-in"></div><div class="volume-control"></div><div id="recording-player"></div><div class="media-box"></div>'; var posviewvideo = document.querySelector('.wrapper-sm'); posviewvideo.after(viewvideo); // add button YouTube var buttonYouTube = document.createElement('div'); buttonYouTube.innerHTML = '<div id="youtube" style="margin-top: 10px;"><span id="signinButton" class="pre-sign-in"><spanclass="g-signin"data-callback="signinCallback"data-clientid="41556190767-115ifahd55lk4ln5pop4jus55cr4l7oh.apps.googleusercontent.com"data-cookiepolicy="single_host_origin"data-scope="https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtube"></span></span><button id="upload-to-youtube" style="vertical-align:top;">Upload to YouTube</button></div></div>'; var posbuttonYouTube = document.querySelector('.wrapper-sm'); posbuttonYouTube.after(buttonYouTube); // add divAutoplay var divAutoplay = document.createElement('div'); divAutoplay.innerHTML = '<section><video autoplay="" style="max-height: 880px;"></video></section>'; var posdivAutoplay = document.querySelector('.wrapper-sm'); posdivAutoplay.after(divAutoplay); // // /*// add button to view video on screen var videotime = document.createElement('div'); videotime.innerHTML = '<div id="video-status"><label>State preview: </label><h5 id="state-preview" style="color: red;">inactive</h5></div>'; var posvideotime = document.querySelector('.wrapper-sm'); posvideotime.after(videotime); */ })(); (function () { var params = {}, r = /([^&=]+)=?([^&]*)/g; function d(s) { return decodeURIComponent(s.replace(/\+/g, ' ')); } var match, search = window.location.search; while (match = r.exec(search.substring(1))) { params[d(match[1])] = d(match[2]); if (d(match[2]) === 'true' || d(match[2]) === 'false') { params[d(match[1])] = d(match[2]) === 'true' ? true : false; } } window.params = params; })(); function addStreamStopListener(stream, callback) { stream.addEventListener('ended', function () { callback(); callback = function () {}; }, false); stream.addEventListener('inactive', function () { callback(); callback = function () {}; }, false); stream.getTracks().forEach(function (track) { track.addEventListener('ended', function () { callback(); callback = function () {}; }, false); track.addEventListener('inactive', function () { callback(); callback = function () {}; }, false); }); } var video = document.createElement('video'); video.controls = false; var mediaElement = getHTMLMediaElement(video, { title: ' ', buttons: ['full-screen' /*, 'take-snapshot'*/ ], showOnMouseEnter: false, width: 360, onTakeSnapshot: function () { var canvas = document.createElement('canvas'); canvas.width = mediaElement.clientWidth; canvas.height = mediaElement.clientHeight; var context = canvas.getContext('2d'); context.drawImage(recordingPlayer, 0, 0, canvas.width, canvas.height); window.open(canvas.toDataURL('image/png')); } }); document.getElementById('recording-player').appendChild(mediaElement); var div = document.createElement('section'); mediaElement.media.parentNode.appendChild(div); mediaElement.media.muted = false; mediaElement.media.autoplay = true; mediaElement.media.playsinline = true; div.appendChild(mediaElement.media); var recordingPlayer = mediaElement.media; var recordingMedia = document.querySelector('.recording-media'); var mediaContainerFormat = document.querySelector('.media-container-format'); var mimeType = 'video/webm'; var fileExtension = 'webm'; var type = 'video'; var recorderType; var defaultWidth; var defaultHeight; var btnStartRecording = document.querySelector('#btn-start-recording'); window.onbeforeunload = function () { btnStartRecording.disabled = false; recordingMedia.disabled = false; mediaContainerFormat.disabled = false; chkFixSeeking.parentNode.style.display = 'inline-block'; }; btnStartRecording.onclick = function (event) { var button = btnStartRecording; if (button.innerHTML === 'Stop Recording') { btnPauseRecording.style.display = 'none'; button.disabled = true; button.disableStateWaiting = true; setTimeout(function () { button.disabled = false; button.disableStateWaiting = false; }, 2000); button.innerHTML = 'Start Recording'; function stopStream() { if (button.stream && button.stream.stop) { button.stream.stop(); button.stream = null; } if (button.stream instanceof Array) { button.stream.forEach(function (stream) { stream.stop(); }); button.stream = null; } videoBitsPerSecond = null; var html = 'Recording status: stopped - '; html += 'Size: ' + bytesToSize(button.recordRTC.getBlob().size); recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = html; } if (button.recordRTC) { if (button.recordRTC.length) { button.recordRTC[0].stopRecording(function (url) { if (!button.recordRTC[1]) { button.recordingEndedCallback(url); stopStream(); saveToDiskOrOpenNewTab(button.recordRTC[0]); return; } button.recordRTC[1].stopRecording(function (url) { button.recordingEndedCallback(url); stopStream(); }); }); } else { button.recordRTC.stopRecording(function (url) { if (button.blobs && button.blobs.length) { var blob = new File(button.blobs, getFileName(fileExtension), { type: mimeType }); button.recordRTC.getBlob = function () { return blob; }; url = URL.createObjectURL(blob); } if (chkFixSeeking.checked === true) { // to fix video seeking issues getSeekableBlob(button.recordRTC.getBlob(), function (seekableBlob) { button.recordRTC.getBlob = function () { return seekableBlob; }; url = URL.createObjectURL(seekableBlob); button.recordingEndedCallback(url); saveToDiskOrOpenNewTab(button.recordRTC); stopStream(); }) return; } button.recordingEndedCallback(url); saveToDiskOrOpenNewTab(button.recordRTC); stopStream(); }); } } return; } if (!event) return; button.disabled = true; var commonConfig = { onMediaCaptured: function (stream) { button.stream = stream; if (button.mediaCapturedCallback) { button.mediaCapturedCallback(); } button.innerHTML = 'Stop Recording'; button.disabled = false; chkFixSeeking.parentNode.style.display = 'none'; }, onMediaStopped: function () { button.innerHTML = 'Start Recording'; if (!button.disableStateWaiting) { button.disabled = false; } chkFixSeeking.parentNode.style.display = 'inline-block'; }, onMediaCapturingFailed: function (error) { console.error('onMediaCapturingFailed:', error); if (error.toString().indexOf('no audio or video tracks available') !== -1) { alert('RecordRTC failed to start because there are no audio or video tracks available.'); } if (error.name === 'PermissionDeniedError' && DetectRTC.browser.name === 'Firefox') { alert('Firefox requires version >= 52. Firefox also requires HTTPs.'); } commonConfig.onMediaStopped(); } }; if (mediaContainerFormat.value === 'h264') { mimeType = 'video/webm\;codecs=h264'; fileExtension = 'mp4'; // video/mp4;codecs=avc1 if (isMimeTypeSupported('video/mpeg')) { mimeType = 'video/mpeg'; } } if (mediaContainerFormat.value === 'mkv' && isMimeTypeSupported('video/x-matroska;codecs=avc1')) { mimeType = 'video/x-matroska;codecs=avc1'; fileExtension = 'mkv'; } if (mediaContainerFormat.value === 'vp8' && isMimeTypeSupported('video/webm\;codecs=vp8')) { mimeType = 'video/webm\;codecs=vp8'; fileExtension = 'webm'; recorderType = null; type = 'video'; } if (mediaContainerFormat.value === 'vp9' && isMimeTypeSupported('video/webm\;codecs=vp9')) { mimeType = 'video/webm\;codecs=vp9'; fileExtension = 'webm'; recorderType = null; type = 'video'; } if (mediaContainerFormat.value === 'pcm') { mimeType = 'audio/wav'; fileExtension = 'wav'; recorderType = StereoAudioRecorder; type = 'audio'; } if (mediaContainerFormat.value === 'opus' || mediaContainerFormat.value === 'ogg') { if (isMimeTypeSupported('audio/webm')) { mimeType = 'audio/webm'; fileExtension = 'webm'; // webm } if (isMimeTypeSupported('audio/ogg')) { mimeType = 'audio/ogg; codecs=opus'; fileExtension = 'ogg'; // ogg } recorderType = null; type = 'audio'; } if (mediaContainerFormat.value === 'whammy') { mimeType = 'video/webm'; fileExtension = 'webm'; recorderType = WhammyRecorder; type = 'video'; } if (mediaContainerFormat.value === 'WebAssembly') { mimeType = 'video/webm'; fileExtension = 'webm'; recorderType = WebAssemblyRecorder; type = 'video'; } if (mediaContainerFormat.value === 'gif') { mimeType = 'image/gif'; fileExtension = 'gif'; recorderType = GifRecorder; type = 'gif'; } if (mediaContainerFormat.value === 'default') { mimeType = 'video/webm\;codecs=h264'; fileExtension = 'mp4'; recorderType = null; type = 'video'; } if (recordingMedia.value === 'record-audio') { captureAudio(commonConfig); button.mediaCapturedCallback = function () { var options = { type: type, mimeType: mimeType, leftChannel: params.leftChannel || false, disableLogs: params.disableLogs || false }; if (params.sampleRate) { options.sampleRate = parseInt(params.sampleRate); } if (params.bufferSize) { options.bufferSize = parseInt(params.bufferSize); } if (recorderType) { options.recorderType = recorderType; } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } if (DetectRTC.browser.name === 'Edge') { options.numberOfAudioChannels = 1; } options.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; }; } if (recordingMedia.value === 'record-audio-plus-video') { captureAudioPlusVideo(commonConfig); button.mediaCapturedCallback = function () { if (typeof MediaRecorder === 'undefined') { // opera or chrome etc. button.recordRTC = []; if (!params.bufferSize) { // it fixes audio issues whilst recording 720p params.bufferSize = 16384; } var options = { type: 'audio', // hard-code to set "audio" leftChannel: params.leftChannel || false, disableLogs: params.disableLogs || false, video: recordingPlayer }; if (params.sampleRate) { options.sampleRate = parseInt(params.sampleRate); } if (params.bufferSize) { options.bufferSize = parseInt(params.bufferSize); } if (params.frameInterval) { options.frameInterval = parseInt(params.frameInterval); } if (recorderType) { options.recorderType = recorderType; } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } options.ignoreMutedMedia = false; var audioRecorder = RecordRTC(button.stream, options); options.type = type; var videoRecorder = RecordRTC(button.stream, options); // to sync audio/video playbacks in browser! videoRecorder.initRecorder(function () { audioRecorder.initRecorder(function () { audioRecorder.startRecording(); videoRecorder.startRecording(); btnPauseRecording.style.display = ''; }); }); button.recordRTC.push(audioRecorder, videoRecorder); button.recordingEndedCallback = function () { var audio = new Audio(); audio.src = audioRecorder.toURL(); audio.controls = true; audio.autoplay = true; recordingPlayer.parentNode.appendChild(document.createElement('hr')); recordingPlayer.parentNode.appendChild(audio); if (audio.paused) audio.play(); }; return; } var options2 = { type: type, mimeType: mimeType, disableLogs: params.disableLogs || false, getNativeBlob: false, // enable it for longer recordings video: recordingPlayer }; if (recorderType) { options2.recorderType = recorderType; if (recorderType == WhammyRecorder || recorderType == GifRecorder || recorderType == WebAssemblyRecorder) { options2.canvas = options2.video = { width: defaultWidth || 320, height: defaultHeight || 240 }; } } if (videoBitsPerSecond) { options2.videoBitsPerSecond = videoBitsPerSecond; } if (timeSlice && typeof MediaRecorder !== 'undefined') { options2.timeSlice = timeSlice; button.blobs = []; options2.ondataavailable = function (blob) { button.blobs.push(blob); }; } options2.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options2); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = '<img src="https://www.webrtc-experiment.com/images/progress.gif">'; }; } if (recordingMedia.value === 'record-screen') { captureScreen(commonConfig); button.mediaCapturedCallback = function () { var options = { type: type, mimeType: mimeType, disableLogs: params.disableLogs || false, getNativeBlob: false, // enable it for longer recordings video: recordingPlayer }; if (recorderType) { options.recorderType = recorderType; if (recorderType == WhammyRecorder || recorderType == GifRecorder || recorderType == WebAssemblyRecorder) { options.canvas = options.video = { width: defaultWidth || 320, height: defaultHeight || 240 }; } } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } options.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; }; } // note: audio+tab is supported in Chrome 50+ // todo: add audio+tab recording if (recordingMedia.value === 'record-audio-plus-screen') { captureAudioPlusScreen(commonConfig); button.mediaCapturedCallback = function () { var options = { type: type, mimeType: mimeType, disableLogs: params.disableLogs || false, getNativeBlob: false, // enable it for longer recordings video: recordingPlayer }; if (recorderType) { options.recorderType = recorderType; if (recorderType == WhammyRecorder || recorderType == GifRecorder || recorderType == WebAssemblyRecorder) { options.canvas = options.video = { width: defaultWidth || 320, height: defaultHeight || 240 }; } } if (videoBitsPerSecond) { options.videoBitsPerSecond = videoBitsPerSecond; } options.ignoreMutedMedia = false; button.recordRTC = RecordRTC(button.stream, options); button.recordingEndedCallback = function (url) { setVideoURL(url); }; button.recordRTC.startRecording(); btnPauseRecording.style.display = ''; }; } }; function captureVideo(config) { captureUserMedia({ video: true }, function (videoStream) { config.onMediaCaptured(videoStream); addStreamStopListener(videoStream, function () { config.onMediaStopped(); }); }, function (error) { config.onMediaCapturingFailed(error); }); } function captureAudio(config) { captureUserMedia({ audio: true }, function (audioStream) { config.onMediaCaptured(audioStream); addStreamStopListener(audioStream, function () { config.onMediaStopped(); }); }, function (error) { config.onMediaCapturingFailed(error); }); } function captureAudioPlusVideo(config) { captureUserMedia({ video: true, audio: true }, function (audioVideoStream) { config.onMediaCaptured(audioVideoStream); if (audioVideoStream instanceof Array) { audioVideoStream.forEach(function (stream) { addStreamStopListener(stream, function () { config.onMediaStopped(); }); }); return; } addStreamStopListener(audioVideoStream, function () { config.onMediaStopped(); }); }, function (error) { config.onMediaCapturingFailed(error); }); } var MY_DOMAIN = 'webrtc-experiment.com'; function isMyOwnDomain() { // replace "webrtc-experiment.com" with your own domain name return document.domain.indexOf(MY_DOMAIN) !== -1; } function isLocalHost() { // "chrome.exe" --enable-usermedia-screen-capturing // or firefox => about:config => "media.getusermedia.screensharing.allowed_domains" => add "localhost" return document.domain === 'localhost' || document.domain === '127.0.0.1'; } var videoBitsPerSecond; function setVideoBitrates() { var select = document.querySelector('.media-bitrates'); var value = select.value; if (value == 'default') { videoBitsPerSecond = null; return; } videoBitsPerSecond = parseInt(value); } function getFrameRates(mediaConstraints) { if (!mediaConstraints.video) { return mediaConstraints; } var select = document.querySelector('.media-framerates'); var value = select.value; if (value == 'default') { return mediaConstraints; } value = parseInt(value); if (DetectRTC.browser.name === 'Firefox') { mediaConstraints.video.frameRate = value; return mediaConstraints; } if (!mediaConstraints.video.mandatory) { mediaConstraints.video.mandatory = {}; mediaConstraints.video.optional = []; } var isScreen = recordingMedia.value.toString().toLowerCase().indexOf('screen') != -1; if (isScreen) { mediaConstraints.video.mandatory.maxFrameRate = value; } else { mediaConstraints.video.mandatory.minFrameRate = value; } return mediaConstraints; } function setGetFromLocalStorage(selectors) { selectors.forEach(function (selector) { var storageItem = selector.replace(/\.|#/g, ''); if (localStorage.getItem(storageItem)) { document.querySelector(selector).value = localStorage.getItem(storageItem); } addEventListenerToUploadLocalStorageItem(selector, ['change', 'blur'], function () { localStorage.setItem(storageItem, document.querySelector(selector).value); }); }); } function addEventListenerToUploadLocalStorageItem(selector, arr, callback) { arr.forEach(function (event) { document.querySelector(selector).addEventListener(event, callback, false); }); } setGetFromLocalStorage(['.media-resolutions', '.media-framerates', '.media-bitrates', '.recording-media', '.media-container-format']); function getVideoResolutions(mediaConstraints) { if (!mediaConstraints.video) { return mediaConstraints; } var select = document.querySelector('.media-resolutions'); var value = select.value; if (value == 'default') { return mediaConstraints; } value = value.split('x'); if (value.length != 2) { return mediaConstraints; } defaultWidth = parseInt(value[0]); defaultHeight = parseInt(value[1]); if (DetectRTC.browser.name === 'Firefox') { mediaConstraints.video.width = defaultWidth; mediaConstraints.video.height = defaultHeight; return mediaConstraints; } if (!mediaConstraints.video.mandatory) { mediaConstraints.video.mandatory = {}; mediaConstraints.video.optional = []; } var isScreen = recordingMedia.value.toString().toLowerCase().indexOf('screen') != -1; if (isScreen) { mediaConstraints.video.mandatory.maxWidth = defaultWidth; mediaConstraints.video.mandatory.maxHeight = defaultHeight; } else { mediaConstraints.video.mandatory.minWidth = defaultWidth; mediaConstraints.video.mandatory.minHeight = defaultHeight; } return mediaConstraints; } function captureUserMedia(mediaConstraints, successCallback, errorCallback) { if (mediaConstraints.video == true) { mediaConstraints.video = {}; } setVideoBitrates(); mediaConstraints = getVideoResolutions(mediaConstraints); mediaConstraints = getFrameRates(mediaConstraints); var isBlackBerry = !!(/BB10|BlackBerry/i.test(navigator.userAgent || '')); if (isBlackBerry && !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia)) { navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; navigator.getUserMedia(mediaConstraints, successCallback, errorCallback); return; } navigator.mediaDevices.getUserMedia(mediaConstraints).then(function (stream) { successCallback(stream); setVideoURL(stream, true); }).catch(function (error) { if (error && (error.name === 'ConstraintNotSatisfiedError' || error.name === 'OverconstrainedError')) { alert('Your camera or browser does NOT supports selected resolutions or frame-rates. \n\nPlease select "default" resolutions.'); } else if (error && error.message) { alert(error.message); } else { alert('Unable to make getUserMedia request. Please check browser console logs.'); } errorCallback(error); }); } function setMediaContainerFormat(arrayOfOptionsSupported) { var options = Array.prototype.slice.call( mediaContainerFormat.querySelectorAll('option') ); var localStorageItem; if (localStorage.getItem('media-container-format')) { localStorageItem = localStorage.getItem('media-container-format'); } var selectedItem; options.forEach(function (option) { option.disabled = true; if (arrayOfOptionsSupported.indexOf(option.value) !== -1) { option.disabled = false; if (localStorageItem && arrayOfOptionsSupported.indexOf(localStorageItem) != -1) { if (option.value != localStorageItem) return; option.selected = true; selectedItem = option; return; } if (!selectedItem) { option.selected = true; selectedItem = option; } } }); } function isMimeTypeSupported(mimeType) { if (typeof MediaRecorder === 'undefined') { return false; } if (typeof MediaRecorder.isTypeSupported !== 'function') { return true; } return MediaRecorder.isTypeSupported(mimeType); } recordingMedia.onchange = function () { if (recordingMedia.value === 'record-audio') { var recordingOptions1 = []; if (isMimeTypeSupported('audio/webm')) { recordingOptions1.push('opus'); } if (isMimeTypeSupported('audio/ogg')) { recordingOptions1.push('ogg'); } recordingOptions1.push('pcm'); setMediaContainerFormat(recordingOptions1); return; } var isChrome = !!window.chrome && !(!!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0); var recordingOptions = ['vp8']; // MediaStreamRecorder with vp8 if (isMimeTypeSupported('video/webm\;codecs=vp9')) { recordingOptions.push('vp9'); // MediaStreamRecorder with vp9 } if (isMimeTypeSupported('video/webm\;codecs=h264')) { recordingOptions.push('h264'); // MediaStreamRecorder with h264 } if (isMimeTypeSupported('video/x-matroska;codecs=avc1')) { recordingOptions.push('mkv'); // MediaStreamRecorder with mkv/matroska } recordingOptions.push('gif'); // GifRecorder if (DetectRTC.browser.name == 'Chrome') { recordingOptions.push('whammy'); // WhammyRecorder } if (DetectRTC.browser.name == 'Chrome') { recordingOptions.push('WebAssembly'); // WebAssemblyRecorder } recordingOptions.push('default'); // Default mimeType for MediaStreamRecorder setMediaContainerFormat(recordingOptions); }; recordingMedia.onchange(); if (typeof MediaRecorder === 'undefined' && (DetectRTC.browser.name === 'Edge' || DetectRTC.browser.name === 'Safari')) { // webp isn't supported in Microsoft Edge // neither MediaRecorder API // so lets disable both video/screen recording options console.warn('Neither MediaRecorder API nor webp is supported in ' + DetectRTC.browser.name + '. You cam merely record audio.'); recordingMedia.innerHTML = '<option value="record-audio">Audio</option>'; setMediaContainerFormat(['pcm']); } function stringify(obj) { var result = ''; Object.keys(obj).forEach(function (key) { if (typeof obj[key] === 'function') { return; } if (result.length) { result += ','; } result += key + ': ' + obj[key]; }); return result; } function mediaRecorderToStringify(mediaRecorder) { var result = ''; result += 'mimeType: ' + mediaRecorder.mimeType; result += ', state: ' + mediaRecorder.state; result += ', audioBitsPerSecond: ' + mediaRecorder.audioBitsPerSecond; result += ', videoBitsPerSecond: ' + mediaRecorder.videoBitsPerSecond; if (mediaRecorder.stream) { result += ', streamid: ' + mediaRecorder.stream.id; result += ', stream-active: ' + mediaRecorder.stream.active; } return result; } function getFailureReport() { var info = 'RecordRTC seems failed. \n\n' + stringify(DetectRTC.browser) + '\n\n' + DetectRTC.osName + ' ' + DetectRTC.osVersion + '\n'; if (typeof recorderType !== 'undefined' && recorderType) { info += '\nrecorderType: ' + recorderType.name; } if (typeof mimeType !== 'undefined') { info += '\nmimeType: ' + mimeType; } Array.prototype.slice.call(document.querySelectorAll('select')).forEach(function (select) { info += '\n' + (select.id || select.className) + ': ' + select.value; }); if (btnStartRecording.recordRTC) { info += '\n\ninternal-recorder: ' + btnStartRecording.recordRTC.getInternalRecorder().name; if (btnStartRecording.recordRTC.getInternalRecorder().getAllStates) { info += '\n\nrecorder-states: ' + btnStartRecording.recordRTC.getInternalRecorder().getAllStates(); } } if (btnStartRecording.stream) { info += '\n\naudio-tracks: ' + getTracks(btnStartRecording.stream, 'audio').length; info += '\nvideo-tracks: ' + getTracks(btnStartRecording.stream, 'video').length; info += '\nstream-active? ' + !!btnStartRecording.stream.active; btnStartRecording.stream.getTracks().forEach(function (track) { info += '\n' + track.kind + '-track-' + (track.label || track.id) + ': (enabled: ' + !!track.enabled + ', readyState: ' + track.readyState + ', muted: ' + !!track.muted + ')'; if (track.getConstraints && Object.keys(track.getConstraints()).length) { info += '\n' + track.kind + '-track-getConstraints: ' + stringify(track.getConstraints()); } if (track.getSettings && Object.keys(track.getSettings()).length) { info += '\n' + track.kind + '-track-getSettings: ' + stringify(track.getSettings()); } }); } if (timeSlice && btnStartRecording.recordRTC) { info += '\ntimeSlice: ' + timeSlice; if (btnStartRecording.recordRTC.getInternalRecorder().getArrayOfBlobs) { var blobSizes = []; btnStartRecording.recordRTC.getInternalRecorder().getArrayOfBlobs().forEach(function (blob) { blobSizes.push(blob.size); }); info += '\nblobSizes: ' + blobSizes; } } else if (btnStartRecording.recordRTC && btnStartRecording.recordRTC.getBlob()) { info += '\n\nblobSize: ' + bytesToSize(btnStartRecording.recordRTC.getBlob().size); } if (btnStartRecording.recordRTC && btnStartRecording.recordRTC.getInternalRecorder() && btnStartRecording.recordRTC.getInternalRecorder().getInternalRecorder && btnStartRecording.recordRTC.getInternalRecorder().getInternalRecorder()) { info += '\n\ngetInternalRecorder: ' + mediaRecorderToStringify(btnStartRecording.recordRTC.getInternalRecorder().getInternalRecorder()); } return info; } function saveToDiskOrOpenNewTab(recordRTC) { if (!recordRTC.getBlob().size) { var info = getFailureReport(); console.log('blob', recordRTC.getBlob()); console.log('recordrtc instance', recordRTC); console.log('report', info); if (mediaContainerFormat.value !== 'default') { alert('RecordRTC seems failed recording using ' + mediaContainerFormat.value + '. Please choose "default" option from the drop down and record again.'); } else { alert('RecordRTC seems failed. Unexpected issue. You can read the email in your console log. \n\nPlease report using disqus chat below.'); } if (mediaContainerFormat.value !== 'vp9' && DetectRTC.browser.name === 'Chrome') { alert('Please record using VP9 encoder. (select from the dropdown)'); } } var fileName = getFileName(fileExtension); document.querySelector('#save-to-disk').parentNode.style.display = 'block'; document.querySelector('#save-to-disk').onclick = function () { if (!recordRTC) return alert('No recording found.'); var file = new File([recordRTC.getBlob()], fileName, { type: mimeType }); invokeSaveAsDialog(file, file.name); }; document.querySelector('#open-new-tab').onclick = function () { if (!recordRTC) return alert('No recording found.'); var file = new File([recordRTC.getBlob()], fileName, { type: mimeType }); window.open(URL.createObjectURL(file)); }; // upload to PHP server if (isMyOwnDomain()) { document.querySelector('#upload-to-php').disabled = true; document.querySelector('#upload-to-php').style.display = 'none'; } else { document.querySelector('#upload-to-php').disabled = true; } document.querySelector('#upload-to-php').onclick = function () { if (isMyOwnDomain()) { alert('PHP Upload is not available on this domain.'); return; } if (!recordRTC) return alert('No recording found.'); this.disabled = true; var button = this; uploadToPHPServer(fileName, recordRTC, function (progress, fileURL) { if (progress === 'ended') { button.disabled = false; button.innerHTML = 'Click to download from server'; button.onclick = function () { SaveFileURLToDisk(fileURL, fileName); }; setVideoURL(fileURL); var html = 'Uploaded to PHP.<br>Download using below link:<br>'; html += '<a href="' + fileURL + '" download="' + fileName + '" style="color: yellow; display: block; margin-top: 15px;">' + fileName + '</a>'; recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = html; return; } button.innerHTML = progress; recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = progress; }); }; // upload to YouTube! document.querySelector('#upload-to-youtube').disabled = false; document.querySelector('#upload-to-youtube').onclick = function () { if (!recordRTC) return alert('No recording found.'); this.disabled = true; if (isLocalHost()) { alert('This feature is NOT available on localhost.'); return; } if (isMyOwnDomain() === false) { var url = 'https://github.com/muaz-khan/RecordRTC/wiki/Upload-to-YouTube'; alert('YouTube API key is configured to work only on webrtc-experiment.com. Please create your own YouTube key + oAuth client-id and use it instead.\n\nWiki page: ' + url); // check instructions on the wiki page location.href = url; return; } var button = this; uploadToYouTube(fileName, recordRTC, function (percentageComplete, fileURL) { if (percentageComplete == 'uploaded') { button.disabled = false; button.innerHTML = 'Uploaded. However YouTube is still processing.'; button.onclick = function () { window.open(fileURL); }; return; } if (percentageComplete == 'processed') { button.disabled = false; button.innerHTML = 'Uploaded & Processed. Click to open YouTube video.'; button.onclick = function () { window.open(fileURL); }; document.querySelector('h1').innerHTML = 'Your video has been uploaded.'; window.scrollTo(0, 0); alert('Your video has been uploaded.'); return; } if (percentageComplete == 'failed') { button.disabled = false; button.innerHTML = 'YouTube failed transcoding the video.'; button.onclick = function () { window.open(fileURL); }; return; } button.innerHTML = percentageComplete + '% uploaded to YouTube.'; }); }; } function uploadToPHPServer(fileName, recordRTC, callback) { var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.getBlob(); blob = new File([blob], getFileName(fileExtension), { type: mimeType }); // create FormData var formData = new FormData(); formData.append('video-filename', fileName); formData.append('video-blob', blob); callback('Uploading recorded-file to server.'); // var upload_url = 'https://your-domain.com/files-uploader/'; var upload_url = 'RecordRTC-to-PHP/save.php'; // var upload_directory = upload_url; var upload_directory = 'RecordRTC-to-PHP/uploads/'; makeXMLHttpRequest(upload_url, formData, function (progress) { if (progress !== 'upload-ended') { callback(progress); return; } callback('ended', upload_directory + fileName); }); } function makeXMLHttpRequest(url, data, callback) { var request = new XMLHttpRequest(); request.onreadystatechange = function () { if (request.readyState == 4 && request.status == 200) { if (request.responseText === 'success') { callback('upload-ended'); return; } document.querySelector('.header').parentNode.style = 'text-align: left; color: red; padding: 5px 10px;'; document.querySelector('.header').parentNode.innerHTML = request.responseText; } }; request.upload.onloadstart = function () { callback('Upload started...'); }; request.upload.onprogress = function (event) { callback('Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%"); }; request.upload.onload = function () { callback('progress-about-to-end'); }; request.upload.onload = function () { callback('Getting File URL..'); }; request.upload.onerror = function (error) { callback('Failed to upload to server'); }; request.upload.onabort = function (error) { callback('Upload aborted.'); }; request.open('POST', url); request.send(data); } function getRandomString() { if (window.crypto && window.crypto.getRandomValues && navigator.userAgent.indexOf('Safari') === -1) { var a = window.crypto.getRandomValues(new Uint32Array(3)), token = ''; for (var i = 0, l = a.length; i < l; i++) { token += a[i].toString(36); } return token; } else { return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, ''); } } function getFileName(fileExtension) { var d = new Date(); var year = d.getUTCFullYear(); var month = d.getUTCMonth(); var date = d.getUTCDate(); return 'RecordRTC-' + year + month + date + '-' + getRandomString() + '.' + fileExtension; } function SaveFileURLToDisk(fileUrl, fileName) { var hyperlink = document.createElement('a'); hyperlink.href = fileUrl; hyperlink.target = '_blank'; hyperlink.download = fileName || fileUrl; (document.body || document.documentElement).appendChild(hyperlink); hyperlink.onclick = function () { (document.body || document.documentElement).removeChild(hyperlink); // required for Firefox window.URL.revokeObjectURL(hyperlink.href); }; var mouseEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); hyperlink.dispatchEvent(mouseEvent); } function getURL(arg) { var url = arg; if (arg instanceof Blob || arg instanceof File) { url = URL.createObjectURL(arg); } if (arg instanceof RecordRTC || arg.getBlob) { url = URL.createObjectURL(arg.getBlob()); } if (arg instanceof MediaStream || arg.getTracks) { // url = URL.createObjectURL(arg); } return url; } function setVideoURL(arg, forceNonImage) { var url = getURL(arg); var parentNode = recordingPlayer.parentNode; parentNode.removeChild(recordingPlayer); parentNode.innerHTML = ''; var elem = 'video'; if (type == 'gif' && !forceNonImage) { elem = 'img'; } if (type == 'audio') { elem = 'audio'; } recordingPlayer = document.createElement(elem); if (arg instanceof MediaStream) { recordingPlayer.muted = true; } recordingPlayer.addEventListener('loadedmetadata', function () { if (navigator.userAgent.toLowerCase().indexOf('android') == -1) return; // android setTimeout(function () { if (typeof recordingPlayer.play === 'function') { recordingPlayer.play(); } }, 2000); }, false); recordingPlayer.poster = ''; if (arg instanceof MediaStream) { recordingPlayer.srcObject = arg; } else { recordingPlayer.src = url; } if (typeof recordingPlayer.play === 'function') { recordingPlayer.play(); } recordingPlayer.addEventListener('ended', function () { url = getURL(arg); if (arg instanceof MediaStream) { recordingPlayer.srcObject = arg; } else { recordingPlayer.src = url; } }); parentNode.appendChild(recordingPlayer); } function captureScreen(config) { if (navigator.getDisplayMedia) { navigator.getDisplayMedia({ video: true }).then(screenStream => { config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia({ video: true }).then(screenStream => { config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else { var error = 'getDisplayMedia API are not supported in this browser.'; config.onMediaCapturingFailed(error); alert(error); } } function captureAudioPlusScreen(config) { if (navigator.getDisplayMedia) { navigator.getDisplayMedia({ video: true }).then(screenStream => { navigator.mediaDevices.getUserMedia({ audio: true }).then(function (mic) { screenStream.addTrack(mic.getTracks()[0]); config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia({ video: true }).then(screenStream => { navigator.mediaDevices.getUserMedia({ audio: true }).then(function (mic) { screenStream.addTrack(mic.getTracks()[0]); config.onMediaCaptured(screenStream); addStreamStopListener(screenStream, function () { // config.onMediaStopped(); btnStartRecording.onclick(); }); setVideoURL(screenStream, true); }); }).catch(function (error) { config.onMediaCapturingFailed(error); }); } else { var error = 'getDisplayMedia API are not supported in this browser.'; config.onMediaCapturingFailed(error); alert(error); } } /* upload_youtube_video.js Copyright 2017 Google Inc. All Rights Reserved. */ function uploadToYouTube(fileName, recordRTC, callback) { var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.getBlob(); blob = new File([blob], getFileName(fileExtension), { type: mimeType }); if (!uploadVideo) { alert('YouTube API are not available.'); return; } uploadVideo.callback = callback; uploadVideo.uploadFile(fileName, blob); } var uploadVideo; var signinCallback = function (result) { if (result.access_token) { uploadVideo = new UploadVideo(); uploadVideo.ready(result.access_token); } else { // console.error('YouTube error', result); // document.querySelector('#upload-to-youtube').style.display = 'none'; } }; var STATUS_POLLING_INTERVAL_MILLIS = 60 * 1000; // One minute. var UploadVideo = function () { this.tags = ['recordrtc']; this.categoryId = 28; // via: http://stackoverflow.com/a/35877512/552182 this.videoId = ''; this.uploadStartTime = 0; }; UploadVideo.prototype.ready = function (accessToken) { this.accessToken = accessToken; this.gapi = gapi; this.authenticated = true; false && this.gapi.client.request({ path: '/youtube/v3/channels', params: { part: 'snippet', mine: true }, callback: function (response) { if (!response.error) { // response.items[0].snippet.title -- channel title // response.items[0].snippet.thumbnails.default.url -- channel thumbnail } }.bind(this) }); }; UploadVideo.prototype.uploadFile = function (fileName, file) { var metadata = { snippet: { title: fileName, description: fileName, tags: this.tags, categoryId: this.categoryId }, status: { privacyStatus: 'public' } }; var uploader = new MediaUploader({ baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos', file: file, token: this.accessToken, metadata: metadata, params: { part: Object.keys(metadata).join(',') }, onError: function (data) { var message = data; try { var errorResponse = JSON.parse(data); message = errorResponse.error.message; } finally { alert(message); } }.bind(this), onProgress: function (data) { var bytesUploaded = data.loaded; var totalBytes = parseInt(data.total); var percentageComplete = parseInt((bytesUploaded * 100) / totalBytes); uploadVideo.callback(percentageComplete); }.bind(this), onComplete: function (data) { var uploadResponse = JSON.parse(data); this.videoId = uploadResponse.id; this.videoURL = 'https://www.youtube.com/watch?v=' + this.videoId; uploadVideo.callback('uploaded', this.videoURL); setTimeout(this.pollForVideoStatus, 2000); }.bind(this) }); this.uploadStartTime = Date.now(); uploader.upload(); }; UploadVideo.prototype.pollForVideoStatus = function () { this.gapi.client.request({ path: '/youtube/v3/videos', params: { part: 'status,player', id: this.videoId }, callback: function (response) { if (response.error) { uploadVideo.pollForVideoStatus(); } else { var uploadStatus = response.items[0].status.uploadStatus; switch (uploadStatus) { case 'uploaded': uploadVideo.callback('uploaded', uploadVideo.videoURL); uploadVideo.pollForVideoStatus(); break; case 'processed': uploadVideo.callback('processed', uploadVideo.videoURL); break; default: uploadVideo.callback('failed', uploadVideo.videoURL); break; } } }.bind(this) }); }; /* cors_upload.js Copyright 2015 Google Inc. All Rights Reserved. */ var DRIVE_UPLOAD_URL = 'https://www.googleapis.com/upload/drive/v2/files/'; var RetryHandler = function () { this.interval = 1000; // Start at one second this.maxInterval = 60 * 1000; // Don't wait longer than a minute }; RetryHandler.prototype.retry = function (fn) { setTimeout(fn, this.interval); this.interval = this.nextInterval_(); }; RetryHandler.prototype.reset = function () { this.interval = 1000; }; RetryHandler.prototype.nextInterval_ = function () { var interval = this.interval * 2 + this.getRandomInt_(0, 1000); return Math.min(interval, this.maxInterval); }; RetryHandler.prototype.getRandomInt_ = function (min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }; var MediaUploader = function (options) { var noop = function () {}; this.file = options.file; this.contentType = options.contentType || this.file.type || 'application/octet-stream'; this.metadata = options.metadata || { 'title': this.file.name, 'mimeType': this.contentType }; this.token = options.token; this.onComplete = options.onComplete || noop; this.onProgress = options.onProgress || noop; this.onError = options.onError || noop; this.offset = options.offset || 0; this.chunkSize = options.chunkSize || 0; this.retryHandler = new RetryHandler(); this.url = options.url; if (!this.url) { var params = options.params || {}; params.uploadType = 'resumable'; this.url = this.buildUrl_(options.fileId, params, options.baseUrl); } this.httpMethod = options.fileId ? 'PUT' : 'POST'; }; MediaUploader.prototype.upload = function () { var self = this; var xhr = new XMLHttpRequest(); xhr.open(this.httpMethod, this.url, true); xhr.setRequestHeader('Authorization', 'Bearer ' + this.token); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.setRequestHeader('X-Upload-Content-Length', this.file.size); xhr.setRequestHeader('X-Upload-Content-Type', this.contentType); xhr.onload = function (e) { if (e.target.status < 400) { var location = e.target.getResponseHeader('Location'); this.url = location; this.sendFile_(); } else { this.onUploadError_(e); } }.bind(this); xhr.onerror = this.onUploadError_.bind(this); xhr.send(JSON.stringify(this.metadata)); }; MediaUploader.prototype.sendFile_ = function () { var content = this.file; var end = this.file.size; if (this.offset || this.chunkSize) { // Only bother to slice the file if we're either resuming or uploading in chunks if (this.chunkSize) { end = Math.min(this.offset + this.chunkSize, this.file.size); } content = content.slice(this.offset, end); } var xhr = new XMLHttpRequest(); xhr.open('PUT', this.url, true); xhr.setRequestHeader('Content-Type', this.contentType); xhr.setRequestHeader('Content-Range', 'bytes ' + this.offset + '-' + (end - 1) + '/' + this.file.size); xhr.setRequestHeader('X-Upload-Content-Type', this.file.type); if (xhr.upload) { xhr.upload.addEventListener('progress', this.onProgress); } xhr.onload = this.onContentUploadSuccess_.bind(this); xhr.onerror = this.onContentUploadError_.bind(this); xhr.send(content); }; MediaUploader.prototype.resume_ = function () { var xhr = new XMLHttpRequest(); xhr.open('PUT', this.url, true); xhr.setRequestHeader('Content-Range', 'bytes */' + this.file.size); xhr.setRequestHeader('X-Upload-Content-Type', this.file.type); if (xhr.upload) { xhr.upload.addEventListener('progress', this.onProgress); } xhr.onload = this.onContentUploadSuccess_.bind(this); xhr.onerror = this.onContentUploadError_.bind(this); xhr.send(); }; MediaUploader.prototype.extractRange_ = function (xhr) { var range = xhr.getResponseHeader('Range'); if (range) { this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1; } }; MediaUploader.prototype.onContentUploadSuccess_ = function (e) { if (e.target.status == 200 || e.target.status == 201) { this.onComplete(e.target.response); } else if (e.target.status == 308) { this.extractRange_(e.target); this.retryHandler.reset(); this.sendFile_(); } }; MediaUploader.prototype.onContentUploadError_ = function (e) { if (e.target.status && e.target.status < 500) { this.onError(e.target.response); } else { this.retryHandler.retry(this.resume_.bind(this)); } }; MediaUploader.prototype.onUploadError_ = function (e) { this.onError(e.target.response); // TODO - Retries for initial upload }; MediaUploader.prototype.buildQuery_ = function (params) { params = params || {}; return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); }).join('&'); }; MediaUploader.prototype.buildUrl_ = function (id, params, baseUrl) { var url = baseUrl || DRIVE_UPLOAD_URL; if (id) { url += id; } var query = this.buildQuery_(params); if (query) { url += '?' + query; } return url; }; var chkFixSeeking = document.querySelector('#chk-fixSeeking'); chkFixSeeking.onchange = function () { if (this.checked === true) { localStorage.setItem(this.id, 'true'); } else { localStorage.removeItem(this.id); } }; if (localStorage.getItem(chkFixSeeking.id) === 'true') { chkFixSeeking.checked = true; } var chkTimeSlice = document.querySelector('#chk-timeSlice'); var timeSlice = false; if (typeof MediaRecorder === 'undefined') { chkTimeSlice.disabled = true; } chkTimeSlice.addEventListener('change', function () { if (chkTimeSlice.checked === true) { var _timeSlice = prompt('Please enter timeSlice in milliseconds e.g. 1000 or 2000 or 3000.', 1000); _timeSlice = parseInt(_timeSlice); if (!_timeSlice || _timeSlice == NaN || typeof _timeSlice === 'undefined') { timeSlice = false; return; } timeSlice = _timeSlice; } else { timeSlice = false; } }, false); var btnPauseRecording = document.querySelector('#btn-pause-recording'); btnPauseRecording.onclick = function () { if (!btnStartRecording.recordRTC) { btnPauseRecording.style.display = 'none'; return; } btnPauseRecording.disabled = true; if (btnPauseRecording.innerHTML === 'Pause') { btnStartRecording.disabled = true; chkFixSeeking.parentNode.style.display = 'none'; btnStartRecording.style.fontSize = '12px'; btnStartRecording.recordRTC.pauseRecording(); recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = 'Recording status: paused'; recordingPlayer.pause(); btnPauseRecording.style.fontSize = '12px'; setTimeout(function () { btnPauseRecording.innerHTML = 'Resume Recording'; btnPauseRecording.disabled = false; }, 2000); } if (btnPauseRecording.innerHTML === 'Resume Recording') { btnStartRecording.disabled = false; chkFixSeeking.parentNode.style.display = 'none'; btnStartRecording.style.fontSize = '12px'; btnStartRecording.recordRTC.resumeRecording(); recordingPlayer.parentNode.parentNode.querySelector('h2').innerHTML = 'Recording status: active'; recordingPlayer.play(); btnPauseRecording.style.fontSize = '12px'; btnPauseRecording.innerHTML = 'Pause'; setTimeout(function () { btnPauseRecording.disabled = false; }, 2000); } }; // getHTMLMediaElement.js function getHTMLMediaElement(mediaElement, config) { config = config || {}; if (!mediaElement.nodeName || (mediaElement.nodeName.toLowerCase() != 'audio' && mediaElement.nodeName.toLowerCase() != 'video')) { if (!mediaElement.getVideoTracks().length) { return getAudioElement(mediaElement, config); } var mediaStream = mediaElement; mediaElement = document.createElement(mediaStream.getVideoTracks().length ? 'video' : 'audio'); if ('srcObject' in mediaElement) { mediaElement.srcObject = mediaStream; } else { mediaElement[!!navigator.mozGetUserMedia ? 'mozSrcObject' : 'src'] = !!navigator.mozGetUserMedia ? mediaStream : window.webkitURL.createObjectURL(mediaStream); } } if (mediaElement.nodeName && mediaElement.nodeName.toLowerCase() == 'audio') { return getAudioElement(mediaElement, config); } mediaElement.controls = false; var buttons = config.buttons || ['mute-audio', 'mute-video', 'full-screen', 'volume-slider', 'stop']; buttons.has = function (element) { return buttons.indexOf(element) !== -1; }; config.toggle = config.toggle || []; config.toggle.has = function (element) { return config.toggle.indexOf(element) !== -1; }; var mediaElementContainer = document.createElement('div'); mediaElementContainer.className = 'media-container'; var mediaControls = document.createElement('div'); mediaControls.className = 'media-controls'; mediaElementContainer.appendChild(mediaControls); if (buttons.has('mute-audio')) { var muteAudio = document.createElement('div'); muteAudio.className = 'control ' + (config.toggle.has('mute-audio') ? 'unmute-audio selected' : 'mute-audio'); mediaControls.appendChild(muteAudio); muteAudio.onclick = function () { if (muteAudio.className.indexOf('unmute-audio') != -1) { muteAudio.className = muteAudio.className.replace('unmute-audio selected', 'mute-audio'); mediaElement.muted = false; mediaElement.volume = 1; if (config.onUnMuted) config.onUnMuted('audio'); } else { muteAudio.className = muteAudio.className.replace('mute-audio', 'unmute-audio selected'); mediaElement.muted = true; mediaElement.volume = 0; if (config.onMuted) config.onMuted('audio'); } }; } if (buttons.has('mute-video')) { var muteVideo = document.createElement('div'); muteVideo.className = 'control ' + (config.toggle.has('mute-video') ? 'unmute-video selected' : 'mute-video'); mediaControls.appendChild(muteVideo); muteVideo.onclick = function () { if (muteVideo.className.indexOf('unmute-video') != -1) { muteVideo.className = muteVideo.className.replace('unmute-video selected', 'mute-video'); mediaElement.muted = false; mediaElement.volume = 1; mediaElement.play(); if (config.onUnMuted) config.onUnMuted('video'); } else { muteVideo.className = muteVideo.className.replace('mute-video', 'unmute-video selected'); mediaElement.muted = true; mediaElement.volume = 0; mediaElement.pause(); if (config.onMuted) config.onMuted('video'); } }; } if (buttons.has('take-snapshot')) { var takeSnapshot = document.createElement('div'); takeSnapshot.className = 'control take-snapshot'; mediaControls.appendChild(takeSnapshot); takeSnapshot.onclick = function () { if (config.onTakeSnapshot) config.onTakeSnapshot(); }; } if (buttons.has('stop')) { var stop = document.createElement('div'); stop.className = 'control stop'; mediaControls.appendChild(stop); stop.onclick = function () { mediaElementContainer.style.opacity = 0; setTimeout(function () { if (mediaElementContainer.parentNode) { mediaElementContainer.parentNode.removeChild(mediaElementContainer); } }, 800); if (config.onStopped) config.onStopped(); }; } var volumeControl = document.createElement('div'); volumeControl.className = 'volume-control'; if (buttons.has('record-audio')) { var recordAudio = document.createElement('div'); recordAudio.className = 'control ' + (config.toggle.has('record-audio') ? 'stop-recording-audio selected' : 'record-audio'); volumeControl.appendChild(recordAudio); recordAudio.onclick = function () { if (recordAudio.className.indexOf('stop-recording-audio') != -1) { recordAudio.className = recordAudio.className.replace('stop-recording-audio selected', 'record-audio'); if (config.onRecordingStopped) config.onRecordingStopped('audio'); } else { recordAudio.className = recordAudio.className.replace('record-audio', 'stop-recording-audio selected'); if (config.onRecordingStarted) config.onRecordingStarted('audio'); } }; } if (buttons.has('record-video')) { var recordVideo = document.createElement('div'); recordVideo.className = 'control ' + (config.toggle.has('record-video') ? 'stop-recording-video selected' : 'record-video'); volumeControl.appendChild(recordVideo); recordVideo.onclick = function () { if (recordVideo.className.indexOf('stop-recording-video') != -1) { recordVideo.className = recordVideo.className.replace('stop-recording-video selected', 'record-video'); if (config.onRecordingStopped) config.onRecordingStopped('video'); } else { recordVideo.className = recordVideo.className.replace('record-video', 'stop-recording-video selected'); if (config.onRecordingStarted) config.onRecordingStarted('video'); } }; } if (buttons.has('volume-slider')) { var volumeSlider = document.createElement('div'); volumeSlider.className = 'control volume-slider'; volumeControl.appendChild(volumeSlider); var slider = document.createElement('input'); slider.type = 'range'; slider.min = 0; slider.max = 100; slider.value = 100; slider.onchange = function () { mediaElement.volume = '.' + slider.value.toString().substr(0, 1); }; volumeSlider.appendChild(slider); } if (buttons.has('full-screen')) { var zoom = document.createElement('div'); zoom.className = 'control ' + (config.toggle.has('zoom-in') ? 'zoom-out selected' : 'zoom-in'); if (!slider && !recordAudio && !recordVideo && zoom) { mediaControls.insertBefore(zoom, mediaControls.firstChild); } else volumeControl.appendChild(zoom); zoom.onclick = function () { if (zoom.className.indexOf('zoom-out') != -1) { zoom.className = zoom.className.replace('zoom-out selected', 'zoom-in'); exitFullScreen(); } else { zoom.className = zoom.className.replace('zoom-in', 'zoom-out selected'); launchFullscreen(mediaElementContainer); } }; function launchFullscreen(element) { if (element.requestFullscreen) { element.requestFullscreen(); } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); } } function exitFullScreen() { if (document.fullscreen) { document.cancelFullScreen(); } if (document.mozFullScreen) { document.mozCancelFullScreen(); } if (document.webkitIsFullScreen) { document.webkitCancelFullScreen(); } } function screenStateChange(e) { if (e.srcElement != mediaElementContainer) return; var isFullScreeMode = document.webkitIsFullScreen || document.mozFullScreen || document.fullscreen; mediaElementContainer.style.width = (isFullScreeMode ? (window.innerWidth - 20) : config.width) + 'px'; mediaElementContainer.style.display = isFullScreeMode ? 'block' : 'inline-block'; if (config.height) { mediaBox.style.height = (isFullScreeMode ? (window.innerHeight - 20) : config.height) + 'px'; } if (!isFullScreeMode && config.onZoomout) config.onZoomout(); if (isFullScreeMode && config.onZoomin) config.onZoomin(); if (!isFullScreeMode && zoom.className.indexOf('zoom-out') != -1) { zoom.className = zoom.className.replace('zoom-out selected', 'zoom-in'); if (config.onZoomout) config.onZoomout(); } setTimeout(adjustControls, 1000); } document.addEventListener('fullscreenchange', screenStateChange, false); document.addEventListener('mozfullscreenchange', screenStateChange, false); document.addEventListener('webkitfullscreenchange', screenStateChange, false); } if (buttons.has('volume-slider') || buttons.has('full-screen') || buttons.has('record-audio') || buttons.has('record-video')) { mediaElementContainer.appendChild(volumeControl); } var mediaBox = document.createElement('div'); mediaBox.className = 'media-box'; mediaElementContainer.appendChild(mediaBox); if (config.title) { var h2 = document.createElement('h2'); h2.innerHTML = config.title; h2.setAttribute('style', 'position: absolute;color:white;font-size:12px;text-shadow: 1px 1px black;padding:0;margin:0;text-align: left; margin-top: 10px; margin-left: 10px; display: block; border: 0;line-height:1.5;z-index:1;'); h2.setAttribute('id', 'recording-status'); mediaBox.appendChild(h2); } mediaBox.appendChild(mediaElement); if (!config.width) config.width = (innerWidth / 2) - 50; mediaElementContainer.style.width = config.width + 'px'; if (config.height) { mediaBox.style.height = config.height + 'px'; } mediaBox.querySelector('video').style.maxHeight = innerHeight + 'px'; var times = 0; function adjustControls() { mediaControls.style.marginLeft = (mediaElementContainer.clientWidth - mediaControls.clientWidth - 2) + 'px'; if (slider) { slider.style.width = (mediaElementContainer.clientWidth / 3) + 'px'; volumeControl.style.marginLeft = (mediaElementContainer.clientWidth / 3 - 30) + 'px'; if (zoom) zoom.style['border-top-right-radius'] = '5px'; } else { volumeControl.style.marginLeft = (mediaElementContainer.clientWidth - volumeControl.clientWidth - 2) + 'px'; } volumeControl.style.marginTop = (mediaElementContainer.clientHeight - volumeControl.clientHeight - 2) + 'px'; if (times < 10) { times++; setTimeout(adjustControls, 1000); } else times = 0; } if (config.showOnMouseEnter || typeof config.showOnMouseEnter === 'undefined') { mediaElementContainer.onmouseenter = mediaElementContainer.onmousedown = function () { adjustControls(); mediaControls.style.opacity = 1; volumeControl.style.opacity = 1; }; mediaElementContainer.onmouseleave = function () { mediaControls.style.opacity = 0; volumeControl.style.opacity = 0; }; } else { setTimeout(function () { adjustControls(); setTimeout(function () { mediaControls.style.opacity = 1; volumeControl.style.opacity = 1; }, 300); }, 700); } adjustControls(); mediaElementContainer.toggle = function (clasName) { if (typeof clasName != 'string') { for (var i = 0; i < clasName.length; i++) { mediaElementContainer.toggle(clasName[i]); } return; } if (clasName == 'mute-audio' && muteAudio) muteAudio.onclick(); if (clasName == 'mute-video' && muteVideo) muteVideo.onclick(); if (clasName == 'record-audio' && recordAudio) recordAudio.onclick(); if (clasName == 'record-video' && recordVideo) recordVideo.onclick(); if (clasName == 'stop' && stop) stop.onclick(); return this; }; mediaElementContainer.media = mediaElement; return mediaElementContainer; }