From 3dd141915e3fa91c5c166cacd2bc3d67f70a5187 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Wed, 15 Apr 2020 07:54:33 +0200 Subject: [PATCH 01/10] Use full image for MediaSession --- src/components/playback/mediasession.js | 41 ++++++++----------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index c03420c85a..dbc2dcc9ba 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -11,13 +11,12 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f var currentPlayer; var lastUpdateTime = 0; - function seriesImageUrl(item, options) { + function seriesImageUrl(item, options = {}) { if (item.Type !== 'Episode') { return null; } - options = options || {}; options.type = options.type || "Primary"; if (options.type === 'Primary') { @@ -49,9 +48,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f return null; } - function imageUrl(item, options) { - - options = options || {}; + function imageUrl(item, options = {}) { options.type = options.type || "Primary"; if (item.ImageTags && item.ImageTags[options.type]) { @@ -69,29 +66,26 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f return null; } - function pushImageUrl(item, imageOptions, list) { + function pushImageUrl(item, imageOptions = {}) { var url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions); if (url) { var height = imageOptions.height || imageOptions.maxHeight; - list.push({ + return { src: url, sizes: height + 'x' + height - }); + }; } } function getImageUrls(item) { - var list = []; + const imageSizes = [96, 128, 192, 256, 384, 512]; - pushImageUrl(item, {height: 96}, list); - pushImageUrl(item, {height: 128}, list); - pushImageUrl(item, {height: 192}, list); - pushImageUrl(item, {height: 256}, list); - pushImageUrl(item, {height: 384}, list); - pushImageUrl(item, {height: 512}, list); + imageSizes.forEach((size) => { + list.push(pushImageUrl(item, {height: size})); + }); return list; } @@ -127,11 +121,6 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f var parts = nowPlayingHelper.getNowPlayingNames(item); var artist = parts[parts.length - 1].text; var title = parts.length === 1 ? '' : parts[0].text; - var albumArtist; - - if (item.AlbumArtists && item.AlbumArtists[0]) { - albumArtist = item.AlbumArtists[0].Name; - } var album = item.Album || ''; var itemId = item.Id; @@ -143,22 +132,16 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f var isPaused = playState.IsPaused || false; var canSeek = playState.CanSeek || false; - if (navigator.mediaSession) { + if ('mediaSession' in navigator) { navigator.mediaSession.metadata = new MediaMetadata({ title: title, artist: artist, album: album, - artwork: getImageUrls(item), - albumArtist: albumArtist, - currentTime: currentTime, - duration: duration, - paused: isPaused, - itemId: itemId, - mediaType: item.MediaType + artwork: getImageUrls(item) }); } else { var imageUrl = []; - pushImageUrl(item, {maxHeight: 400}, imageUrl); + imageUrl.push(pushImageUrl(item)); if (imageUrl.length) { imageUrl = imageUrl[0].src; From 9bcb270942ea8f4c3c5380138fab089028f898bf Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Wed, 15 Apr 2020 08:14:08 +0200 Subject: [PATCH 02/10] More MediaSession cleanup --- src/components/playback/mediasession.js | 73 ++++++------------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index dbc2dcc9ba..d77b02474a 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -9,36 +9,20 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f // Reports media playback to the device for lock screen control var currentPlayer; - var lastUpdateTime = 0; - - function seriesImageUrl(item, options = {}) { + function seriesImageUrl(item, options = {}, type = options.type || 'Primary') { if (item.Type !== 'Episode') { return null; - } - - options.type = options.type || "Primary"; - - if (options.type === 'Primary') { - - if (item.SeriesPrimaryImageTag) { - - options.tag = item.SeriesPrimaryImageTag; - - return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); - } - } - - if (options.type === 'Thumb') { + } else if (type === 'Primary' && item.SeriesPrimaryImageTag) { + options.tag = item.SeriesPrimaryImageTag; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); + } else if (type === 'Thumb') { if (item.SeriesThumbImageTag) { - options.tag = item.SeriesThumbImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); - } - if (item.ParentThumbImageTag) { - + } else if (item.ParentThumbImageTag) { options.tag = item.ParentThumbImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options); @@ -48,18 +32,14 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f return null; } - function imageUrl(item, options = {}) { - options.type = options.type || "Primary"; + function imageUrl(item, options = {}, type = options.type || 'Primary') { + if (item.ImageTags && item.ImageTags[type]) { + options.tag = item.ImageTags[type]; - if (item.ImageTags && item.ImageTags[options.type]) { - - options.tag = item.ImageTags[options.type]; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.Id, options); - } - - if (item.AlbumId && item.AlbumPrimaryImageTag) { - + } else if (item.AlbumId && item.AlbumPrimaryImageTag) { options.tag = item.AlbumPrimaryImageTag; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options); } @@ -79,9 +59,8 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } } - function getImageUrls(item) { + function getImageUrls(item, imageSizes = [96, 128, 192, 256, 384, 512]) { var list = []; - const imageSizes = [96, 128, 192, 256, 384, 512]; imageSizes.forEach((size) => { list.push(pushImageUrl(item, {height: size})); @@ -166,37 +145,25 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } function onGeneralEvent(e) { + var state = playbackManager.getPlayerState(this); - var player = this; - var state = playbackManager.getPlayerState(player); - - updatePlayerState(player, state, e.type); + updatePlayerState(this, state, e.type); } function onStateChanged(e, state) { - - var player = this; - updatePlayerState(player, state, 'statechange'); + updatePlayerState(this, state, 'statechange'); } function onPlaybackStart(e, state) { - - var player = this; - - updatePlayerState(player, state, e.type); + updatePlayerState(this, state, e.type); } - function onPlaybackStopped(e, state) { - - var player = this; - + function onPlaybackStopped() { hideMediaControls(); } function releaseCurrentPlayer() { - if (currentPlayer) { - events.off(currentPlayer, 'playbackstart', onPlaybackStart); events.off(currentPlayer, 'playbackstop', onPlaybackStopped); events.off(currentPlayer, 'unpause', onGeneralEvent); @@ -211,8 +178,6 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } function hideMediaControls() { - lastUpdateTime = 0; - if (navigator.mediaSession) { navigator.mediaSession.metadata = null; } else { @@ -221,7 +186,6 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } function bindToPlayer(player) { - releaseCurrentPlayer(); if (!player) { @@ -244,8 +208,8 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f function execute(name) { playbackManager[name](currentPlayer); } - if (navigator.mediaSession) { + if (navigator.mediaSession) { navigator.mediaSession.setActionHandler('previoustrack', function () { execute('previousTrack'); }); @@ -272,7 +236,6 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } events.on(playbackManager, 'playerchange', function () { - bindToPlayer(playbackManager.getCurrentPlayer()); }); From af7c87b9f64a7c3ca964a377f26dad2afb34dacc Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Wed, 15 Apr 2020 08:49:46 +0200 Subject: [PATCH 03/10] Migrate MediaSession to ES6 --- package.json | 1 + src/components/playback/mediasession.js | 59 ++++++++++++------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 8f42635adc..693dac2e7c 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "src/components/filedownloader.js", "src/components/filesystem.js", "src/components/input/keyboardnavigation.js", + "src/components/playback/mediasession.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", "src/scripts/settings/appSettings.js", diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index d77b02474a..65a61b91c8 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -1,14 +1,12 @@ -define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], function (playbackManager, nowPlayingHelper, events, connectionManager) { - "use strict"; - - // no support for mediaSession - if (!navigator.mediaSession && !window.NativeShell) { - return; - } +import playbackManager from 'playbackManager'; +import nowPlayingHelper from 'nowPlayingHelper'; +import events from 'events'; +import connectionManager from 'connectionManager'; +/* eslint-disable indent */ // Reports media playback to the device for lock screen control - var currentPlayer; + let currentPlayer; function seriesImageUrl(item, options = {}, type = options.type || 'Primary') { if (item.Type !== 'Episode') { @@ -47,10 +45,10 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } function pushImageUrl(item, imageOptions = {}) { - var url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions); + const url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions); if (url) { - var height = imageOptions.height || imageOptions.maxHeight; + const height = imageOptions.height || imageOptions.maxHeight; return { src: url, @@ -60,7 +58,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } function getImageUrls(item, imageSizes = [96, 128, 192, 256, 384, 512]) { - var list = []; + const list = []; imageSizes.forEach((size) => { list.push(pushImageUrl(item, {height: size})); @@ -71,45 +69,45 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f function updatePlayerState(player, state, eventName) { // Don't go crazy reporting position changes - if (eventName == 'timeupdate') { + if (eventName === 'timeupdate') { // Only report if this item hasn't been reported yet, or if there's an actual playback change. // Don't report on simple time updates return; } - var item = state.NowPlayingItem; + const item = state.NowPlayingItem; if (!item) { hideMediaControls(); return; } - if (eventName == 'init') { // transform "init" event into "timeupdate" to restraint update rate + if (eventName === 'init') { // transform "init" event into "timeupdate" to restraint update rate eventName = 'timeupdate'; } - var isVideo = item.MediaType === 'Video'; - var isLocalPlayer = player.isLocalPlayer || false; + const isVideo = item.MediaType === 'Video'; + const isLocalPlayer = player.isLocalPlayer || false; // Local players do their own notifications if (isLocalPlayer && isVideo) { return; } - var playState = state.PlayState || {}; - var parts = nowPlayingHelper.getNowPlayingNames(item); - var artist = parts[parts.length - 1].text; - var title = parts.length === 1 ? '' : parts[0].text; + const playState = state.PlayState || {}; + const parts = nowPlayingHelper.getNowPlayingNames(item); + const artist = parts[parts.length - 1].text; + const title = parts.length === 1 ? '' : parts[0].text; - var album = item.Album || ''; - var itemId = item.Id; + const album = item.Album || ''; + const itemId = item.Id; // Convert to ms - var duration = parseInt(item.RunTimeTicks ? (item.RunTimeTicks / 10000) : 0); - var currentTime = parseInt(playState.PositionTicks ? (playState.PositionTicks / 10000) : 0); + const duration = parseInt(item.RunTimeTicks ? (item.RunTimeTicks / 10000) : 0); + const currentTime = parseInt(playState.PositionTicks ? (playState.PositionTicks / 10000) : 0); - var isPaused = playState.IsPaused || false; - var canSeek = playState.CanSeek || false; + const isPaused = playState.IsPaused || false; + const canSeek = playState.CanSeek || false; if ('mediaSession' in navigator) { navigator.mediaSession.metadata = new MediaMetadata({ @@ -119,7 +117,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f artwork: getImageUrls(item) }); } else { - var imageUrl = []; + let imageUrl = []; imageUrl.push(pushImageUrl(item)); if (imageUrl.length) { @@ -145,7 +143,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } function onGeneralEvent(e) { - var state = playbackManager.getPlayerState(this); + const state = playbackManager.getPlayerState(this); updatePlayerState(this, state, e.type); } @@ -194,7 +192,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f currentPlayer = player; - var state = playbackManager.getPlayerState(player); + const state = playbackManager.getPlayerState(player); updatePlayerState(player, state, 'init'); events.on(currentPlayer, 'playbackstart', onPlaybackStart); @@ -240,4 +238,5 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f }); bindToPlayer(playbackManager.getCurrentPlayer()); -}); + +/* eslint-enable indent */ From 9cba01963fd2ee4b3718dbe10abcf5b42f56776a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Wed, 15 Apr 2020 10:21:58 +0200 Subject: [PATCH 04/10] Fix code smell in mediasession --- src/components/playback/mediasession.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 65a61b91c8..8851601bdc 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -117,13 +117,9 @@ import connectionManager from 'connectionManager'; artwork: getImageUrls(item) }); } else { - let imageUrl = []; - imageUrl.push(pushImageUrl(item)); - - if (imageUrl.length) { - imageUrl = imageUrl[0].src; - } else { - imageUrl = null; + let itemImageUrl = seriesImageUrl(item) || imageUrl(item); + if (!itemImageUrl) { + itemImageUrl = null; } window.NativeShell.updateMediaSession({ @@ -135,7 +131,7 @@ import connectionManager from 'connectionManager'; album: album, duration: duration, position: currentTime, - imageUrl: imageUrl, + imageUrl: itemImageUrl, canSeek: canSeek, isPaused: isPaused }); From 96d5dd54cdae4123e0df1e7966d6d376c12b1e7a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Apr 2020 16:19:15 +0200 Subject: [PATCH 05/10] Set options.type in mediaSessions if unset --- src/components/playback/mediasession.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 8851601bdc..93ef044c98 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -8,14 +8,16 @@ import connectionManager from 'connectionManager'; let currentPlayer; - function seriesImageUrl(item, options = {}, type = options.type || 'Primary') { + function seriesImageUrl(item, options = {}) { + options.type = options.type || 'Primary'; + if (item.Type !== 'Episode') { return null; - } else if (type === 'Primary' && item.SeriesPrimaryImageTag) { + } else if (options.type === 'Primary' && item.SeriesPrimaryImageTag) { options.tag = item.SeriesPrimaryImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); - } else if (type === 'Thumb') { + } else if (options.type === 'Thumb') { if (item.SeriesThumbImageTag) { options.tag = item.SeriesThumbImageTag; @@ -30,9 +32,11 @@ import connectionManager from 'connectionManager'; return null; } - function imageUrl(item, options = {}, type = options.type || 'Primary') { - if (item.ImageTags && item.ImageTags[type]) { - options.tag = item.ImageTags[type]; + function imageUrl(item, options = {}) { + options.type = options.type || 'Primary'; + + if (item.ImageTags && item.ImageTags[options.type]) { + options.tag = item.ImageTags[options.type]; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.Id, options); } else if (item.AlbumId && item.AlbumPrimaryImageTag) { From fccd99d0ef909247660207b824a08b6f81542ff4 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Apr 2020 16:36:15 +0200 Subject: [PATCH 06/10] Fix suggestions --- src/components/playback/mediasession.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 93ef044c98..1f38345f3f 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -48,7 +48,7 @@ import connectionManager from 'connectionManager'; return null; } - function pushImageUrl(item, imageOptions = {}) { + function getImageUrl(item, imageOptions = {}) { const url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions); if (url) { @@ -58,6 +58,8 @@ import connectionManager from 'connectionManager'; src: url, sizes: height + 'x' + height }; + } else { + return null; } } @@ -65,7 +67,7 @@ import connectionManager from 'connectionManager'; const list = []; imageSizes.forEach((size) => { - list.push(pushImageUrl(item, {height: size})); + list.push(getImageUrl(item, {height: size})); }); return list; @@ -122,9 +124,6 @@ import connectionManager from 'connectionManager'; }); } else { let itemImageUrl = seriesImageUrl(item) || imageUrl(item); - if (!itemImageUrl) { - itemImageUrl = null; - } window.NativeShell.updateMediaSession({ action: eventName, From a224a87fc7091f559cc0abb35615a39f84c30277 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Apr 2020 16:39:41 +0200 Subject: [PATCH 07/10] Adjust mediaSession feature test for consistency --- src/components/playback/mediasession.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 1f38345f3f..470a9de2f6 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -175,7 +175,7 @@ import connectionManager from 'connectionManager'; } function hideMediaControls() { - if (navigator.mediaSession) { + if ('mediaSession' in navigator) { navigator.mediaSession.metadata = null; } else { window.NativeShell.hideMediaSession(); @@ -206,7 +206,7 @@ import connectionManager from 'connectionManager'; playbackManager[name](currentPlayer); } - if (navigator.mediaSession) { + if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('previoustrack', function () { execute('previousTrack'); }); From a6732443f3088f4c0fa2b43e556d9f9bef572331 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Apr 2020 17:00:26 +0200 Subject: [PATCH 08/10] Only push image url to array if non-null --- src/components/playback/mediasession.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 470a9de2f6..8e24cc61db 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -67,7 +67,10 @@ import connectionManager from 'connectionManager'; const list = []; imageSizes.forEach((size) => { - list.push(getImageUrl(item, {height: size})); + const url = getImageUrl(item, {height: size}); + if (url !== null) { + list.push(url); + } }); return list; From 097802cd51bf9d28c85cf1356238fa73969a63be Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 20 Apr 2020 17:48:02 +0200 Subject: [PATCH 09/10] Add maxHeight for media session image --- src/components/playback/mediasession.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 8e24cc61db..2dd10b3484 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -126,7 +126,7 @@ import connectionManager from 'connectionManager'; artwork: getImageUrls(item) }); } else { - let itemImageUrl = seriesImageUrl(item) || imageUrl(item); + let itemImageUrl = seriesImageUrl(item, { maxHeight: 3000 }) || imageUrl(item, { maxHeight: 3000 }); window.NativeShell.updateMediaSession({ action: eventName, From 370a01f4afc33a99ea204403fc118b737db40947 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 1 May 2020 16:13:46 +0200 Subject: [PATCH 10/10] Only load mediaSessions if available or if NativeShell --- src/scripts/site.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index f861824797..e33cf25d6f 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -576,7 +576,10 @@ var AppInfo = {}; require(["components/playback/volumeosd"]); } - require(["mediaSession", "serverNotifications"]); + if (navigator.mediaSession || window.NativeShell) { + require(["mediaSession"]); + } + require(["serverNotifications"]); require(["date-fns", "date-fns/locale"]); if (!browser.tv && !browser.xboxOne) {