完整的 Media Session API 支持

This commit is contained in:
史悦
2026-01-06 10:52:43 +08:00
parent 2841aff80b
commit b1e76110ff

View File

@@ -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 (