-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Play audio when timer ends, via Chromium offscreen API (#8)
- Loading branch information
Showing
5 changed files
with
103 additions
and
0 deletions.
There are no files selected for viewing
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
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
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'); |
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
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)); | ||
} |
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
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
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> |