修复移动端通知栏进度条的问题
This commit is contained in:
82
index.html
82
index.html
@@ -965,6 +965,22 @@
|
|||||||
setIsPlaying(true);
|
setIsPlaying(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateMediaSessionPosition = () => {
|
||||||
|
if (!('mediaSession' in navigator)) return;
|
||||||
|
const audio = audioRef.current;
|
||||||
|
if (!audio) return;
|
||||||
|
const duration = Number.isFinite(audio.duration) && audio.duration > 0 ? audio.duration : 0;
|
||||||
|
const position = Number.isFinite(audio.currentTime) ? audio.currentTime : 0;
|
||||||
|
const playbackRate = Number.isFinite(audio.playbackRate) ? audio.playbackRate : 1;
|
||||||
|
try {
|
||||||
|
navigator.mediaSession.setPositionState({
|
||||||
|
duration: duration,
|
||||||
|
playbackRate: playbackRate,
|
||||||
|
position: duration > 0 ? Math.min(position, duration) : position
|
||||||
|
});
|
||||||
|
} catch (e) {}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSeek = (time) => {
|
const handleSeek = (time) => {
|
||||||
if (Number.isFinite(time)) {
|
if (Number.isFinite(time)) {
|
||||||
audioRef.current.currentTime = time;
|
audioRef.current.currentTime = time;
|
||||||
@@ -1006,17 +1022,6 @@
|
|||||||
|
|
||||||
// --- Media Session Integration ---
|
// --- Media Session Integration ---
|
||||||
|
|
||||||
const updateMediaSessionPosition = () => {
|
|
||||||
if ('mediaSession' in navigator && audioRef.current && !isNaN(audioRef.current.duration)) {
|
|
||||||
try {
|
|
||||||
navigator.mediaSession.setPositionState({
|
|
||||||
duration: audioRef.current.duration,
|
|
||||||
playbackRate: audioRef.current.playbackRate,
|
|
||||||
position: audioRef.current.currentTime
|
|
||||||
});
|
|
||||||
} catch (e) { console.error("MediaSession Position Error:", e); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update refs for Media Session actions
|
// Update refs for Media Session actions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -1056,25 +1061,58 @@
|
|||||||
{ src: api.getPicUrl(currentSong.id, currentSong.platform || currentSong.source), sizes: '512x512', type: 'image/jpeg' }
|
{ src: api.getPicUrl(currentSong.id, currentSong.platform || currentSong.source), sizes: '512x512', type: 'image/jpeg' }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
// Reset position state when song changes
|
||||||
|
try { navigator.mediaSession.setPositionState({ duration: 0, playbackRate: 1, position: 0 }); } catch(e) {}
|
||||||
} else {
|
} else {
|
||||||
navigator.mediaSession.metadata = null;
|
navigator.mediaSession.metadata = null;
|
||||||
|
try { navigator.mediaSession.setPositionState({ duration: 0, playbackRate: 1, position: 0 }); } catch(e) {}
|
||||||
}
|
}
|
||||||
}, [currentSong]);
|
}, [currentSong]);
|
||||||
|
|
||||||
// Media Session Playback State & Position
|
// Media Session Logic (Unified)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if ('mediaSession' in navigator) {
|
if (!('mediaSession' in navigator)) return;
|
||||||
navigator.mediaSession.playbackState = isPlaying ? 'playing' : 'paused';
|
|
||||||
updateMediaSessionPosition();
|
|
||||||
}
|
|
||||||
}, [isPlaying]);
|
|
||||||
|
|
||||||
// Update position when song loads
|
|
||||||
useEffect(() => {
|
|
||||||
const audio = audioRef.current;
|
const audio = audioRef.current;
|
||||||
const onLoadedMetadata = () => updateMediaSessionPosition();
|
|
||||||
audio.addEventListener('loadedmetadata', onLoadedMetadata);
|
const updateState = () => {
|
||||||
return () => audio.removeEventListener('loadedmetadata', onLoadedMetadata);
|
if (!audio) return;
|
||||||
|
|
||||||
|
// Update Playback State directly from audio element source of truth
|
||||||
|
try {
|
||||||
|
navigator.mediaSession.playbackState = audio.paused ? 'paused' : 'playing';
|
||||||
|
} catch(e) {}
|
||||||
|
|
||||||
|
updateMediaSessionPosition();
|
||||||
|
};
|
||||||
|
|
||||||
|
let lastPositionUpdate = 0;
|
||||||
|
const updatePositionThrottled = () => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - lastPositionUpdate < 500) return;
|
||||||
|
lastPositionUpdate = now;
|
||||||
|
updateMediaSessionPosition();
|
||||||
|
};
|
||||||
|
|
||||||
|
const eventHandlers = [
|
||||||
|
['play', updateState],
|
||||||
|
['pause', updateState],
|
||||||
|
['playing', updateState], // Important: triggered when playback actually starts/resumes
|
||||||
|
['waiting', updateState],
|
||||||
|
['seeking', updateState],
|
||||||
|
['seeked', updateState],
|
||||||
|
['ratechange', updateState],
|
||||||
|
['durationchange', updateState],
|
||||||
|
['loadedmetadata', updateState],
|
||||||
|
['ended', updateState],
|
||||||
|
['timeupdate', updatePositionThrottled]
|
||||||
|
];
|
||||||
|
|
||||||
|
eventHandlers.forEach(([evt, handler]) => audio.addEventListener(evt, handler));
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
eventHandlers.forEach(([evt, handler]) => audio.removeEventListener(evt, handler));
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleClearCache = () => {
|
const handleClearCache = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user