Merge pull request #1456 from ciderapp/enhancement/mediaSessionAPI
Enhancement/media session api
This commit is contained in:
commit
ef06ab8fd2
4 changed files with 151 additions and 58 deletions
2
.github/workflows/pr-chores.yml
vendored
2
.github/workflows/pr-chores.yml
vendored
|
@ -34,4 +34,4 @@ jobs:
|
|||
uses: wearerequired/lint-action@v2
|
||||
with:
|
||||
prettier: true
|
||||
prettier_args: "'**/*.{js,json,ts,css,vue,less}'"
|
||||
prettier_args: "'src/**/*.{js,json,ts,css,vue,less}'"
|
||||
|
|
|
@ -200,15 +200,11 @@ export class wsapi {
|
|||
response.message = "Unmuted";
|
||||
break;
|
||||
case "next":
|
||||
this._win.webContents.executeJavaScript(`if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null) {
|
||||
try {
|
||||
app.prevButtonBackIndicator = false;
|
||||
} catch (e) { }
|
||||
MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);}`);
|
||||
this._win.webContents.executeJavaScript(`MusicKitInterop.next()`);
|
||||
response.message = "Next";
|
||||
break;
|
||||
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";
|
||||
break;
|
||||
case "musickit-api":
|
||||
|
|
|
@ -10,6 +10,7 @@ const MusicKitInterop = {
|
|||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => {
|
||||
const attributes = MusicKitInterop.getAttributes();
|
||||
if (!attributes) return;
|
||||
MusicKitInterop.updateMediaState(attributes);
|
||||
if (MusicKitInterop.filterTrack(attributes, true, false)) {
|
||||
global.ipcRenderer.send("playbackStateDidChange", attributes);
|
||||
global.ipcRenderer.send("wsapi-updatePlaybackState", attributes);
|
||||
|
@ -35,6 +36,7 @@ const MusicKitInterop = {
|
|||
const attributes = MusicKitInterop.getAttributes();
|
||||
if (!attributes) return;
|
||||
ipcRenderer.send("playbackTimeDidChange", attributes);
|
||||
MusicKitInterop.updatePositionState(attributes);
|
||||
});
|
||||
|
||||
/* MusicKit.Events.nowPlayingItemDidChange */
|
||||
|
@ -43,6 +45,7 @@ const MusicKitInterop = {
|
|||
if (!attributes) return;
|
||||
attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchSongRelationships() : attributes.artistName;
|
||||
|
||||
MusicKitInterop.updateMediaSession(attributes);
|
||||
global.ipcRenderer.send("nowPlayingItemDidChange", attributes);
|
||||
|
||||
if (MusicKitInterop.filterTrack(attributes, false, true)) {
|
||||
|
@ -142,7 +145,7 @@ const MusicKitInterop = {
|
|||
|
||||
attributes.songId = attributes.songId ?? attributes.playParams?.catalogId ?? attributes.playParams?.id;
|
||||
attributes.type = nowPlayingItem?.type ?? "";
|
||||
attributes.status = isPlayingExport ?? null;
|
||||
attributes.status = nowPlayingItem == null ? null : !!isPlayingExport;
|
||||
attributes.name = attributes?.name ?? "no-title-found";
|
||||
attributes.artwork = attributes?.artwork ?? { url: "" };
|
||||
attributes.artwork.url = (attributes?.artwork?.url ?? "").replace(`{f}`, "png");
|
||||
|
@ -205,22 +208,139 @@ const MusicKitInterop = {
|
|||
},
|
||||
|
||||
next: () => {
|
||||
// try {
|
||||
// app.prevButtonBackIndicator = false;
|
||||
// } catch (e) { }
|
||||
// if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null)
|
||||
// MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);
|
||||
if (app) {
|
||||
app.skipToNextItem();
|
||||
} else {
|
||||
MusicKit.getInstance()
|
||||
.skipToNextItem()
|
||||
.then((r) => console.debug(`[cider:preload] [next] Skipping to Next ${r}`));
|
||||
}
|
||||
},
|
||||
|
||||
previous: () => {
|
||||
// if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null)
|
||||
// MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex);
|
||||
if (app) {
|
||||
app.skipToPreviousItem();
|
||||
} else {
|
||||
MusicKit.getInstance()
|
||||
.skipToPreviousItem()
|
||||
.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,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -195,7 +195,6 @@ const app = new Vue({
|
|||
type: "",
|
||||
},
|
||||
MVsource: null,
|
||||
prevButtonBackIndicator: false,
|
||||
currentSongInfo: {},
|
||||
page: "",
|
||||
pageHistory: [],
|
||||
|
@ -2249,40 +2248,20 @@ const app = new Vue({
|
|||
}
|
||||
},
|
||||
prevButton() {
|
||||
if (!app.prevButtonBackIndicator && app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) {
|
||||
app.prevButtonBackIndicator = true;
|
||||
try {
|
||||
clearTimeout(app.pauseButtonTimer);
|
||||
} catch (e) {}
|
||||
if (app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) {
|
||||
app.mk.seekToTime(0);
|
||||
app.pauseButtonTimer = setTimeout(() => {
|
||||
app.prevButtonBackIndicator = false;
|
||||
}, 3000);
|
||||
} else {
|
||||
try {
|
||||
clearTimeout(app.pauseButtonTimer);
|
||||
} catch (e) {}
|
||||
app.prevButtonBackIndicator = false;
|
||||
app.skipToPreviousItem();
|
||||
}
|
||||
},
|
||||
isDisabled() {
|
||||
if (!app.mk.nowPlayingItem || app.mk.nowPlayingItem.attributes.playParams.kind == "radioStation") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return !app.mk.nowPlayingItem || app.mk.nowPlayingItem.attributes.playParams.kind === "radioStation";
|
||||
},
|
||||
isPrevDisabled() {
|
||||
if (this.isDisabled() || (app.mk.queue._position == 0 && app.mk.currentPlaybackTime <= 2)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return this.isDisabled() || (app.mk.queue._position === 0 && app.mk.currentPlaybackTime <= 2);
|
||||
},
|
||||
isNextDisabled() {
|
||||
if (this.isDisabled() || app.mk.queue._position + 1 == app.mk.queue.length) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return this.isDisabled() || app.mk.queue._position + 1 === app.mk.queue.length;
|
||||
},
|
||||
|
||||
async getNowPlayingItemDetailed(target) {
|
||||
|
@ -5098,21 +5077,19 @@ const app = new Vue({
|
|||
}
|
||||
},
|
||||
skipToNextItem() {
|
||||
app.prevButtonBackIndicator = false;
|
||||
// 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);
|
||||
if (this.mk.queue.nextPlayableItemIndex !== -1 && this.mk.queue.nextPlayableItemIndex != null) this.mk.changeToMediaAtIndex(this.mk.queue.nextPlayableItemIndex);
|
||||
},
|
||||
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() {
|
||||
navigator.mediaSession.setActionHandler("previoustrack", function () {
|
||||
app.prevButton();
|
||||
});
|
||||
navigator.mediaSession.setActionHandler("nexttrack", function () {
|
||||
app.skipToNextItem();
|
||||
});
|
||||
MusicKitInterop.initMediaSession();
|
||||
// navigator.mediaSession.setActionHandler("previoustrack", function () {
|
||||
// app.skipToPreviousItem();
|
||||
// });
|
||||
// navigator.mediaSession.setActionHandler("nexttrack", function () {
|
||||
// app.skipToNextItem();
|
||||
// });
|
||||
},
|
||||
authCC() {
|
||||
ipcRenderer.send("cc-auth");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue