diff --git a/packages/webamp-docs/docs/06_API/02_webamp-constructor.md b/packages/webamp-docs/docs/06_API/02_webamp-constructor.md index 1445b811..c242d37e 100644 --- a/packages/webamp-docs/docs/06_API/02_webamp-constructor.md +++ b/packages/webamp-docs/docs/06_API/02_webamp-constructor.md @@ -237,6 +237,22 @@ const webamp = new Webamp({ }); ``` +### `enableMediaSession` + +Have Webamp attempt to connect to the browser's [Media Session +API](https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API). +**Default:** `false`. + +This allows OS/hardware level media controls like play/pause/next/previous +and lock screen "current track" information to work with Webamp. + +```ts +const webamp = new Webamp({ + enableMediaSession: true, + // ...other config options +}); +``` + ### `__butterchurnOptions` Webamp's Milkdrop window is powered by the third party library [Butterchurn](https://butterchurnviz.com/). Getting Butterchurn to work with Webamp requires some additional configuration which is still a bit fiddly, but is possible. For a full working example, see the [Butterchurn Example](https://github.com/captbaritone/webamp/tree/master/examples/minimalMilkdrop). diff --git a/packages/webamp-docs/docs/06_API/03_instance-methods.md b/packages/webamp-docs/docs/06_API/03_instance-methods.md index 2ec6ce2e..d0cf9c92 100644 --- a/packages/webamp-docs/docs/06_API/03_instance-methods.md +++ b/packages/webamp-docs/docs/06_API/03_instance-methods.md @@ -216,8 +216,12 @@ Returns an "unsubscribe" function. **Note:** If the user drags in a track, the URL may be an [ObjectURL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL) ```ts -const unsubscribe = webamp.onTrackDidChange((track => { - console.log("New track playing:", track.url); +const unsubscribe = webamp.onTrackDidChange((track) => { + if (track == null) { + document.title = "Webamp"; + } else { + document.title = `${track.metaData.title} - ${track.metaData.artist} \u00B7 Webamp`; + } }); // If at some point in the future you want to stop listening to these events: diff --git a/packages/webamp-docs/docs/07_guides/03_bundle-size.md b/packages/webamp-docs/docs/07_guides/03_bundle-size.md index d724700f..5817e03a 100644 --- a/packages/webamp-docs/docs/07_guides/03_bundle-size.md +++ b/packages/webamp-docs/docs/07_guides/03_bundle-size.md @@ -5,7 +5,7 @@ By default the Webamp import/bundle includes a few heavy dependencies. `JSZip` f First you'll need to install the dependencies in your project: ```bash -npm install jszip music-metadata-browser@^0.6.1 +npm install jszip music-metadata-browser@^0.6.6 ``` The "lazy" version of Webamp will require that you inject functions for lazily importing these dependencies. diff --git a/packages/webamp/CHANGELOG.md b/packages/webamp/CHANGELOG.md index f61507c1..8f31ab6b 100644 --- a/packages/webamp/CHANGELOG.md +++ b/packages/webamp/CHANGELOG.md @@ -1,6 +1,8 @@ ## Upcoming [UNRELEASED] (`webamp@next`) -_No changes yet._ +### Improvements + +- Add new config option `enableMediaSession` to allow Webamp to connect to the browser's Media Session API. This enables OS/hardware level media controls like play/pause/next/previous. ## 2.1.2 [CURRENT] diff --git a/packages/webamp/demo/js/index.tsx b/packages/webamp/demo/js/index.tsx index 82115a85..ab86d6f4 100644 --- a/packages/webamp/demo/js/index.tsx +++ b/packages/webamp/demo/js/index.tsx @@ -17,7 +17,6 @@ import { import { disableMarquee, skinUrl as configSkinUrl } from "./config"; import DemoDesktop from "./DemoDesktop"; -import enableMediaSession from "./mediaSession"; // import { choreograph } from "./choreography"; declare global { @@ -133,8 +132,6 @@ async function main() { : `${track.metaData.title} - ${track.metaData.artist} \u00B7 ${DEFAULT_DOCUMENT_TITLE}`; }); - enableMediaSession(webamp); - // Expose a file input in the DOM for testing. const fileInput = document.createElement("input"); fileInput.id = "webamp-file-input"; diff --git a/packages/webamp/demo/js/webampConfig.ts b/packages/webamp/demo/js/webampConfig.ts index 01be1233..b2941a0d 100644 --- a/packages/webamp/demo/js/webampConfig.ts +++ b/packages/webamp/demo/js/webampConfig.ts @@ -111,6 +111,7 @@ export async function getWebampConfig( windowLayout, filePickers: [dropboxFilePicker], enableHotkeys: true, + enableMediaSession: true, handleTrackDropEvent: (e) => { const trackJson = e.dataTransfer.getData("text/json"); if (trackJson == null) { diff --git a/packages/webamp/docs/architecture.md b/packages/webamp/docs/architecture.md index 3b45bdee..d1082031 100644 --- a/packages/webamp/docs/architecture.md +++ b/packages/webamp/docs/architecture.md @@ -93,7 +93,7 @@ Moving windows when their neighbors are resized via "double" or "shade" mode tog 1. Computing a graph where each window is a node, and the edges are where those windows are "touching". 2. Dispatching the passed in action. -3. Looking at the new sizes, and dispatching another event to move the windows to new locations where the original edeges are all still touching. +3. Looking at the new sizes, and dispatching another event to move the windows to new locations where the original edges are all still touching. ## Dropping files diff --git a/packages/webamp/docs/usage.md b/packages/webamp/docs/usage.md index 94f00509..0a1f052b 100644 --- a/packages/webamp/docs/usage.md +++ b/packages/webamp/docs/usage.md @@ -1,3 +1,3 @@ # Usage -This doc has moved to the Webamps doc page. +This doc has moved to the [Webamp's doc page](https://docs.webamp.org). diff --git a/packages/webamp/demo/js/mediaSession.ts b/packages/webamp/js/mediaSession.ts similarity index 97% rename from packages/webamp/demo/js/mediaSession.ts rename to packages/webamp/js/mediaSession.ts index 1773f53d..306e88e3 100644 --- a/packages/webamp/demo/js/mediaSession.ts +++ b/packages/webamp/js/mediaSession.ts @@ -1,4 +1,4 @@ -import type WebampLazy from "../../js/webampLazy"; +import type WebampLazy from "./webampLazy"; export default function enableMediaSession(webamp: WebampLazy) { if ("mediaSession" in navigator) { diff --git a/packages/webamp/js/types.ts b/packages/webamp/js/types.ts index e0d41fa9..70b4d021 100644 --- a/packages/webamp/js/types.ts +++ b/packages/webamp/js/types.ts @@ -716,6 +716,16 @@ export interface Options { handleAddUrlEvent?: () => Track[] | null | Promise; handleLoadListEvent?: () => Track[] | null | Promise; handleSaveListEvent?: (tracks: Track[]) => null | Promise; + + /** + * Have Webamp attempt to connect to the browser's media session API. + * + * This allows OS/hardware level media controls like play/pause/next/previous + * and lock screen "current track" information to work with Webamp. + * + * https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API + */ + enableMediaSession?: boolean; } /** diff --git a/packages/webamp/js/webampLazy.tsx b/packages/webamp/js/webampLazy.tsx index 4d9cb0ec..22a2aea6 100644 --- a/packages/webamp/js/webampLazy.tsx +++ b/packages/webamp/js/webampLazy.tsx @@ -39,6 +39,7 @@ import Emitter from "./emitter"; import { SerializedStateV1 } from "./serializedStates/v1Types"; import Disposable from "./Disposable"; +import enableMediaSession from "./mediaSession.js"; export interface PrivateOptions { __initialState?: PartialState; @@ -100,6 +101,10 @@ class Webamp { __customMediaClass, } = this.options; + if (options.enableMediaSession) { + enableMediaSession(this); + } + // TODO: Make this much cleaner let convertPreset = null; if (__butterchurnOptions != null) {