Skip to content

Commit

Permalink
feat: Play audio when timer ends, via Chromium offscreen API (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
nfreear committed Aug 28, 2024
1 parent 4b6bef1 commit 3db0141
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
4 changes: 4 additions & 0 deletions build/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const TEMPLATE = {
background: {
// scripts: ['lib/service-worker.js'],
// service_worker: 'lib/service-worker.js'
type: 'module'
},

action: {
Expand Down Expand Up @@ -83,7 +84,10 @@ const MANIFEST = IS_GECKO ? { ...TEMPLATE, ...GECKO } : TEMPLATE;
if (IS_GECKO) {
MANIFEST.background.scripts = [SERVICE_WORKER];
} else {
// Chromium-specific.
MANIFEST.background.service_worker = SERVICE_WORKER;

MANIFEST.permissions.push('offscreen');
}

const jsonData = JSON.stringify(MANIFEST, null, 2);
Expand Down
14 changes: 14 additions & 0 deletions lib/offscreen-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

const BROWSER = globalThis.browser || globalThis.chrome;

const AUDIO = document.querySelector('#audio');

BROWSER.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.type === 'audio:play') {
AUDIO.play();
console.debug('OP - audio:play received:', msg);
sendResponse('offscreen page - audio:play received');
}
});

console.debug('offscreen-page.js');
56 changes: 56 additions & 0 deletions lib/offscreenAudio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
*
* © NDF, 28-August-2024.
* @see https://developer.chrome.com/docs/extensions/reference/api/offscreen
*/

const BROWSER = globalThis.browser || globalThis.chrome;
const OFFSCREEN_PAGE = '/pages/off_screen.html';

let creating; // A global promise to avoid concurrency issues

async function setupOffscreenDocument (path) {
// Check all windows controlled by the service worker to see if one
// of them is the offscreen document with the given path
const offscreenUrl = BROWSER.runtime.getURL(path);
const existingContexts = await BROWSER.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [offscreenUrl]
});

if (existingContexts.length > 0) {
return;
}

// create offscreen document
if (creating) {
await creating;
} else {
creating = BROWSER.offscreen.createDocument({
url: path,
reasons: ['AUDIO_PLAYBACK'], // ['CLIPBOARD'],
justification: 'to play a sound when the timer stops'
});
await creating;
creating = null;
}
}

function hasOffscreenApi () {
return BROWSER.offscreen && BROWSER.offscreen.createDocument;
}

export async function offscreenAudio () {
if (!hasOffscreenApi) {
return console.debug('Offscreen API not supported.');
}
await setupOffscreenDocument(OFFSCREEN_PAGE);

// Send message to offscreen document
const send = BROWSER.runtime.sendMessage({
type: 'audio:play',
target: 'offscreen',
data: '...'
});
send.then((msg) => console.debug('offscreenAudio:', msg));
}
8 changes: 8 additions & 0 deletions lib/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
© NDF, 26-July-2024.
*/

import { offscreenAudio } from './OffscreenAudio.js';

const DURATION = {
default: 10
};
Expand Down Expand Up @@ -92,6 +94,7 @@ class WorkerTimer {
this._postMessage({ type: 'timer:ping', value, duration: this._duration });

await this._createNotification(`Timer started: ${value}`);
await this._playAudio();

console.debug('WT ~ Sending timer:started', value);
} // IF.
Expand Down Expand Up @@ -121,6 +124,7 @@ class WorkerTimer {
// WAS: chrome.runtime.sendMessage({ type: 'timer:stopped', value: '00:00' });

await this._createNotification('Timer stopped!');
await this._playAudio();

console.debug('WT ~ Sending timer:stopped');
}
Expand All @@ -141,6 +145,10 @@ class WorkerTimer {
message
});
}

async _playAudio () {
await offscreenAudio();
}
}

const workerTimer = new WorkerTimer();
Expand Down
21 changes: 21 additions & 0 deletions pages/off_screen.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!doctype html>
<html lang="html">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title> Off-screen audio — My Pomodoro </title>

<h1> Off-screen audio — My Pomodoro </h1>

<audio
id="audio"
controls
src="https://upload.wikimedia.org/wikipedia/commons/6/68/Bicycle-bell-1.wav"
>
</audio>
<p>
<a href="https://commons.wikimedia.org/wiki/File:Bicycle-bell-1.wav"
>Bicycle-bell-1.wav — License: CC0 1.0</a>
</p>

<script src="../lib/offscreen-page.js"></script>
</html>

0 comments on commit 3db0141

Please sign in to comment.