javascripthtmlaudio-player

How to add different songs to a player in HTML and JavaScript?


I'm struggling to add different songs to a very simple audio-player in HTML and JavaScript.

I'd like to be able to have a bunch of links on the page that would call a function that sets the player's "src" value, and then play the added song and stop the previous one playing. For some reason it doesn't work...

HTML:

<body>

<a href="" onclick="setfp(1)">Song 1</a>
<a href="" onclick="setfp(2)">Song 2</a>

<div class="audio-player">
    <div id="play-btn"></div>

    <div class="audio-wrapper" id="player-container" ref="javascript:;">
        <audio id="player">
            <source src="" type="audio/mp3">
        </audio>
    </div>
</div>

<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'> 
</script><script  src="./script.js"></script>

</body>

JavaScript:

var sfile = "";

function setfp(song_number)
{
    sfile = "./sf/" + song_number.toString() + ".mp3";  
    alert(sfile);
}

function init()
{
    (function()
        {
            var playerContainer = document.getElementById('player-container');
            var player = document.getElementById('player');
            var isPlaying = false;
            var playBtn = document.getElementById('play-btn');          

            if (playBtn != null)
            {
                playBtn.addEventListener('click', function() {togglePlay()});
            }

            function togglePlay()
            {
                alert(sfile);

                if (player.paused === false)
                {
                    player.pause();
                    isPlaying = false;
                    $('#play-btn').removeClass('pause');
                } else {
                    player.src = sfile;
                    player.play();
                    $('#play-btn').addClass('pause');
                    isPlaying = true;
                }
            }
        }());
}

init();

For some reason, whenever the "play" button is pressed, the value "sfile" is empty even though I set it through the links.


Solution

  • Global variable sfile is not being updated properly within the setfp() function. When setfp() is called from the links, it updates the value of sfile, but the togglePlay() function doesn't have access to the updated value because it's in a different scope. Try this code

    HTML:

    <a href="#" onclick="setfp(1)">Song 1</a>
    <a href="#" onclick="setfp(2)">Song 2</a>
    

    JavaScript:

    var sfile = "";
    
    function setfp(song_number) {
        sfile = "./sf/" + song_number.toString() + ".mp3";
        alert(sfile);
        togglePlay();
    }
    
    function togglePlay() {
        var player = document.getElementById('player');
        var playBtn = document.getElementById('play-btn');
    
        if (player.paused === false) {
            player.pause();
            $('#play-btn').removeClass('pause');
        } else {
            player.src = sfile;
            player.play();
            $('#play-btn').addClass('pause');
        }
    }
    
    function init() {
        var playBtn = document.getElementById('play-btn');
    
        if (playBtn != null) {
            playBtn.addEventListener('click', togglePlay);
        }
    }
    
    init();
    

    The togglePlay() function is called from within setfp() after updating the sfile variable. This ensures that togglePlay() can access the updated value of sfile. The IIFE wrapping has also been removed for simplicity. Now, the play button should correctly play and pause the selected songs.