Mark Serrano
Mark Serrano

Reputation: 97

Play a certain audio track when clicked

All the songs have a .song class but it plays the first song on the playlist. It's basically the play button for the whole playlist. I've play around with this for awhile and I can't seem to get it right. It might be the simplest thing too. I have the song populate with php depending on the album. I want people to be able to click a certain song and that song plays.

example: http://mixtapemonkey.com/mixtape?m=637

Also if you know how to toggle between the play and stop button, that would be nice to throw in there too. Thanks!

<script>

jQuery(document).ready(function(){

    i=0;

    nowPlaying = document.getElementsByClassName('playsong');
    nowPlaying[i].load();

    $('.play').on('click', function() {
        nowPlaying[i].play();
        callMeta();
    });

    $('.song').on('click', function() {
        nowPlaying[i].play();
        callMeta();
    });

    $('.pause').on('click', function() {
        nowPlaying[i].pause();
        callMeta();
    });

    $('.next').on('click', function() {
        $.each($('audio.playsong'), function(){
            this.pause();
        });
        ++i;
        nowPlaying[i].load();
        nowPlaying[i].play();
        callMeta();

    })

    function callMeta(){
        var trackTitle = $(nowPlaying[i]).attr('data-songtitle');
        $('.songtitle').html(trackTitle);

        var trackArtist = $(nowPlaying[i]).attr('data-songartist');
        $('.songartist').html(trackArtist);

    }

})

Upvotes: 4

Views: 259

Answers (2)

adeneo
adeneo

Reputation: 318302

You have to target the audio element inside each .song, now you're always targeting the first one.
To toggle, check if the audio is paused, and play() or pause() accordingly :

$('.song').on('click', function() {
    var audio = $('.playsong', this).get(0);

    if (audio.paused) {
         audio.play();
    }else{
         audio.pause()
    }
    callMeta();
});

EDIT:

with a few changes, I'm guessing something like this would work :

jQuery(document).ready(function($){

    var audios = $('.playsong');
    var audio  = audios.get(0);

    audio.load();

    $('.play').on('click', function() {
        callMeta(audio);
    });

    $('.song').on('click', function() {
        audio = $('.playsong', this).get(0);
        callMeta(audio);
    });

    $('.pause').on('click', function() {
        audio.pause();
    });

    $('.next').on('click', function() {
        var i = audios.index(audio);
        audio = $(audios).get(i+1);
        callMeta(audio);
    });

    function callMeta(elem){
        audios.each(function(i,el) {
            if (!el.paused) {
                el.pause();
                el.currentTime = 0;
            }
        });
        elem.load();
        elem.play();
        $(elem).on('ended', function() {
            $('.next').trigger('click');
        });
        $('.songtitle').html($(elem).attr('data-songtitle'));
        $('.songartist').html( $(elem).attr('data-songartist') );
    }
});

Upvotes: 4

Trojan
Trojan

Reputation: 2254

Just for clarity - you say the songs have class "song", yet your code says "playsong". A typo, perhaps?

The first song always plays because you always play nowPlaying[i], and i=0 - which only changes when $('.next').on('click', function(){}) is called! You need a way to either change i when a song is clicked, or make the HTML more "modular" (I use this loosely) around each song.

Example HTML:

<audio id="coolSong1">
    <!-- Sources -->
</audio>
<!-- I'm not sure what you're using as play, pause, next buttons, so I'll use buttons -->
<input type="button" class="play" name="coolSong1" value="play" />
<input type="button" class="pause" name="coolSong1" value="pause" />
<input type="button" class="next" name="coolSong1" value="next" />

Corresponding script:

$(".play").click(function(event) {
    document.getElementById(event.target.name).play();
});
$(".pause").click(function(event) {
document.getElementById(event.target.name).pause();
});

Upvotes: 0

Related Questions