fix: prevent notification close on skip and background audio stall
- playCurrent: set _trackChanging flag and update media session metadata before changing src, so the pause event fired by src-swap does not set playbackState='paused' and dismiss the Samsung cover screen notification - Remove stalled->load() handler that silently paused audio with no recovery - Error handler now retries regardless of paused state (load() causes paused) - Add .catch() to audio.play() in playCurrent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
f2c77f975d
commit
89e169b70a
8 files changed
+632
-9
No files matched your search
+25
-3
@@ -17,11 +17,12 @@ export function playQueue(songs, startIdx) {
|
||||
export function playCurrent() {
|
||||
if(S.qIdx < 0 || S.qIdx >= S.queue.length) return;
|
||||
const s = S.queue[S.qIdx];
|
||||
S.audio.src = streamUrl(s.id);
|
||||
S.audio.play();
|
||||
updatePlayerUI(s);
|
||||
S._trackChanging = true;
|
||||
updatePlayerUI(s); // update metadata/notification BEFORE src change
|
||||
onNpSongChange(s.id);
|
||||
renderQueue();
|
||||
S.audio.src = streamUrl(s.id);
|
||||
S.audio.play().catch(() => {});
|
||||
}
|
||||
|
||||
export function updatePlayerUI(s) {
|
||||
@@ -122,6 +123,8 @@ export function setPlayIcon(playing) {
|
||||
const cover = document.getElementById('np-cover');
|
||||
if(cover) cover.classList.toggle('playing', playing);
|
||||
}
|
||||
// Android native MediaSession bridge
|
||||
if (window.Android) { try { window.Android.setPlaybackState(playing); } catch(_) {} }
|
||||
}
|
||||
|
||||
export function prevSong() {
|
||||
@@ -193,9 +196,16 @@ export async function fillRadioQueue() {
|
||||
}
|
||||
|
||||
// ─── PROGRESS & SCRUBBING ───
|
||||
let _androidPosTick = 0;
|
||||
export function updateProgress() {
|
||||
if(!S.audio.duration || S._scrubbing) return;
|
||||
syncMediaSessionPosition();
|
||||
// Update Android native position every ~5 seconds to keep lock screen scrubber in sync
|
||||
const now = Date.now();
|
||||
if(now - _androidPosTick > 5000) {
|
||||
_androidPosTick = now;
|
||||
if (window.Android) { try { window.Android.updatePosition(S.audio.currentTime, S.audio.duration); } catch(_) {} }
|
||||
}
|
||||
const p = (S.audio.currentTime / S.audio.duration) * 100;
|
||||
document.getElementById('progress-fill').style.width = p + '%';
|
||||
document.getElementById('time-cur').textContent = formatDur(S.audio.currentTime);
|
||||
@@ -279,6 +289,18 @@ export function setVolume(v) {
|
||||
|
||||
// ─── MEDIA SESSION ───
|
||||
export function updateMediaSession(s) {
|
||||
// Android native MediaSession bridge — use 512px art for high-DPI screens
|
||||
if (window.Android) {
|
||||
try {
|
||||
window.Android.updateTrack(
|
||||
s.title || '',
|
||||
s.artist || '',
|
||||
s.coverArt ? coverUrl(s.coverArt, 512) : '',
|
||||
s.duration || 0
|
||||
);
|
||||
} catch(_) {}
|
||||
}
|
||||
|
||||
if(!navigator.mediaSession) return;
|
||||
const artwork = s.coverArt ? [
|
||||
{ src: coverUrl(s.coverArt,96), sizes:'96x96', type:'image/jpeg' },
|
||||
|
||||
Reference in new issue
Block a user