Audio Control Panel

When learning a language, it’s useful to be able to slow down and rewind audio clips in your target language. If the audio goes too fast, then you will miss words and quickly lose track of what’s being discussed. The problem is, many websites don’t allow you to slow down or rewind audio on their page.

I created the Audio Control Panel to give you control over audio clips in news articles on the Voice of Tibet website. The Audio Control Panel allows you to control the playback speed and jump forward or backward in the audio. It is meant to help language learners access the website and use it to train their Tibetan listening skills.

In order to run the program, you have to download a browser extension such as Greasemonkey, Tampermonkey, or Violentmonkey. These extensions allow for userscripts, i.e. custom programs that run on the browser on selected webpages. I developed this extension on Violentmonkey specifically. (If you want to run this program on a phone, you will have to download a mobile browser that allows you to install extensions. I use the Kiwi browser for this. Once you’ve downloaded the browser, you will then have to install one of the aforementioned userscript extensions.)

Once the extension is downloaded, you have to make sure it’s enabled, then open its settings dashboard and click on the + button on screen to add a new script. Click ctrl+A and then backspace to delete the existing //==UserScript== metadata block, and copy-paste the following code in its place:

// ==UserScript==
// @name        Audio Control Panel
// @namespace   Violentmonkey Scripts
// @match       *://vot.org/*
// @grant       none
// @version     1.0
// @author      Nick Prior
// @description 2025-06-06, 4:54:39 p.m.
// ==/UserScript==
// Function to create and insert the audio control panel
function createAudioControlPanel() {
    // Create control panel container
    const controlPanel = document.createElement('div');
    controlPanel.className = 'audio-control-panel';
    controlPanel.style.display = 'flex';
    controlPanel.style.alignItems = 'center';
    controlPanel.style.marginTop = '10px';

    // Create rewind button
    const rewindButton = document.createElement('button');
    rewindButton.id = 'rewind';
    rewindButton.textContent = 'Rewind 3s';
    controlPanel.appendChild(rewindButton);

    // Create fast forward button
    const fastForwardButton = document.createElement('button');
    fastForwardButton.id = 'fastForward';
    fastForwardButton.textContent = 'Fast Forward 3s';
    controlPanel.appendChild(fastForwardButton);

    // Create playback speed label
    const playbackSpeedLabel = document.createElement('label');
    playbackSpeedLabel.textContent = 'Playback Speed:';
    controlPanel.appendChild(playbackSpeedLabel);

    // Create playback speed select
    const playbackSpeedSelect = document.createElement('select');
    playbackSpeedSelect.id = 'playbackSpeed';
    const speeds = [0.5, 0.7, 0.9, 1];
    speeds.forEach(speed => {
        const option = document.createElement('option');
        option.value = speed;
        option.textContent = `${speed}x`;
        playbackSpeedSelect.appendChild(option);
    });
    controlPanel.appendChild(playbackSpeedSelect);

    // Insert the control panel after the first audio element
    const audioElements = document.querySelectorAll('audio');
    if (audioElements.length > 0) {
        audioElements[1].parentNode.insertBefore(controlPanel, audioElements[1].nextSibling);
    }

    // Rewind button functionality
    rewindButton.addEventListener('click', () => {
        const audio = getCurrentAudio();
        if (audio) {
            audio.currentTime = Math.max(0, audio.currentTime - 3);
        }
    });

    // Fast forward button functionality
    fastForwardButton.addEventListener('click', () => {
        const audio = getCurrentAudio();
        if (audio) {
            audio.currentTime = Math.min(audio.duration, audio.currentTime + 3);
        }
    });

    // Playback speed functionality
    playbackSpeedSelect.addEventListener('change', (event) => {
        const audio = getCurrentAudio();
        if (audio) {
            audio.playbackRate = parseFloat(event.target.value);
        }
    });
}

// Function to get the currently playing audio element
function getCurrentAudio() {
    const audioElements = document.querySelectorAll('audio');
    for (let audio of audioElements) {
        if (!audio.paused) {
            return audio;
        }
    }
    return null; // No audio is currently playing
}

// Run the function to create the audio control panel
createAudioControlPanel();

Then save and close the script. You may need to click a toggle button beside the script in the extension’s settings in order to activate it. You can read through the relevant extension’s user guide if you run into any difficulty with these steps.

(Note: if you have trouble following this process, please contact me and I can send you a video showing the steps.)

Result:

In the above image, the buttons saying “Rewind 3s”, “Fast Forward 3s”, and “Playback speed: __x” are added by this extension.

Customizing the program

If you want to change the amount of seconds that you can rewind by, then change the “3” in “audio.currentTime – 3” to whatever number of seconds you want.

If you want to change the amount of seconds that you can fast forward by, then change the “3” in “audio.currentTime + 3” to whatever number of seconds you want.

If you want to change the playback speed options, then change the numbers in “const speeds = [0.5, 0.7, 0.9, 1];” to whatever numbers you want.

Don’t forget to save any changes you make!

If you want the script to run on other websites, or if you want to target different audio files on the site, please hire a web developer for help. The script in its current form is only meant to target one audio file per webpage, and is tailored to the Voice of Tibet website.