Skip to content
This repository has been archived by the owner on Jul 9, 2024. It is now read-only.

Commit

Permalink
feat: amplify video volume
Browse files Browse the repository at this point in the history
  • Loading branch information
adil192 committed May 2, 2024
1 parent ea93235 commit fec4f35
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const scripts = <String, List<String>>{
'*://online.manchester.ac.uk/ultra',
'*://online.manchester.ac.uk/ultra/*'
],
'amplify_videos': ['*://video.manchester.ac.uk/embedded/*'],
'auto_login': ['*://login.manchester.ac.uk/cas/login*'],
'expand_menu': ['*://online.manchester.ac.uk/webapps/blackboard/content/*'],
'save_scroll_pos': ['*://leanpub.com/*/read*'],
Expand Down
1 change: 1 addition & 0 deletions src/assets/ear-listen-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 104 additions & 0 deletions src/scripts/amplify_videos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/// Adds a button to videos to amplify the volume

// @ts-check

(async function() {
'use strict';

/** @type {MediaElementAudioSourceNode | null} */
let audioContextSource = null;
/** @type {GainNode | null} */
let audioContextGain = null;
/** @type {HTMLButtonElement | null} */
let amplifyButton = null;

const maxGain = 10;

function setupAudioContext() {
if (!video) return;
if (audioContextSource?.mediaElement === video) return;

const audioContext = new AudioContext();
audioContextSource = audioContext.createMediaElementSource(video);
audioContextGain = audioContext.createGain();

audioContextSource.connect(audioContextGain);
audioContextGain.connect(audioContext.destination);
}

function addAmplifyButton() {
/** @type {HTMLDivElement | null} */
const volumeButton = document.querySelector('.vjs-volume-menu-button');
if (!volumeButton) return;
const controlBar = volumeButton.parentElement;
if (!controlBar) return;

/** @type {HTMLButtonElement | null} */
amplifyButton = controlBar.querySelector('.vjs-amplify-control');
if (!amplifyButton) {
amplifyButton = document.createElement('button');
amplifyButton.className = "vjs-amplify-control vjs-control vjs-button";
amplifyButton.type = "button";
amplifyButton.title = "Amplify volume";

const amplifyButtonSpan = document.createElement('span');
amplifyButtonSpan.className = "vjs-control-text";
amplifyButtonSpan.innerText = "Amplify volume";
amplifyButton.appendChild(amplifyButtonSpan);

amplifyButton.setAttribute('aria-valuemin', '1');
amplifyButton.setAttribute('aria-valuemax', `${maxGain}`);
updateButton();
}
// left click
amplifyButton.onclick = onAmplifyButtonClick;
// right click
amplifyButton.oncontextmenu = onAmplifyButtonRightClick;
console.log('Amplify button:', amplifyButton);

controlBar.insertBefore(amplifyButton, volumeButton.nextSibling);
}

function onAmplifyButtonClick() {
console.log('Amplifying volume');
if (!audioContextGain) return;

let gain = Math.round(audioContextGain.gain.value);
gain = (gain < maxGain) ? (gain + 1) : 1;

audioContextGain.gain.value = gain;
updateButton();
}

/** @param {MouseEvent} e */
function onAmplifyButtonRightClick(e) {
console.log('Unamplifying volume');
if (!audioContextGain) return;
e.preventDefault();

let gain = Math.round(audioContextGain.gain.value);
gain = (gain > 1) ? (gain - 1) : maxGain;

audioContextGain.gain.value = gain;
updateButton();
}

function updateButton() {
if (!amplifyButton) return;
const gain = audioContextGain?.gain.value || 1.0;

amplifyButton?.setAttribute('aria-valuenow', `${gain}`);
amplifyButton?.setAttribute('aria-valuetext', `${gain}`);
}

/** @type {HTMLVideoElement | null} */
let video = document.querySelector('video');
while (!video) {
await new Promise(resolve => setTimeout(resolve, 500));
video = document.querySelector('video');
console.log('Found video:', video);
}
console.log('Video found:', video);
setupAudioContext();
addAmplifyButton();
})();
30 changes: 30 additions & 0 deletions src/styles/video.manchester.ac.uk.scss
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,36 @@ video,
flex: none;
}

.vjs-amplify-control[aria-valuetext] {
background: url("../assets/ear-listen-solid.svg") no-repeat center !important;
background-size: 1.3em !important;
background-position-y: 40% !important;
cursor: pointer;
flex: none;

&::before {
all: unset;
content: attr(aria-valuetext);
display: block;
font-size: 1.25em;
position: absolute;
bottom: 15%;
left: 60%;
}
&[aria-valuetext="1"] {
opacity: 0.5;
&::before {
content: "";
}
}

@for $i from 2 through 10 {
&[aria-valuetext="#{$i}"] {
opacity: calc(0.8 + 0.2 * $i / 10);
}
}
}

/* in fullscreen, use a better scaling algorithm */
:fullscreen video,
video:fullscreen {
Expand Down

0 comments on commit fec4f35

Please sign in to comment.