Merge pull request #1456 from ciderapp/enhancement/mediaSessionAPI

Enhancement/media session api
This commit is contained in:
Core 2022-09-22 00:10:06 +01:00 committed by GitHub
commit ef06ab8fd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 151 additions and 58 deletions

View file

@ -34,4 +34,4 @@ jobs:
uses: wearerequired/lint-action@v2 uses: wearerequired/lint-action@v2
with: with:
prettier: true prettier: true
prettier_args: "'**/*.{js,json,ts,css,vue,less}'" prettier_args: "'src/**/*.{js,json,ts,css,vue,less}'"

View file

@ -200,15 +200,11 @@ export class wsapi {
response.message = "Unmuted"; response.message = "Unmuted";
break; break;
case "next": case "next":
this._win.webContents.executeJavaScript(`if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null) { this._win.webContents.executeJavaScript(`MusicKitInterop.next()`);
try {
app.prevButtonBackIndicator = false;
} catch (e) { }
MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);}`);
response.message = "Next"; response.message = "Next";
break; break;
case "previous": case "previous":
this._win.webContents.executeJavaScript(`if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex)}`); this._win.webContents.executeJavaScript(`MusicKitInterop.previous()`);
response.message = "Previous"; response.message = "Previous";
break; break;
case "musickit-api": case "musickit-api":

View file

@ -10,6 +10,7 @@ const MusicKitInterop = {
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => { MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => {
const attributes = MusicKitInterop.getAttributes(); const attributes = MusicKitInterop.getAttributes();
if (!attributes) return; if (!attributes) return;
MusicKitInterop.updateMediaState(attributes);
if (MusicKitInterop.filterTrack(attributes, true, false)) { if (MusicKitInterop.filterTrack(attributes, true, false)) {
global.ipcRenderer.send("playbackStateDidChange", attributes); global.ipcRenderer.send("playbackStateDidChange", attributes);
global.ipcRenderer.send("wsapi-updatePlaybackState", attributes); global.ipcRenderer.send("wsapi-updatePlaybackState", attributes);
@ -35,6 +36,7 @@ const MusicKitInterop = {
const attributes = MusicKitInterop.getAttributes(); const attributes = MusicKitInterop.getAttributes();
if (!attributes) return; if (!attributes) return;
ipcRenderer.send("playbackTimeDidChange", attributes); ipcRenderer.send("playbackTimeDidChange", attributes);
MusicKitInterop.updatePositionState(attributes);
}); });
/* MusicKit.Events.nowPlayingItemDidChange */ /* MusicKit.Events.nowPlayingItemDidChange */
@ -43,6 +45,7 @@ const MusicKitInterop = {
if (!attributes) return; if (!attributes) return;
attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchSongRelationships() : attributes.artistName; attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchSongRelationships() : attributes.artistName;
MusicKitInterop.updateMediaSession(attributes);
global.ipcRenderer.send("nowPlayingItemDidChange", attributes); global.ipcRenderer.send("nowPlayingItemDidChange", attributes);
if (MusicKitInterop.filterTrack(attributes, false, true)) { if (MusicKitInterop.filterTrack(attributes, false, true)) {
@ -142,7 +145,7 @@ const MusicKitInterop = {
attributes.songId = attributes.songId ?? attributes.playParams?.catalogId ?? attributes.playParams?.id; attributes.songId = attributes.songId ?? attributes.playParams?.catalogId ?? attributes.playParams?.id;
attributes.type = nowPlayingItem?.type ?? ""; attributes.type = nowPlayingItem?.type ?? "";
attributes.status = isPlayingExport ?? null; attributes.status = nowPlayingItem == null ? null : !!isPlayingExport;
attributes.name = attributes?.name ?? "no-title-found"; attributes.name = attributes?.name ?? "no-title-found";
attributes.artwork = attributes?.artwork ?? { url: "" }; attributes.artwork = attributes?.artwork ?? { url: "" };
attributes.artwork.url = (attributes?.artwork?.url ?? "").replace(`{f}`, "png"); attributes.artwork.url = (attributes?.artwork?.url ?? "").replace(`{f}`, "png");
@ -205,22 +208,139 @@ const MusicKitInterop = {
}, },
next: () => { next: () => {
// try { if (app) {
// app.prevButtonBackIndicator = false; app.skipToNextItem();
// } catch (e) { } } else {
// if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null)
// MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);
MusicKit.getInstance() MusicKit.getInstance()
.skipToNextItem() .skipToNextItem()
.then((r) => console.debug(`[cider:preload] [next] Skipping to Next ${r}`)); .then((r) => console.debug(`[cider:preload] [next] Skipping to Next ${r}`));
}
}, },
previous: () => { previous: () => {
// if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null) if (app) {
// MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex); app.skipToPreviousItem();
} else {
MusicKit.getInstance() MusicKit.getInstance()
.skipToPreviousItem() .skipToPreviousItem()
.then((r) => console.debug(`[cider:preload] [previous] Skipping to Previous ${r}`)); .then((r) => console.debug(`[cider:preload] [previous] Skipping to Previous ${r}`));
}
},
initMediaSession: () => {
if ("mediaSession" in navigator) {
const defaultSkipTime = 10;
console.debug("[cider:preload] [initMediaSession] Media Session API supported");
navigator.mediaSession.setActionHandler("play", () => {
MusicKitInterop.play();
console.log("[cider:preload] [initMediaSession] Play");
});
navigator.mediaSession.setActionHandler("pause", () => {
MusicKitInterop.pause();
console.log("[cider:preload] [initMediaSession] Pause");
});
navigator.mediaSession.setActionHandler("stop", () => {
MusicKit.getInstance().stop();
console.log("[cider:preload] [initMediaSession] Stop");
});
navigator.mediaSession.setActionHandler("seekbackward", (details) => {
const skipTime = details.seekOffset || defaultSkipTime;
MusicKit.getInstance().seekToTime(Math.max(MusicKit.getInstance().currentPlaybackTime - skipTime, 0));
console.log(`[cider:preload] [initMediaSession] Seek Backward ${skipTime}`);
});
navigator.mediaSession.setActionHandler("seekforward", (details) => {
const skipTime = details.seekOffset || defaultSkipTime;
MusicKit.getInstance().seekToTime(Math.max(MusicKit.getInstance().currentPlaybackTime + skipTime, 0));
console.log(`[cider:preload] [initMediaSession] Seek Forward ${skipTime}`);
});
navigator.mediaSession.setActionHandler("seekto", ({ seekTime, fastSeek }) => {
MusicKit.getInstance().seekToTime(seekTime);
console.log(`[cider:preload] [initMediaSession] Seek To ${seekTime}`);
});
navigator.mediaSession.setActionHandler("previoustrack", () => {
MusicKitInterop.previous();
console.log("[cider:preload] [initMediaSession] Previous Track");
});
navigator.mediaSession.setActionHandler("nexttrack", () => {
MusicKitInterop.next();
console.log("[cider:preload] [initMediaSession] Next Track");
});
} else {
console.debug("[cider:preload] [initMediaSession] Media Session API not supported");
}
},
updateMediaSession: (a) => {
if ("mediaSession" in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: a.name,
artist: a.artistName,
album: a.albumName,
artwork: [
{
src: a.artwork.url.replace("/{w}x{h}bb", "/96x96bb").replace("/2000x2000bb", "/35x35bb"),
sizes: "96x96",
type: "image/jpeg",
},
{
src: a.artwork.url.replace("/{w}x{h}bb", "/128x128bb").replace("/2000x2000bb", "/35x35bb"),
sizes: "128x128",
type: "image/jpeg",
},
{
src: a.artwork.url.replace("/{w}x{h}bb", "/192x192bb").replace("/2000x2000bb", "/35x35bb"),
sizes: "192x192",
type: "image/jpeg",
},
{
src: a.artwork.url.replace("/{w}x{h}bb", "/256x256bb").replace("/2000x2000bb", "/35x35bb"),
sizes: "256x256",
type: "image/jpeg",
},
{
src: a.artwork.url.replace("/{w}x{h}bb", "/384x384bb").replace("/2000x2000bb", "/35x35bb"),
sizes: "384x384",
type: "image/jpeg",
},
{
src: a.artwork.url.replace("/{w}x{h}bb", "/512x512bb").replace("/2000x2000bb", "/35x35bb"),
sizes: "512x512",
type: "image/jpeg",
},
],
});
}
},
updateMediaState: (a) => {
if ("mediaSession" in navigator) {
console.log("[cider:preload] [updateMediaState] Updating Media State to " + a.status);
switch (a.status) {
default:
case null:
navigator.mediaSession.playbackState = "none";
break;
case false:
navigator.mediaSession.playbackState = "paused";
break;
case true:
navigator.mediaSession.playbackState = "playing";
break;
}
}
},
updatePositionState: (a) => {
if ("mediaSession" in navigator && a.currentPlaybackTime <= a.durationInMillis / 1000 && a.currentPlaybackTime >= 0) {
navigator.mediaSession.setPositionState({
duration: a.durationInMillis / 1000,
playbackRate: app?.cfg?.audio?.playbackRate ?? 1,
position: a.currentPlaybackTime,
});
}
}, },
}; };

