简体   繁体   中英

Add Playlist to Tone.js Audio Player

Short version: I am building an audio player with playlist functionality. The player works, but playlist buttons don't change initially provided URLs.

Long version: I use GrainPlayer(*) by Tone.js to play songs consisting of several mp3s each. The player itself including Play and Stop Buttons works fine, but only for the URLs that are initially provided for the variables melodyURL and percussionURL.

I also included playlist buttons to switch between songs, hence change the URLs for melodyURL and percussion URL. But the new URLs are not assigned to the GrainPlayer.

What am I missing? Any help appreciated.

Thanks in advance,

Georg

*) GrainPlayer, because I also have to adjust the playback rate without affecting the pitch.

<button id="btn-play">PLAY</button>
<button id="btn-stop" style="display:none">STOP</button>

<ul id="playlist">
    <li><button data-melody="funk_melody.mp3" data-perc="funk_percussion.mp3" >Funk Song</button></li>
    <li><button data-melody="rock_melody.mp3" data-perc="rock_percussion.mp3" >Rock Song</button></li>
</ul>
    
<script src="Tone.js"></script>
<script>    
    let melodyURL = "funk_melody.mp3"
    let percussionURL = "funk_percussion.mp3"
        
    const player = {
        melody: new Tone.GrainPlayer({ 
            url: melodyURL, 
        }),
        percussion: new Tone.GrainPlayer({ 
            url: percussionURL, 
        }),
    }
    player.melody.toDestination()
    player.percussion.toDestination()
        
    
    //  PLAYLIST BUTTONS (Don't work! Don't reasign file URLs)
    
    const playList = document.getElementById('playlist')
    const playlistItems = playlist.querySelectorAll('li')
        
    for (playlistItem of playlistItems) {
        const itemButton = playlistItem.querySelector('button')
        itemButton.addEventListener('click', async () => {
            melodyURL       = itemButton.dataset.melody
            percussionURL   = itemButton.dataset.percussion
        }
    }
    
    
    //  PLAY / STOP BUTTONS
        
    document.getElementById("btn-play").addEventListener('click', async () => {
        Tone.loaded().then(() => {
            player.melody.start()
            player.percussion.start()
            document.getElementById("btn-play").style.display = 'none'
            document.getElementById("btn-stop").style.display = 'inline'
        })
    })
        
    document.getElementById("btn-stop").addEventListener('click', async () => {
        player.melody.stop()
        player.percussion.stop()
        document.getElementById("btn-play").style.display = 'inline'
        document.getElementById("btn-stop").style.display = 'none'
    })
</script>

I found the solution to my problem: reasigning the variables for the URLs is not enough. The playlist buttons also have to reasign the player afterwards.

//  PLAYLIST BUTTONS (Now working!)

const playList = document.getElementById('playlist')
const playlistItems = playlist.querySelectorAll('li')
    
for (playlistItem of playlistItems) {
    const itemButton = playlistItem.querySelector('button')
    itemButton.addEventListener('click', async () => {

        // NEW: stop previous player
        player.melody.stop()
        player.percussion.stop()

        melodyURL       = itemButton.dataset.melody
        percussionURL   = itemButton.dataset.percussion

        // NEW: reasign player 
        player = {
            melody: new Tone.GrainPlayer({ url: melodyURL }).toDestination(),
            percussion: new Tone.GrainPlayer({ url: percussionURL }).toDestination,
        }

        player.melody.start()
        player.percussion.start()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM