HTML5 audio clicking the progress bar to move to a different time

24,134

Solution 1

Given some html that looks like this:

<div class="container">
    <video class="video">
        <source></source>
    </video>
    <progress min="0" max="100" value="0"></progress>
    <div class="controls"></div>
</div>

In order to seek to a specific time in the video as a result of a click event the js would look like this:

var player = document.querySelector("video");
var progressBar = document.querySelector("progress");
progressBar.addEventListener("click", seek);

function seek(e) {
    var percent = e.offsetX / this.offsetWidth;
    player.currentTime = percent * player.duration;
    progressBar.value = percent / 100;
}

However, this doesn't address how to seek on a click/drag (like most video players do). include script

Solution 2

I came across this question today because I am creating a custom HTML5 video player and had the same question. Just in regards to video instead of audio. The process should work the same though.

I found this article and was able to incorporate the progress bar part of it into my player. https://msdn.microsoft.com/en-us/library/ie/gg589528%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Instead of using a progressbar element, like I was doing, or a div element, like you're doing, the trick here is to use a canvas element instead.

<canvas id='progress-bar' width="200" height="20" style="border:1px solid green;">canvas not supported</canvas>

Then in your JavaScript, create a handle to reference it by

var mediaPlayer;
var progressBar;
var canvas;

When the document loads, initialize everything including the progress bar items

mediaPlayer = document.getElementById('media-video');
progressBar = document.getElementById('progress-bar');
canvas = document.getElementById('progress-bar');

canvas.addEventListener("click", function(e) {

    var canvas = document.getElementById('progress-bar');

    if (!e) {
        e = window.event;
    } //get the latest windows event if it isn't set
    try {
        //calculate the current time based on position of mouse cursor in canvas box
        mediaPlayer.currentTime = mediaPlayer.duration * (e.offsetX / canvas.clientWidth);
    }
    catch (err) {
    // Fail silently but show in F12 developer tools console
        if (window.console && console.error("Error:" + err));
    }
}, true);

mediaPlayer.addEventListener('timeupdate', updateProgressBar, false);

Then create a function outside of your initialization function for the timeupdate listener to call and automatically update the progress bar for you

function updateProgressBar() {        
    mediaPlayer = document.getElementById('media-video');
    //get current time in seconds
    var elapsedTime = Math.round(mediaPlayer.currentTime);
    //update the progress bar
    if (canvas.getContext) {
        var ctx = canvas.getContext("2d");
        //clear canvas before painting
        ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
        ctx.fillStyle = "rgb(255,0,0)";
        var fWidth = (elapsedTime / mediaPlayer.duration) * (canvas.clientWidth);
        if (fWidth > 0) {
            ctx.fillRect(0, 0, fWidth, canvas.clientHeight);
        }
    }
}

I haven't completely cleaned it up yet. Hence the redundant handles to the same id. But I'm sure you get the picture.

Solution 3

Hope this can save someone some time. If you're trying to set this up in an Angular app, you'll notice this is your controller context. So you'll need to use e.srcElement.clientWidth for this to work.

vm.setPosition = function(e){

  var percent = ((e.offsetX / e.srcElement.clientWidth));

  vm.songObject.setProgress(percent);
}
Share:
24,134
user962206
Author by

user962206

Updated on July 09, 2022

