Musik Latar Abadi Lintas Seluruh Halaman
Alunan melodi syahdu terus menyala mendampingi tamu membaca undangan hingga melihat galeri tanpa jeda atau berhenti di tengah jalan.
Alunan melodi syahdu terus menyala mendampingi tamu membaca undangan hingga melihat galeri tanpa jeda atau berhenti di tengah jalan.
Tantangan & Kebutuhan Pengguna
Musik latar memegang peran krusial dalam membangun suasana emosional undangan pernikahan. Masalah yang sering terjadi pada aplikasi Single Page / App Router adalah terputusnya lagu saat pengguna berpindah rute (misalnya dari '/' ke '/gallery'), serta penolakan NotAllowedError dari browser ketika kode mencoba memanggil audio.play() saat halaman baru saja dimuat.
Audio latar yang baik harus terasa menyatu dengan ruang aplikasi: menyala tepat di ketukan pertama pengguna dan tidak pernah terputus saat berpindah ruangan.
Solusi & Cara Kerja
Komponen MusicPlayer ditempatkan di dalam app/layout.tsx berdampingan dengan {children}. Karena RootLayout di Next.js tidak mengalami unmount saat perpindahan rute internal, instance HTMLAudioElement yang disimpan di dalam audioRef.current tetap hidup. Saat inisialisasi awal, objek Audio('/backsound.mp3') diatur dengan loop = true dan volume = 0.35, lalu memantau event 'canplaythrough'. Pemicuan awal dilakukan secara terpisah (decoupled) melalui event 'wedding:play' pada window ketika pengguna menekan tombol pembuka undangan.
Berikut adalah implementasi lengkap pengelolaan siklus hidup audio dan kontrol tombol mengambang dari file app/components/MusicPlayer.tsx:
Detail & Hal yang Diperhatikan
- Kepatuhan Autoplay Mobile Safari & Chrome: Karena event 'wedding:play' dipancarkan secara sinkron di dalam handler onClick tombol 'Buka Undangan', pemanggilan a.play() diizinkan oleh kebijakan keamanan media browser.
- Kesiapan Buffer Audio (canplaythrough): Tombol kontrol manual di pojok kanan bawah mengunci aksi toggle sebelum state ready bernilai true, mencegah kondisi balapan (race condition) saat jaringan pengguna lambat.
- Pencegahan Kebocoran Audio Saat Unmount: Fungsi cleanup menghentikan pemutaran dan mengosongkan a.src = '' sehingga tidak ada stream audio yatim (orphaned audio stream) di memori.
Penanganan Promise .catch(() => {}) pada a.play() wajib disertakan agar aplikasi tidak melempar UnhandledRejection apabila browser pengguna memiliki pengaturan pemblokiran media tingkat sistem.