سؤال

I'm looking to have an image, that when clicked plays a sound clip (from a list of sound clips) without repeating the same clip (until the user goes through the whole list of sounds.)

At the moment my code works but plays any one of my sound clips randomly and repeats a lot.

If anyone knows how to tweak this to make it play every clip in the list at least once before repeating that would be brilliant!

This is the code I'm using at the moment:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script>
function playSounds() {
    var sounds = [
        "AUDIO URL",
        "AUDIO URL",
        "AUDIO URL",
        "AUDIO URL",
        "AUDIO URL"
    ];

    var index = Math.floor(Math.random() * (sounds.length));
    $("#element").html("<embed src=\"" + sounds[index] + "\" hidden=\"true\" autostart=\"true\" />");
}
</script>

<a onclick="playSounds()"><img src="IMAGE URL" width="300px" id="ImageButton1"></a>

I'm guessing it's something to do with the Math.random() part of the code?

هل كانت مفيدة؟

المحلول

You can use the Array as playlist and maintain the played sounds in a second array. Check my JSfiddle

<a onclick="playSounds()">
   <img src="http://www.stephaniequinn.com/Ani-Piano.gif" width="300px" id="ImageButton1">
</a>
<div id="element"></div>
<script>
var sounds = ["http://www.stephaniequinn.com/Music/Allegro%20from%20Duet%20in%20C%20Major.mp3",
              "http://www.stephaniequinn.com/Music/Canon.mp3",
              "http://www.stephaniequinn.com/Music/Handel%20Royal%20Fireworks%20-%2007.mp3",
              "http://www.stephaniequinn.com/Music/Commercial%20DEMO%20-%2009.mp3"],
    oldSounds = [];

var playSounds = function () {
    var index = Math.floor(Math.random() * (sounds.length)),
        thisSound = sounds[index];

        oldSounds.push(thisSound);
        sounds.splice(index, 1);

        if (sounds.length < 1) {
            sounds = oldSounds.splice(0, oldSounds.length);
        }

        $("#element").html("<audio autoplay><source src=\"" + thisSound + "\" type=\"audio/mpeg\"><embed src=\"" + thisSound + "\" hidden=\"true\" autostart=\"true\" /></audio>");
}
</script>

نصائح أخرى

I haven't ran the following code but the outline should be enough. This will always play the sounds in random order. The steps are:

  1. generate the random indices in a loop until we found one that has not been played yet
  2. when we find one that's not been played add it to an array for future reference and play it
  3. we know we've played all of the sounds when the array's length equals that of the sounds' array. At this point we empty the array and carry on.

    var playedSounds = [];
    
    var sounds = [
        "AUDIO URL",
        "AUDIO URL",
        "AUDIO URL",
        "AUDIO URL",
        "AUDIO URL"
    ];
    
    function hasPlayed(sound) {
    
        if (playedSounds.length == sounds.length) {
    
            // We've played all of the sounds. Reset and start again.
            playedSounds = [];
            playedSounds.push(sound);
            return false;
    
        }
    
        // We haven't played all the sounds yet but check to see whether we've played the current one.
        for (var i = 0; i < playedSounds.length; i++)
            if (playedSounds[i] == sound)
                return true;
    
        // Note that we've now played this sound.
        playedSounds.push(sound);
        return false;
    
    }
    
    function playSounds() {
    
        var index = Math.floor(Math.random() * (sounds.length));
    
        // Loop until we've found a sound that we've not yet played.
        while (hasPlayed(index)) {
    
            index = Math.floor(Math.random() * (sounds.length));
    
        }
    
        $("#element").html("<embed src=\"" + sounds[index] + "\" hidden=\"true\" autostart=\"true\" />");
    
    }
    

I would be tempted to do something like this (JSFiddle example):

var sounds = [];

// Return the full list of URLs in random order
function getSounds() {
    return [
        'url1',
        'url2',
        'url3'
    ].sort(function () {
        // http://stackoverflow.com/a/18650169/283078
        return (.5 - Math.random());
    });
}

// Play the next sound
function playSound() {
    if (!sounds.length) {
        // Get the list of sounds (random order)
        sounds = getSounds();
    }

    // Pops a URL every time, ensuring all are played exactly once
    $("#element").html(
        '<embed src="' + sounds.pop() +
        '" hidden="true" autostart="true" />'
    );

    // Once all the URLs have been popped, the process starts again
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top