View file

@ -195,7 +195,6 @@ const app = new Vue({
type: "", type: "",
}, },
MVsource: null, MVsource: null,
prevButtonBackIndicator: false,
currentSongInfo: {}, currentSongInfo: {},
page: "", page: "",
pageHistory: [], pageHistory: [],
@ -2249,40 +2248,20 @@ const app = new Vue({
} }
}, },
prevButton() { prevButton() {
if (!app.prevButtonBackIndicator && app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) { if (app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) {
app.prevButtonBackIndicator = true;
try {
clearTimeout(app.pauseButtonTimer);
} catch (e) {}
app.mk.seekToTime(0); app.mk.seekToTime(0);
app.pauseButtonTimer = setTimeout(() => {
app.prevButtonBackIndicator = false;
}, 3000);
} else { } else {
try {
clearTimeout(app.pauseButtonTimer);
} catch (e) {}
app.prevButtonBackIndicator = false;
app.skipToPreviousItem(); app.skipToPreviousItem();
} }
}, },
isDisabled() { isDisabled() {
if (!app.mk.nowPlayingItem || app.mk.nowPlayingItem.attributes.playParams.kind == "radioStation") { return !app.mk.nowPlayingItem || app.mk.nowPlayingItem.attributes.playParams.kind === "radioStation";
return true;
}
return false;
}, },
isPrevDisabled() { isPrevDisabled() {
if (this.isDisabled() || (app.mk.queue._position == 0 && app.mk.currentPlaybackTime <= 2)) { return this.isDisabled() || (app.mk.queue._position === 0 && app.mk.currentPlaybackTime <= 2);
return true;
}
return false;
}, },
isNextDisabled() { isNextDisabled() {
if (this.isDisabled() || app.mk.queue._position + 1 == app.mk.queue.length) { return this.isDisabled() || app.mk.queue._position + 1 === app.mk.queue.length;
return true;
}
return false;
}, },
async getNowPlayingItemDetailed(target) { async getNowPlayingItemDetailed(target) {
@ -5098,21 +5077,19 @@ const app = new Vue({
} }
}, },
skipToNextItem() { skipToNextItem() {
app.prevButtonBackIndicator = false; if (this.mk.queue.nextPlayableItemIndex !== -1 && this.mk.queue.nextPlayableItemIndex != null) this.mk.changeToMediaAtIndex(this.mk.queue.nextPlayableItemIndex);
// app.mk.skipToNextItem() is buggy somehow so use this
if (this.mk.queue.nextPlayableItemIndex != -1 && this.mk.queue.nextPlayableItemIndex != null) this.mk.changeToMediaAtIndex(this.mk.queue.nextPlayableItemIndex);
}, },
skipToPreviousItem() { skipToPreviousItem() {
// app.mk.skipToPreviousItem() is buggy somehow so use this if (this.mk.queue.previousPlayableItemIndex !== -1 && this.mk.queue.previousPlayableItemIndex != null) this.mk.changeToMediaAtIndex(this.mk.queue.previousPlayableItemIndex);
if (this.mk.queue.previousPlayableItemIndex != -1 && this.mk.queue.previousPlayableItemIndex != null) this.mk.changeToMediaAtIndex(this.mk.queue.previousPlayableItemIndex);
}, },
mediaKeyFixes() { mediaKeyFixes() {
navigator.mediaSession.setActionHandler("previoustrack", function () { MusicKitInterop.initMediaSession();
app.prevButton(); // navigator.mediaSession.setActionHandler("previoustrack", function () {
}); // app.skipToPreviousItem();
navigator.mediaSession.setActionHandler("nexttrack", function () { // });
app.skipToNextItem(); // navigator.mediaSession.setActionHandler("nexttrack", function () {
}); // app.skipToNextItem();
// });
}, },
authCC() { authCC() {
ipcRenderer.send("cc-auth"); ipcRenderer.send("cc-auth");