Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to play mp3 playlists with SoundManager using the controls

I am trying to play multiple audio files using SoundManager2 and so far this is the only working example I could find of the site.

<script src="/path/to/soundmanager2.js"></script>
<script>
soundManager.setup({
  url: '/path/to/swf-files/',
  onready: function() {
    var mySound = soundManager.createSound({
      id: 'aSound',
      url: '/path/to/example.mp3'
    });
    mySound.play();
  },
  ontimeout: function() {
    // Hrmm, SM2 could not start. Missing SWF? Flash blocked? Show an error, etc.?
  }
});
</script>

Even though, I can play example.mp3 with the above example, I would like to use the playlist as shown in this example. Sadly, that page does not mention anything about how to implement the playlist feature.

I currently have a Json that returns the mp3 paths for a given song artist, like this:

{
  "john_doe":"/path/to/audio/john_doe.mp3",
  "jane_smith":"/path/to/audio/jane_smith.mp3",
}

So, how can I incorporate this json data to make a playlist of, for example 2 songs.

like image 839
robue-a7119895 Avatar asked Apr 25 '15 00:04

robue-a7119895


1 Answers

You can use a list like you want. You can hard code it as below or use your JSON result. This will loop them endlessly:

    var audio = [];
// Array of files you'd like played
audio.playlist = [
    "/canvas/audio/Marissa_Car_Chase.mp3",
    "/canvas/audio/Vortex_Battl_Thru_Danger.mp3",
    "/canvas/audio/Gadgets_Activated.mp3",
    "/canvas/audio/Kids_Run_Into_Agents.mp3",
    "/canvas/audio/Jet_Luge_Chase.mp3"
];
 
function playAudio(playlistId){
    // Default playlistId to 0 if not supplied 
    playlistId = playlistId ? playlistId : 0;
    // If SoundManager object exists, get rid of it...
    if (audio.nowPlaying){
        audio.nowPlaying.destruct();
        // ...and reset array key if end reached
        if(playlistId == audio.playlist.length){
            playlistId = 0;
        }
    }
    // Standard Sound Manager play sound function...
    soundManager.onready(function() {
        audio.nowPlaying = soundManager.createSound({
            id: 'sk4Audio',
            url: audio.playlist[playlistId],
            autoLoad: true,
            autoPlay: true,
            volume: 50,
            // ...with a recursive callback when play completes
            onfinish: function(){
                playlistId ++;
                playAudio(playlistId);
            }
        })
    });
}
 
// Start
playAudio[0];

Then, make sure you aren't running into the Flash 8 issue:

From SoundManager2's Revision History:

Flash Player 11.6.602.171, released by Adobe on 02/26/2013, introduced an issue with SM2's default Flash 8 (flashVersion: 8) API-based JS/Flash interaction, where SM2 methods called from callbacks such as onfinish() would not work. This primarily broke methods used for playing sounds in sequence, serially loading a series of sounds and so on. (See discussion for more.)

Note that this does not affect cases where soundManager.setup({ flashVersion: 9}) is being used; however, SM2 does use flashVersion: 8 by default.

Specifically, Flash-initiated events (such as a sound finishing) make Flash -> JS calls to the SM2 API, which subsequently call user-specified event handlers. If the user-specified SM2 onfinish() handler immediately calls a SM2 method like play() that makes a JS -> Flash call, this call either silently fails or is blocked. Other JS + Flash libraries that use similar callback patterns may also be affected, if their SWF is built targeting the Flash 8 API.

Suspecting a timing or recursion/stack issue, it was found that introducing a setTimeout(callback, 0) to user-specified SM2 callbacks like onfinish() restored sequential/playlist functionality.

Flash Player 11.6.602.180, relased by Adobe on 3/12/2013, exhibits the same behaviour. To avoid additional hacks, SM2 applies this to all Flash 8-based API callbacks regardless of what version of Flash Player is installed. No regressions are anticipated as a result of this change.

Alternately, this issue can be avoided by using soundManager.setup({ flashVersion: 9 }) as the Flash 9-based API does not appear to have this problem.

Note that in the example, the playlist drawer is inserted here:

This is the menu button for triggering the dropdown ("drawer"). The JavaScript will take care of everything based upon the class names you assign shown here:

  <div class="sm2-inline-element sm2-button-element sm2-menu">
   <div class="sm2-button-bd">
    <a href="#menu" class="sm2-inline-button menu">menu</a>
   </div>
  </div>

This is the title bar:

    <div class="sm2-playlist">
    <div class="sm2-playlist-target">
     <!-- playlist <ul> + <li> markup will be injected here -->
     <!-- if you want default / non-JS content, you can put that here. -->
     <noscript><p>JavaScript is required.</p></noscript>
    </div>
   </div>

Playlist Drawer (first part builds the drawer / second builds the playlist itself in the drawer.

 <div class="bd sm2-playlist-drawer sm2-element">

  <div class="sm2-inline-texture">
   <div class="sm2-box-shadow"></div>
  </div>

  <!-- playlist content is mirrored here -->

  <div class="sm2-playlist-wrapper">
        <ul class="sm2-playlist-bd">
         <li><a href="http://freshly-ground.com/data/audio/sm2/SonReal%20-%20I%20Tried.mp3">
           <b>SonReal</b> - I Tried</a></li>
        </ul>
      </div>

 </div>

</div>

Random research tips:

  • The html nodes are modified via the utility function rather than JQuery or something else you might have been looking for. You can find the code for this at the beginning of the bar-ui.js file in case you want to be able to understand what all the other source code is doing better.
  • The CSS file you're looking for is bar-ui.css. It gives you all the style you need.
  • In a browser like Chrome you can right click an area and select "Inspect Element" to see what part of the page a DIV refers to.
like image 118
Palu Macil Avatar answered Oct 26 '22 15:10

Palu Macil