完整的 Media Session API 支持
This commit is contained in:
73
index.html
73
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 (
|
||||
|
||||
Reference in New Issue
Block a user