@@ -278,45 +278,64 @@ defmodule EventHorizonWeb.JukeboxLive do
278278 < script :type = { Phoenix.LiveView.ColocatedHook } name = ".JukeboxPanel " >
279279 export default {
280280 mounted ( ) {
281- this . _audios = { } ;
281+ this . _tracks = { } ;
282+ this . _ctx = null ;
282283 this . _wasHidden = this . el . style . display === 'none' ;
283284
284285 this . el . addEventListener ( "jukebox:credit_click" , e => {
285286 e . stopPropagation ( ) ;
286287 } ) ;
287288
289+ const getCtx = ( ) => {
290+ if ( ! this . _ctx ) this. _ctx = new ( window . AudioContext || window . webkitAudioContext ) ( ) ;
291+ return this . _ctx ;
292+ } ;
293+
294+ const getVolume = ( ) => {
295+ const slider = this . el . querySelector ( '#jukebox-volume-slider' ) ;
296+ return slider ? parseInt ( slider . value , 10 ) / 100 : 0.7 ;
297+ } ;
298+
288299 this . handleEvent ( "jukebox:play" , ( { id , url , loop } ) => {
289- if ( this . _audios [ id ] ) {
290- this . _audios [ id ] . pause ( ) ;
291- delete this. _audios [ id ] ;
300+ if ( this . _tracks [ id ] ) {
301+ this . _tracks [ id ] . audio . pause ( ) ;
302+ this. _tracks [ id ] . source . disconnect ( ) ;
303+ delete this. _tracks [ id ] ;
292304 }
293- const slider = this . el . querySelector ( '#jukebox-volume-slider' ) ;
294- const vol = slider ? parseInt ( slider . value , 10 ) / 100 : 0.7 ;
305+ const ctx = getCtx ( ) ;
295306 const audio = new Audio ( url ) ;
307+ audio. crossOrigin = "anonymous" ;
296308 audio. preload = "metadata" ;
297309 audio. loop = ! ! loop ;
298- audio . volume = vol ;
310+ const source = ctx . createMediaElementSource ( audio ) ;
311+ const gain = ctx . createGain ( ) ;
312+ gain. gain . value = getVolume ( ) ;
313+ source. connect ( gain ) ;
314+ gain. connect ( ctx . destination ) ;
299315 if ( ! loop ) {
300316 audio . addEventListener ( "ended" , ( ) => {
301- delete this . _audios [ id ] ;
317+ source . disconnect ( ) ;
318+ delete this. _tracks [ id ] ;
302319 this. pushEvent ( "track_ended" , { id: id } ) ;
303320 } ) ;
304321 }
305322 audio . play ( ) . catch ( ( ) => { } ) ;
306- this. _audios [ id ] = audio ;
323+ this. _tracks [ id ] = { audio , source , gain } ;
307324 } ) ;
308325
309326 this . handleEvent ( "jukebox:stop" , ( { id } ) => {
310- if ( this . _audios [ id ] ) {
311- this . _audios [ id ] . pause ( ) ;
312- delete this. _audios [ id ] ;
327+ if ( this . _tracks [ id ] ) {
328+ this . _tracks [ id ] . audio . pause ( ) ;
329+ this. _tracks [ id ] . source . disconnect ( ) ;
330+ delete this. _tracks [ id ] ;
313331 }
314332 } ) ;
315333
316334 this . handleEvent ( "jukebox:stop_all" , ( ) => {
317- Object . keys ( this . _audios ) . forEach ( id => {
318- this . _audios [ id ] . pause ( ) ;
319- delete this. _audios [ id ] ;
335+ Object . keys ( this . _tracks ) . forEach ( id => {
336+ this . _tracks [ id ] . audio . pause ( ) ;
337+ this. _tracks [ id ] . source . disconnect ( ) ;
338+ delete this. _tracks [ id ] ;
320339 } ) ;
321340 } ) ;
322341
@@ -325,7 +344,7 @@ defmodule EventHorizonWeb.JukeboxLive do
325344 const onVolume = ( ) => {
326345 const vol = parseInt ( slider . value , 10 ) / 100 ;
327346 slider. style . setProperty ( "--vol" , ( vol * 100 ) + "%" ) ;
328- Object. values ( this . _audios ) . forEach ( a => a . volume = vol ) ;
347+ Object. values ( this . _tracks ) . forEach ( t => t . gain . gain . value = vol ) ;
329348 this. pushEvent ( "set_volume" , { volume: parseInt ( slider . value , 10 ) } ) ;
330349 } ;
331350 slider . addEventListener ( "input" , onVolume ) ;
@@ -337,8 +356,12 @@ defmodule EventHorizonWeb.JukeboxLive do
337356 this . _wasHidden = this . el . style . display === 'none' ;
338357 } ,
339358 destroyed ( ) {
340- Object . values ( this . _audios ) . forEach ( a => a . pause ( ) ) ;
341- this . _audios = { } ;
359+ Object . values ( this . _tracks ) . forEach ( t => {
360+ t . audio . pause ( ) ;
361+ if ( t . source ) t. source . disconnect ( ) ;
362+ } ) ;
363+ this . _tracks = { } ;
364+ if ( this . _ctx ) this. _ctx . close ( ) ;
342365 }
343366 }
344367 </ script >
0 commit comments