From fd5dac0798fae7cc91ff14f2b0752eab525e97ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Velad=20Galv=C3=A1n?= Date: Thu, 26 Feb 2026 10:54:08 +0100 Subject: [PATCH] feat(UI): Add support for chapter images in MediaSession (#9761) Co-authored-by: Theodore Abshire --- lib/net/networking_utils.js | 14 +++++++++++--- ui/media_session.js | 32 ++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/lib/net/networking_utils.js b/lib/net/networking_utils.js index 579f1d042..90ddac743 100644 --- a/lib/net/networking_utils.js +++ b/lib/net/networking_utils.js @@ -22,9 +22,7 @@ shaka.net.NetworkingUtils = class { * @return {!Promise} */ static async getMimeType(uri, netEngine, retryParams) { - const extension = shaka.net.NetworkingUtils.getExtension(uri); - let mimeType = - shaka.net.NetworkingUtils.EXTENSIONS_TO_MIME_TYPES_.get(extension); + let mimeType = shaka.net.NetworkingUtils.getMimeTypeFromUri(uri); if (mimeType) { return mimeType; } @@ -51,6 +49,16 @@ shaka.net.NetworkingUtils = class { return mimeType ? mimeType.toLowerCase().split(';').shift() : ''; } + /** + * @param {string} uri + * @return {string} + */ + static getMimeTypeFromUri(uri) { + const extension = shaka.net.NetworkingUtils.getExtension(uri); + const mimeType = + shaka.net.NetworkingUtils.EXTENSIONS_TO_MIME_TYPES_.get(extension); + return mimeType ?? ''; + } /** * @param {string} uri diff --git a/ui/media_session.js b/ui/media_session.js index fe1a10aad..648a6c486 100644 --- a/ui/media_session.js +++ b/ui/media_session.js @@ -8,6 +8,7 @@ goog.provide('shaka.ui.MediaSession'); goog.require('shaka.log'); goog.require('shaka.ads.Utils'); +goog.require('shaka.net.NetworkingUtils'); goog.require('shaka.util.EventManager'); goog.require('shaka.util.IReleasable'); goog.require('shaka.util.TXml'); @@ -194,7 +195,15 @@ shaka.ui.MediaSession = class { } if (this.supported_) { const metadata = this.getMediaMetadata(); - metadata.artwork = [{src: imageUrl}]; + const artwork = { + src: imageUrl, + }; + const mimeType = + shaka.net.NetworkingUtils.getMimeTypeFromUri(imageUrl); + if (mimeType) { + artwork.type = mimeType; + } + metadata.artwork = [artwork]; navigator.mediaSession.metadata = new MediaMetadata(metadata); } } @@ -209,11 +218,26 @@ shaka.ui.MediaSession = class { } const chapterInfo = []; for (const chapter of chapters) { - chapterInfo.push({ + const info = { title: chapter.title, startTime: chapter.startTime, artwork: [], - }); + }; + for (const imageInfo of chapter.images) { + const artwork = { + src: imageInfo.url, + }; + if (imageInfo.width && imageInfo.height) { + artwork.sizes = `${imageInfo.width}x${imageInfo.height}`; + } + const mimeType = + shaka.net.NetworkingUtils.getMimeTypeFromUri(imageInfo.url); + if (mimeType) { + artwork.type = mimeType; + } + info.artwork.push(artwork); + } + chapterInfo.push(info); } const metadata = this.getMediaMetadata(); metadata.chapterInfo = chapterInfo; @@ -333,7 +357,7 @@ shaka.ui.MediaSession = class { if (!this.config_.mediaSession.handleMetadata) { return; } - this.eventManager_.listen(this.player_, 'trackschanged', () => { + this.eventManager_.listen(this.controls_, 'chaptersupdated', () => { this.setupChapters(this.controls_.getChapters()); }); this.eventManager_.listen(this.player_, 'metadata', (event) => {