add MediaSession plugin (#6298)

This commit is contained in:
feederbox826 2025-11-24 17:12:23 -05:00 committed by GitHub
parent 5d02f916c2
commit ca8ee6bc2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 88 additions and 0 deletions

View file

@ -22,6 +22,7 @@ import "./vtt-thumbnails";
import "./big-buttons"; import "./big-buttons";
import "./track-activity"; import "./track-activity";
import "./vrmode"; import "./vrmode";
import "./media-session";
import cx from "classnames"; import cx from "classnames";
import { import {
useSceneSaveActivity, useSceneSaveActivity,
@ -397,6 +398,7 @@ export const ScenePlayer: React.FC<IScenePlayerProps> = PatchComponent(
pauseBeforeLooping: false, pauseBeforeLooping: false,
createButtons: uiConfig?.showAbLoopControls ?? false, createButtons: uiConfig?.showAbLoopControls ?? false,
}, },
mediaSession: {},
}, },
}; };
@ -874,6 +876,21 @@ export const ScenePlayer: React.FC<IScenePlayerProps> = PatchComponent(
return () => player.off("ended"); return () => player.off("ended");
}, [getPlayer, onComplete]); }, [getPlayer, onComplete]);
// set up mediaSession plugin
useEffect(() => {
const player = getPlayer();
if (!player) return;
// set up mediasession plugin
player
.mediaSession()
.setMetadata(
scene?.title ?? "Stash",
scene?.studio?.name ?? "Stash",
scene.paths.screenshot || ""
);
}, [getPlayer, scene]);
function onScrubberScroll() { function onScrubberScroll() {
if (started.current) { if (started.current) {
getPlayer()?.pause(); getPlayer()?.pause();

View file

@ -0,0 +1,71 @@
import videojs, { VideoJsPlayer } from "video.js";
class MediaSessionPlugin extends videojs.getPlugin("plugin") {
constructor(player: VideoJsPlayer) {
super(player);
player.ready(() => {
player.addClass("vjs-media-session");
this.setActionHandlers();
});
player.on("play", () => {
this.updatePlaybackState();
});
player.on("pause", () => {
this.updatePlaybackState();
});
this.updatePlaybackState();
}
// manually set poster since it's only set on useEffect
public setMetadata(title: string, studioName: string, poster: string): void {
if ("mediaSession" in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title,
artist: studioName,
artwork: [
{
src: poster || this.player.poster() || "",
type: "image/jpeg",
},
],
});
}
}
private updatePlaybackState(): void {
if ("mediaSession" in navigator) {
const playbackState = this.player.paused() ? "paused" : "playing";
navigator.mediaSession.playbackState = playbackState;
}
}
private setActionHandlers(): void {
// method initialization
navigator.mediaSession.setActionHandler("play", () => {
this.player.play();
});
navigator.mediaSession.setActionHandler("pause", () => {
this.player.pause();
});
navigator.mediaSession.setActionHandler("nexttrack", () => {
this.player.skipButtons()?.handleForward();
});
navigator.mediaSession.setActionHandler("previoustrack", () => {
this.player.skipButtons()?.handleBackward();
});
}
}
videojs.registerPlugin("mediaSession", MediaSessionPlugin);
/* eslint-disable @typescript-eslint/naming-convention */
declare module "video.js" {
interface VideoJsPlayer {
mediaSession: () => MediaSessionPlugin;
}
}
export default MediaSessionPlugin;