Comments

  • user962206
    user962206 almost 2 years
    <html>
        <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
            <script>
                $(document).ready(function(){
    
                    var counter = 0;
                    var numOfTracks = $(".audio-player").length;
                    $("#play-bt").click(function(){
                        $(".audio-player")[counter].play();
                        $("#message").text("Music started");
                    })
    
                    $("#pause-bt").click(function(){
                        $(".audio-player")[counter].pause();
                        $("#message").text("Music paused");
                    })
    
                    $("#stop-bt").click(function(){
                        $(".audio-player")[counter].pause();
                        $(".audio-player")[counter].currentTime = 0;
                        $("#message").text("Music Stopped");
                    })
    
                    $("#next-bt").click(function(){
                        $(".audio-player")[counter].pause();
                        $(".audio-player")[counter].currentTime = 0;
                        counter++;
    
    
                        if(counter > numOfTracks - 1){
                            counter = 0 ;
                        }
    
                        $(".audio-player")[counter].play();
                        $("#message").text("Next Track started");
                    })
    
                    $("#prev-bt").click(function(){
                        $(".audio-player")[counter].pause();
                        $(".audio-player")[counter].currentTime = 0;
                        counter--;
                        $(".audio-player")[counter].play();
                        $("#message").text("Previous Track");
                    })
    
                    $(".audio-player").bind('timeupdate', function(){
    
                        //Gets the whole duration of the track.
                        //No idea kung saan ko ilalagay sa UI**IMPLEMENT LATER**
                        var track_length = $(".audio-player")[counter].duration;
                        var secs = $(".audio-player")[counter].currentTime;
                        var progress = (secs/track_length) * 100;
    
                        $('#progressbar').css({'width' : progress * 2});
    
                        //Will Use these later on production
                        //NOTE DO NOT DELETE
                        //Track Minutes
                        var tcMins = parseInt(secs/60);
                        //Track Seconds
                        var tcSecs = parseInt(secs - (tcMins * 60));
    
                        if (tcSecs < 10) { tcSecs = '0' + tcSecs; }
    
                        // Display the time. REMEMBER
                        $('#timecode').html(tcMins + ':' + tcSecs);
                    })
                })
            </script>
                <style>
    
            /*Seperate this some time in the development*/
    
            #playerContainer{ 
                background-color: #A8A8A8  ; 
                width: 260px; 
                height: 55px;
                padding: 8px;
                border: 1px solid #d0d0d0;
            }
            /* Player Controls */
    
            /*list items of controls */
    
            #playerControls li { 
                display: block; 
                width: 32px; 
                height: 32px; 
                padding: 0px;
                float: left; 
                cursor: pointer;
            }
    
            #playerControls { list-style: none; padding: 0px; margin: 0px;}
    
            /*Images for each li items items */
            #play-bt { background: url('icons/glyphicons_173_play.png'); background-repeat:no-repeat }
            #pause-bt {background: url('icons/glyphicons_174_pause.png'); background-repeat:no-repeat;}
            #next-bt { background: url('icons/glyphicons_176_forward.png'); background-repeat:no-repeat}
            #prev-bt {background: url('icons/glyphicons_172_rewind.png'); background-repeat:no-repeat;}
    
            /*Progress Stuff*/
    
    
            /*Remember to manipulate its width via javascript later*/
            #progressContainer 
            { 
                background-color:#e0e0e0;
                height: 14px; 
                width: 256px; 
                float: left;
                margin-left: 0px;
            }
    
            #progressbar {background-color: #1384bb; height:14px; width:0%; }
    
                </style>
        </head>
    <body>
                <audio class ="audio-player"  name= "audio-player" src="04-zedd-stars_come_out_(terravita_remix).ogg" >
                    <p>Sorry your file doesn't support html5</p>
                </audio>
                <!--Second Track For Testing Purposes-->
                <audio  class ="audio-player" name= "audio-player" src="01-hard_rock_sofa-quasar.mp3" ></audio>
    
                <div id="message"></div>
                    <div id = "playerContainer">
    
                        <ul id =  "playerControls" >
                            <li id = "prev-bt"></li>
                            <li id= "play-bt"></li>
                            <li id= "pause-bt"></li> 
                            <li id = "next-bt"></li>
                            <li id= "stop-bt" ></li>
                            <li><span id ="timecode"></span></li>
    
                        </ul>
                            <div id="progressContainer"><!-- Progess bars container //-->
                                <div id="progressbar"></div>
                            </div>
                    </div>
    
                </div>
    
    
    
        </body>
    </html>
    

    How can I click a certain part of my progress bar so that I can move it to a different time in the track? I have no idea on how I am going to do that. any ideas ?