Changeset 6a51968 in Klonkt
- Timestamp:
- 06/25/2026 02:02:59 PM (3 months ago)
- Branches:
- main
- Children:
- 7a235bc
- Parents:
- c648b04
- Location:
- src
- Files:
-
- 2 edited
-
assets/js/audio-player.js (modified) (4 diffs)
-
views/shell.ejs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/audio-player.js
rc648b04 r6a51968 289 289 }); 290 290 291 // Media Session metadata (lock-screen / notification info + artwork). Set per 292 // track; the action handlers are wired once below. Keeping a live media session 293 // is what lets iOS continue a programmatic auto-advance play() instead of 294 // pausing it immediately. 295 function updateMediaMetadata(t) { 296 if (!('mediaSession' in navigator) || typeof MediaMetadata === 'undefined') return; 297 try { 298 const art = []; 299 if (t && t.cover) { 300 let u = t.cover; try { u = new URL(t.cover, location.href).href; } catch (e) {} 301 art.push({ src: u, sizes: '512x512', type: '' }); 302 } 303 navigator.mediaSession.metadata = new MediaMetadata({ 304 title: (t && t.title) || 'Untitled', 305 artist: (t && t.artist) || '', 306 album: albumName || '', 307 artwork: art, 308 }); 309 } catch (e) { /* non-fatal */ } 310 } 311 291 312 function loadTrack(index, autoplay, metaOnly) { 292 313 if (!queue[index]) { … … 314 335 renderQueue(); 315 336 markPlaying(t.id); 337 updateMediaMetadata(t); 316 338 317 339 if (metaOnly) return; … … 475 497 root.classList.remove('audio-needs-tap'); // hide tap hint 476 498 mediaRegistry().setActive(registrySelf); // pause any currently playing embeds 477 }); 499 if ('mediaSession' in navigator) { try { navigator.mediaSession.playbackState = 'playing'; } catch (e) {} } 500 }); 501 502 // Media Session action handlers (wired once): lock-screen / headset / car 503 // controls, and — crucially — an active session so iOS keeps a programmatic 504 // auto-advance playing instead of pausing it the instant it starts. 505 if ('mediaSession' in navigator) { 506 const ms = navigator.mediaSession; 507 const wire = (action, fn) => { try { ms.setActionHandler(action, fn); } catch (e) { /* unsupported action */ } }; 508 wire('play', () => play()); 509 wire('pause', () => pause()); 510 wire('previoustrack', () => prev()); 511 wire('nexttrack', () => next()); 512 wire('seekto', (e) => { if (e && e.seekTime != null && audio.duration) { try { audio.currentTime = e.seekTime; } catch (er) {} } }); 513 } 478 514 // Reset the error counter only on a REAL playback start (`playing`), not the 479 515 // eager `play` event. `play` fires before any network/decode error, so resetting … … 481 517 // track → infinite "next" loop. `playing` only fires when audio is actually playing. 482 518 audio.addEventListener('playing', () => { consecutiveErrors = 0; preloadNext(); }); 483 audio.addEventListener('pause', () => { isPlaying = false; root.classList.remove('is-playing'); });519 audio.addEventListener('pause', () => { isPlaying = false; root.classList.remove('is-playing'); if ('mediaSession' in navigator) { try { navigator.mediaSession.playbackState = 'paused'; } catch (e) {} } }); 484 520 audio.addEventListener('ended', next); 485 521 audio.addEventListener('error', (e) => { -
src/views/shell.ejs
rc648b04 r6a51968 335 335 ?v=N — cache-buster: bump bij elke audio-player.js wijziging zodat 336 336 Cloudflare (max-age=1y) niet de oude versie blijft serveren. --> 337 <script src="/assets/js/audio-player.js?v= 29"></script>337 <script src="/assets/js/audio-player.js?v=30"></script> 338 338 <!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) via de echte 339 339 player-API's + gedeelde mutual-exclusion registry met de site-speler. -->
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)