diff --git a/index.html b/index.html
index 8fd95c2..6478b7d 100644
--- a/index.html
+++ b/index.html
@@ -691,6 +691,12 @@
const audioRef = useRef(new Audio());
+ // Media Session Refs
+ const playNextRef = useRef(null);
+ const playPrevRef = useRef(null);
+ const togglePlayRef = useRef(null);
+ const handleSeekRef = useRef(null);
+
// --- Effects ---
useEffect(() => { localStorage.setItem('th_playlist', JSON.stringify(playlist)); }, [playlist]);
@@ -711,7 +717,20 @@
useEffect(() => {
const audio = audioRef.current;
audio.volume = volume;
- const updateTime = () => setCurrentTime(audio.currentTime);
+ const updateTime = () => {
+ setCurrentTime(audio.currentTime);
+ if ('mediaSession' in navigator && !isNaN(audio.duration)) {
+ try {
+ navigator.mediaSession.setPositionState({
+ duration: audio.duration,
+ playbackRate: audio.playbackRate,
+ position: audio.currentTime
+ });
+ } catch (e) {
+ // Ignore errors
+ }
+ }
+ };
const updateDuration = () => setDuration(audio.duration);
const onEnded = () => playNext(true);
@@ -894,6 +913,58 @@
setMode(next);
};
+ // --- Media Session Integration ---
+
+ // Update refs for Media Session actions
+ useEffect(() => {
+ playNextRef.current = playNext;
+ playPrevRef.current = playPrev;
+ togglePlayRef.current = togglePlay;
+ handleSeekRef.current = handleSeek;
+ });
+
+ // Media Session Actions (One-time setup)
+ useEffect(() => {
+ if (!('mediaSession' in navigator)) return;
+
+ const actionHandlers = [
+ ['play', () => togglePlayRef.current?.()],
+ ['pause', () => togglePlayRef.current?.()],
+ ['previoustrack', () => playPrevRef.current?.()],
+ ['nexttrack', () => playNextRef.current?.()],
+ ['seekto', (details) => handleSeekRef.current?.(details.seekTime)],
+ ];
+
+ for (const [action, handler] of actionHandlers) {
+ try { navigator.mediaSession.setActionHandler(action, handler); } catch (e) {}
+ }
+ }, []);
+
+ // Media Session Metadata
+ useEffect(() => {
+ if (!('mediaSession' in navigator)) return;
+
+ if (currentSong) {
+ navigator.mediaSession.metadata = new MediaMetadata({
+ title: currentSong.name,
+ artist: currentSong.artist,
+ album: SOURCES.find(s => s.id === (currentSong.platform || currentSong.source))?.name || '',
+ artwork: [
+ { src: api.getPicUrl(currentSong.id, currentSong.platform || currentSong.source), sizes: '512x512', type: 'image/jpeg' }
+ ]
+ });
+ } else {
+ navigator.mediaSession.metadata = null;
+ }
+ }, [currentSong]);
+
+ // Media Session Playback State
+ useEffect(() => {
+ if ('mediaSession' in navigator) {
+ navigator.mediaSession.playbackState = isPlaying ? 'playing' : 'paused';
+ }
+ }, [isPlaying]);
+
// --- Render ---
return (