From ad6bf930c9d1505040282ca99b781005fb448b40 Mon Sep 17 00:00:00 2001 From: Gerben Date: Sat, 19 Oct 2019 19:14:27 +0530 Subject: [PATCH] Move current code into app/audio-player --- app/audio-player/background.js | 52 ++++++++++++++++++ app/audio-player/contentscript.js | 88 ++++++++++++++++++++++++++++++ app/scripts/background.js | 53 +----------------- app/scripts/contentscript.js | 89 +------------------------------ 4 files changed, 142 insertions(+), 140 deletions(-) create mode 100644 app/audio-player/background.js create mode 100644 app/audio-player/contentscript.js diff --git a/app/audio-player/background.js b/app/audio-player/background.js new file mode 100644 index 0000000..7633c3f --- /dev/null +++ b/app/audio-player/background.js @@ -0,0 +1,52 @@ +import delay from 'delay'; + +async function tryUntilItWorks(func, delayBetweenTries = 1, maxTries = 10) { + for (let i = 0; i < maxTries; i++) { + try { + await func(); + return; + } catch (err) { + await delay(delayBetweenTries); + continue; + } + } +} + +async function onHeadersReceived({ responseHeaders, url, tabId }) { + const isAudio = responseHeaders.some(header => + header.name === 'Content-Type' && header.value.startsWith('audio/') + ); + + if (isAudio) { + // Avoid any short glitch of sound (observed in Firefox) before our injected script executes. + await browser.tabs.update(tabId, { muted: true }); + + // Too quickly executing the script may fail (bug in Firefox), so we retry if necessary. + await tryUntilItWorks(() => browser.tabs.executeScript(tabId, { + runAt: 'document_end', + file: '/scripts/contentscript.js', + })); + + // Unmute again. + await browser.tabs.update(tabId, { muted: false }); + + await tryUntilItWorks(() => browser.tabs.insertCSS(tabId, { + runAt: 'document_end', + file: '/assets/main.css', + })); + + await tryUntilItWorks(() => browser.tabs.insertCSS(tabId, { + runAt: 'document_end', + file: '/assets/waveform-playlist.css', + })); + } +} + +browser.webRequest.onHeadersReceived.addListener( + onHeadersReceived, + { + urls: [''], + types: ['main_frame'], + }, + ['responseHeaders'], +); diff --git a/app/audio-player/contentscript.js b/app/audio-player/contentscript.js new file mode 100644 index 0000000..7df4b95 --- /dev/null +++ b/app/audio-player/contentscript.js @@ -0,0 +1,88 @@ +import * as WaveformPlaylist from 'waveform-playlist'; +import delay from 'delay'; + +async function init() { + document.body.innerHTML = ` +
+
+ +
+ + +
+
+
+
+
+ `; + + const playlist = WaveformPlaylist.init({ + container: document.getElementById('container'), + timescale: true, + waveHeight: 100, + state: 'select', + }); + + const eventEmitter = playlist.getEventEmitter(); + + // Hook up play/pause and volume inputs + const playpauseEl = document.getElementById('playpause'); + const volumeEl = document.getElementById('volume'); + playpauseEl.addEventListener('click', + e => eventEmitter.emit(playlist.isPlaying() ? 'pause' : 'play') + ); + volumeEl.addEventListener('input', + e => eventEmitter.emit("mastervolumechange", e.target.value) + ); + + + // Read target fragment from URL + let start, end; + + async function setFragmentToSelection() { + + const fragmentIdentifier = window.location.hash; + if (fragmentIdentifier) { + const match = fragmentIdentifier.match(/#t=(\d+(?:\.\d+)?)?(?:,(\d+(?:\.\d+)?))?/); + if (match) { + if (match[1] !== undefined) { + start = Number.parseFloat(match[1]); + } + if (match[2] !== undefined) { + end = Number.parseFloat(match[2]); + } + } + } + + // Emit event to update selection in player + eventEmitter.emit('select', start, end); + + } + + + // Bind window hash change to update player + window.addEventListener('hashchange', async function() { + if(playlist.isPlaying()) { + eventEmitter.emit('stop') + // pause needs a small delay, coz the lib doesn't + // update player view (drawRequest) when isPlaying() = true. + await delay(10); + } + await setFragmentToSelection(); + eventEmitter.emit('play'); + }); + + + // Load Playlist + await playlist.load([{ + src: document.URL + }]); + + // update start & end for initial load + setFragmentToSelection(); + + // Start playing. A tiny delay seems needed in Firefox to show the cursor at the right place. + requestAnimationFrame(() => eventEmitter.emit('play')); +} + +init(); diff --git a/app/scripts/background.js b/app/scripts/background.js index 7633c3f..8663d22 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1,52 +1 @@ -import delay from 'delay'; - -async function tryUntilItWorks(func, delayBetweenTries = 1, maxTries = 10) { - for (let i = 0; i < maxTries; i++) { - try { - await func(); - return; - } catch (err) { - await delay(delayBetweenTries); - continue; - } - } -} - -async function onHeadersReceived({ responseHeaders, url, tabId }) { - const isAudio = responseHeaders.some(header => - header.name === 'Content-Type' && header.value.startsWith('audio/') - ); - - if (isAudio) { - // Avoid any short glitch of sound (observed in Firefox) before our injected script executes. - await browser.tabs.update(tabId, { muted: true }); - - // Too quickly executing the script may fail (bug in Firefox), so we retry if necessary. - await tryUntilItWorks(() => browser.tabs.executeScript(tabId, { - runAt: 'document_end', - file: '/scripts/contentscript.js', - })); - - // Unmute again. - await browser.tabs.update(tabId, { muted: false }); - - await tryUntilItWorks(() => browser.tabs.insertCSS(tabId, { - runAt: 'document_end', - file: '/assets/main.css', - })); - - await tryUntilItWorks(() => browser.tabs.insertCSS(tabId, { - runAt: 'document_end', - file: '/assets/waveform-playlist.css', - })); - } -} - -browser.webRequest.onHeadersReceived.addListener( - onHeadersReceived, - { - urls: [''], - types: ['main_frame'], - }, - ['responseHeaders'], -); +import '../audio-player/background.js' diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 7df4b95..e33d912 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -1,88 +1 @@ -import * as WaveformPlaylist from 'waveform-playlist'; -import delay from 'delay'; - -async function init() { - document.body.innerHTML = ` -
-
- -
- - -
-
-
-
-
- `; - - const playlist = WaveformPlaylist.init({ - container: document.getElementById('container'), - timescale: true, - waveHeight: 100, - state: 'select', - }); - - const eventEmitter = playlist.getEventEmitter(); - - // Hook up play/pause and volume inputs - const playpauseEl = document.getElementById('playpause'); - const volumeEl = document.getElementById('volume'); - playpauseEl.addEventListener('click', - e => eventEmitter.emit(playlist.isPlaying() ? 'pause' : 'play') - ); - volumeEl.addEventListener('input', - e => eventEmitter.emit("mastervolumechange", e.target.value) - ); - - - // Read target fragment from URL - let start, end; - - async function setFragmentToSelection() { - - const fragmentIdentifier = window.location.hash; - if (fragmentIdentifier) { - const match = fragmentIdentifier.match(/#t=(\d+(?:\.\d+)?)?(?:,(\d+(?:\.\d+)?))?/); - if (match) { - if (match[1] !== undefined) { - start = Number.parseFloat(match[1]); - } - if (match[2] !== undefined) { - end = Number.parseFloat(match[2]); - } - } - } - - // Emit event to update selection in player - eventEmitter.emit('select', start, end); - - } - - - // Bind window hash change to update player - window.addEventListener('hashchange', async function() { - if(playlist.isPlaying()) { - eventEmitter.emit('stop') - // pause needs a small delay, coz the lib doesn't - // update player view (drawRequest) when isPlaying() = true. - await delay(10); - } - await setFragmentToSelection(); - eventEmitter.emit('play'); - }); - - - // Load Playlist - await playlist.load([{ - src: document.URL - }]); - - // update start & end for initial load - setFragmentToSelection(); - - // Start playing. A tiny delay seems needed in Firefox to show the cursor at the right place. - requestAnimationFrame(() => eventEmitter.emit('play')); -} - -init(); +import '../audio-player/contentscript.js'