Last active
June 5, 2021 13:07
-
-
Save thihxm/d29042cdeb01fa68a09ead18d01f397f to your computer and use it in GitHub Desktop.
Volume & Speed Slider for BB Collaborate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Volume & Speed Slider BB Collaborate | |
// @namespace thihxm | |
// @match *://*.bbcollab.com/collab/ui/session/* | |
// @match *://*.bbcollab.com/guest/* | |
// @downloadURL https://gist.githubusercontent.com/thihxm/d29042cdeb01fa68a09ead18d01f397f/raw/VolumeSliderBBCollab.js | |
// @run-at document-idle | |
// @grant none | |
// @version 2.0.3 | |
// @author thihxm | |
// @description Adiciona um slider de volume nas aulas ao vivo do BlackBoard Collaborate e um controle de velocidade nas gravações | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
const head = document.querySelector('head'); | |
const body = document.querySelector('body'); | |
const style = document.createElement('style'); | |
style.type = 'text/css'; | |
const css = '#custom-bbcollab-volume-slider-wrapper {'+ | |
'position: relative;'+ | |
'}'+ | |
'#custom-bbcollab-volume-slider-value {'+ | |
'position: absolute;'+ | |
'top: -150%;'+ | |
'opacity: 0;'+ | |
'transition: opacity 0.2s linear;'+ | |
'}'+ | |
'#custom-bbcollab-volume-slider-value span {'+ | |
'width: 30px;'+ | |
'height: 24px;'+ | |
'line-height: 24px;'+ | |
'text-align: center;'+ | |
'background: #0575ff;'+ | |
'color: #fff;'+ | |
'font-size: 12px;'+ | |
'display: block;'+ | |
'position: absolute;'+ | |
'left: 50%;'+ | |
'transform: translate(-50%, 0);'+ | |
'border-radius: 6px;'+ | |
'}'+ | |
'#custom-bbcollab-volume-slider-value span:before {'+ | |
'content: "";'+ | |
'position: absolute;'+ | |
'width: 0;'+ | |
'height: 0;'+ | |
'border-top: 10px solid #0575ff;'+ | |
'border-left: 5px solid transparent;'+ | |
'border-right: 5px solid transparent;'+ | |
'top: 100%;'+ | |
'left: 50%;'+ | |
'margin-left: -5px;'+ | |
'margin-top: -1px;'+ | |
'}'+ | |
'#custom-bbcollab-speed-changer {'+ | |
'position: relative;'+ | |
'}'+ | |
'#custom-bbcollab-speed-slider-wrapper {'+ | |
'position: absolute;'+ | |
'z-index: 10;'+ | |
'visibility: visible;'+ | |
'border: 1px solid #cdcdcd;'+ | |
'border-radius: .125rem;'+ | |
'background-color: #fff;'+ | |
'font-size: .875rem;'+ | |
'box-shadow: 0 0 0 4px rgba(38,38,38,.075);'+ | |
'padding: 0;'+ | |
'display: flex;'+ | |
'flex-direction: row;'+ | |
'align-items: center;'+ | |
'height: 1.875rem;'+ | |
'width: 8.875rem;'+ | |
'margin-top: -2rem;'+ | |
'color: #262626;'+ | |
'outline: none!important;'+ | |
'top: calc(50% - 8.875rem / 2);'+ | |
'left: calc(50% - 8.875rem / 2);'+ | |
'transform: rotate(-90deg);'+ | |
'}'+ | |
'#custom-bbcollab-speed-slider-wrapper.isHidden {'+ | |
'visibility: hidden;'+ | |
'display: none;'+ | |
'}'+ | |
'#custom-bbcollab-speed-slider {'+ | |
'transform: translateX(-50%);'+ | |
'left: 50%;'+ | |
'position: relative;'+ | |
'}'+ | |
'#custom-bbcollab-speed-slider-value {'+ | |
'position: absolute;'+ | |
'top: 150%;'+ | |
'opacity: 0;'+ | |
'transition: opacity 0.2s linear;'+ | |
'}'+ | |
'#custom-bbcollab-speed-slider-value span {'+ | |
'width: 40px;'+ | |
'height: 24px;'+ | |
'line-height: 24px;'+ | |
'text-align: center;'+ | |
'background: #0575ff;'+ | |
'color: #fff;'+ | |
'font-size: 12px;'+ | |
'display: block;'+ | |
'position: absolute;'+ | |
'left: 50%;'+ | |
'transform: translate(-50%, 0) rotate(90deg);'+ | |
'border-radius: 6px;'+ | |
'}'+ | |
'#custom-bbcollab-speed-slider-value span:before {'+ | |
'content: "";'+ | |
'position: absolute;'+ | |
'width: 0;'+ | |
'height: 0;'+ | |
'border-top: 10px solid #0575ff;'+ | |
'border-left: 5px solid transparent;'+ | |
'border-right: 5px solid transparent;'+ | |
'top: 50%;'+ | |
'right: 100%;'+ | |
'margin-right: -1px;'+ | |
'margin-top: -5px;'+ | |
'transform: rotate(90deg);'+ | |
'}'; | |
style.appendChild(document.createTextNode(css)); | |
head.appendChild(style); | |
const waitForEl = (selector, callback) => { | |
const element = document.querySelector(selector); | |
if (element) { | |
callback(element); | |
} else { | |
setTimeout(function() { | |
waitForEl(selector, callback); | |
}, 100); | |
} | |
}; | |
const changeVolume = (volume) => { | |
document.querySelectorAll('audio').forEach(audioEl => { | |
audioEl.volume = volume; | |
}); | |
document.querySelectorAll('video').forEach(videoEl => { | |
videoEl.volume = volume; | |
}); | |
} | |
const handleVolumeChange = (volumeSlider, volumeValueDisplay) => { | |
volumeSlider.addEventListener('input', e => { | |
const slider = e.target; | |
const sliderValue = e.target.value; | |
const newValue = Number( (sliderValue - slider.min) * 100 / (slider.max - slider.min) ); | |
const newPosition = 10 - (newValue * 0.2); | |
volumeValueDisplay.innerHTML = `<span>${Math.floor(sliderValue * 100)}</span>`; | |
volumeValueDisplay.style.left = `calc(${newValue}% + (${newPosition}px))`; | |
localStorage.setItem('thihxm/bb_volume', sliderValue * 100); | |
changeVolume(sliderValue); | |
}); | |
} | |
const toggleVolumeTooltipEvents = (volumeSlider, volumeValueDisplay) => { | |
volumeSlider.addEventListener('mouseup', e => { | |
volumeValueDisplay.style.opacity = 0; | |
}); | |
volumeSlider.addEventListener('mousedown', e => { | |
volumeValueDisplay.style.opacity = 1; | |
}); | |
} | |
if (body) { | |
if (window.location.pathname.includes("playback")) { | |
const playback_volume_slider_selector = '.playback-controls .playback-controls__volume-slider'; | |
waitForEl(playback_volume_slider_selector, playback_volume_slider => { | |
const speedChangerWrapper = document.createElement('div'); | |
const speedSliderButton = document.createElement('button'); | |
const speedSliderWrapper = document.createElement('div'); | |
const speedSlider = document.createElement('input'); | |
const speedValueDisplay = document.createElement('div'); | |
const buttonIcon = document.createElement('bb-svg-icon'); | |
const buttonTooltip = document.createElement('span'); | |
const buttonTooltipContent = document.createElement('span'); | |
buttonIcon.classList.add('playback-controls__icon'); | |
buttonIcon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="16px" height="16px"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44zm-9.79 6.84a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/></svg>'; | |
buttonTooltip.classList.add('tooltip'); | |
buttonTooltip.classList.add('tip-top-right'); | |
buttonTooltip.setAttribute('role', 'tooltip'); | |
buttonTooltipContent.classList.add('tooltip-content'); | |
buttonTooltipContent.innerHTML = 'Velocidade de reprodução'; | |
buttonTooltip.appendChild(buttonTooltipContent); | |
speedChangerWrapper.id = 'custom-bbcollab-speed-changer'; | |
speedSliderButton.id = 'speed-dropdown-toggle'; | |
speedSliderButton.classList.add('playback-controls__button'); | |
speedSliderButton.classList.add('button'); | |
speedSliderButton.classList.add('has-tooltip'); | |
speedSliderButton.appendChild(buttonIcon); | |
speedSliderButton.appendChild(buttonTooltip); | |
speedSliderWrapper.id = 'custom-bbcollab-speed-slider-wrapper'; | |
speedSliderWrapper.classList.add('isHidden'); | |
speedValueDisplay.id = 'custom-bbcollab-speed-slider-value'; | |
speedSlider.id = 'custom-bbcollab-speed-slider'; | |
speedSlider.type = 'range'; | |
speedSlider.min = 0.25; | |
speedSlider.max = 5; | |
speedSlider.step = 0.25; | |
speedSlider.value = 1; | |
document.addEventListener('click', e => { | |
if (speedSliderButton.contains(e.target)) { | |
speedSliderWrapper.classList.toggle('isHidden'); | |
} else if (!speedSliderWrapper.contains(e.target)) { | |
speedSliderWrapper.classList.add('isHidden'); | |
} | |
}); | |
speedSlider.addEventListener('input', e => { | |
const slider = e.target; | |
const sliderValue = e.target.value; | |
const newValue = Number( (sliderValue - slider.min) * 100 / (slider.max - slider.min) ); | |
const newPosition = 12 - (newValue * 0.25); | |
speedValueDisplay.innerHTML = `<span>${sliderValue}x</span>`; | |
speedValueDisplay.style.left = `calc(${newValue}% + (${newPosition}px))`; | |
document.querySelector('video').playbackRate = sliderValue; | |
}); | |
speedSlider.addEventListener('mouseup', e => { | |
speedValueDisplay.style.opacity = 0; | |
}); | |
speedSlider.addEventListener('mousedown', e => { | |
speedValueDisplay.style.opacity = 1; | |
}); | |
speedSliderWrapper.appendChild(speedSlider); | |
speedSliderWrapper.appendChild(speedValueDisplay); | |
speedChangerWrapper.appendChild(speedSliderButton); | |
speedChangerWrapper.appendChild(speedSliderWrapper); | |
playback_volume_slider.parentNode.insertBefore(speedChangerWrapper, playback_volume_slider.nextSibling); | |
}); | |
} else { | |
const volumeSliderWrapper = document.createElement('div'); | |
const volumeSlider = document.createElement('input'); | |
const volumeValueDisplay = document.createElement('div'); | |
const volume = (localStorage.getItem('thihxm/bb_volume')/100) || 1; | |
volumeSliderWrapper.id = 'custom-bbcollab-volume-slider-wrapper'; | |
volumeValueDisplay.id = 'custom-bbcollab-volume-slider-value'; | |
volumeSlider.id = 'custom-bbcollab-volume-slider'; | |
volumeSlider.type = 'range' | |
volumeSlider.min = 0; | |
volumeSlider.max = 1; | |
volumeSlider.step = 0.02; | |
volumeSlider.value = volume; | |
handleVolumeChange(volumeSlider, volumeValueDisplay); | |
toggleVolumeTooltipEvents(volumeSlider, volumeValueDisplay); | |
changeVolume(volume); | |
volumeSliderWrapper.appendChild(volumeValueDisplay); | |
volumeSliderWrapper.appendChild(volumeSlider); | |
const observer = new MutationObserver(function(mutations) { | |
mutations.forEach(function(mutation) { | |
const addedNodes = mutation.addedNodes; | |
addedNodes.forEach(newNode => { | |
const nodeName = newNode.nodeName.toLowerCase(); | |
if (nodeName === 'audio' || nodeName === 'video') { | |
const volumeSlider = document.querySelector('#custom-bbcollab-volume-slider'); | |
console.log('New Audio/Video Element'); | |
newNode.volume = volume; | |
handleVolumeChange(volumeSlider, volumeValueDisplay); | |
toggleVolumeTooltipEvents(volumeSlider, volumeValueDisplay); | |
} | |
}); | |
}); | |
var controlsContainer = document.querySelector('.controls-container'); | |
if (controlsContainer && volumeSliderWrapper.parentNode != controlsContainer) { | |
controlsContainer.appendChild(volumeSliderWrapper); | |
return; | |
} | |
}); | |
const observerConfig = { | |
childList: true, | |
subtree: true, | |
}; | |
document.addEventListener("DOMContentLoaded", () => { | |
const newValue = Number( (volumeSlider.value - volumeSlider.min) * 100 / (volumeSlider.max - volumeSlider.min) ); | |
const newPosition = 10 - (newValue * 0.2); | |
volumeValueDisplay.innerHTML = `<span>${Math.floor(volumeSlider.value * 100)}</span>`; | |
volumeValueDisplay.style.left = `calc(${newValue}% + (${newPosition}px))`; | |
}); | |
observer.observe(body, observerConfig); | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment