How to make this module work for audio playlist

May 29, 2014 at 3:47 PM
Edited May 30, 2014 at 7:19 AM
This module installed OK from gallery into Orchard 1.7.1. It creates a content part "MediaGallery", a content definition "Media Gallery Widget" and adds jPlayer to the admin menu in the dashboard. Making it work should be as simple as creating a media gallery using jPlayer, creating a widget which references content type "Media Gallery Widget" and pointing it at the gallery containing your audio files. This I did and ended up with a JPlayer control panel on my page but with no attached playlist. Inspection of html revealed that a plausible javascript had been generated for the player and playlist but was clearly not being executed by the browser (and I tried many browsers!). Debugging now starts in earnest ...
The source of the javascript is the display template Audio.cshtml, found in ../Modules/Orchard.jPlayer/Views/DisplayTemplates/Parts. This contains the statement:
@Model.MediaGalleryType.Javascript(Model.Medias, Model.AutoPlay, Url.Content("~/Modules/Orchard.jPlayer/Content/Swf/"), id)
This statement inserts the javascript code for the jPlayer in the script. Digging deeper led me into a lot of detailed stringbuilder work which among other things converted the playlist referenced in the parameter Model.Medias and created a JSON object for insertion in the script. There is also another script playlist.js (which looks like a nightmare) which actually creates the jQuery playlist function call. At this point I decided that debugging these server generated scripts was not the answer - after all I just wanted to get my page working!

Here is a recipe that gets it working and provides some pointers for a better version of this module which I might get around to developing one day.
  • Download the jPlayer source from this site or the orchard gallery and build the module in Visual Studio.
  • Visit jPlayer.org website and download latest scripts and css. You need:
jquery.jplayer.min.js
jplayer.playlist.min.js
jplayer.blue.monday.css
jplayer.blue.monday.jpg
jplayer.blue.monday.seeking.gif
  • Put the javascript into the module Scripts folder and the css and images into the module Styles folder overwriting originals.
  • Extract one of the audio playlist demo scripts from the jPlayer.org website. I used this one:
<script type="text/javascript">
    $(function() {
        new jPlayerPlaylist({
            jPlayer: "#jquery_jplayer_1",
            cssSelectorAncestor: "#jp_container_1"
        }, jsonPlayList , {
                    supplied: "oga, mp3, wav",
                    wmode: "window",
                    smoothPlayBar: true,
                    keyEnabled: true
                });
    });
</script>
        <div id="jquery_jplayer_1" class="jp-jplayer"></div>

        <div id="jp_container_1" class="jp-audio">
            <div class="jp-type-playlist">
                <div class="jp-gui jp-interface">
                    <ul class="jp-controls">
                        <li><a href="javascript:;" class="jp-previous" tabindex="1">previous</a></li>
                        <li><a href="javascript:;" class="jp-play" tabindex="1">play</a></li>
                        <li><a href="javascript:;" class="jp-pause" tabindex="1">pause</a></li>
                        <li><a href="javascript:;" class="jp-next" tabindex="1">next</a></li>
                        <li><a href="javascript:;" class="jp-stop" tabindex="1">stop</a></li>
                        <li><a href="javascript:;" class="jp-mute" tabindex="1" title="mute">mute</a></li>
                        <li><a href="javascript:;" class="jp-unmute" tabindex="1" title="unmute">unmute</a></li>
                        <li><a href="javascript:;" class="jp-volume-max" tabindex="1" title="max volume">max volume</a></li>
                    </ul>
                    <div class="jp-progress">
                        <div class="jp-seek-bar">
                            <div class="jp-play-bar"></div>

                        </div>
                    </div>
                    <div class="jp-volume-bar">
                        <div class="jp-volume-bar-value"></div>
                    </div>
                    <div class="jp-current-time"></div>
                    <div class="jp-duration"></div>
                    <ul class="jp-toggles">
                        <li><a href="javascript:;" class="jp-shuffle" tabindex="1" title="shuffle">shuffle</a></li>
                        <li><a href="javascript:;" class="jp-shuffle-off" tabindex="1" title="shuffle off">shuffle off</a></li>
                        <li><a href="javascript:;" class="jp-repeat" tabindex="1" title="repeat">repeat</a></li>
                        <li><a href="javascript:;" class="jp-repeat-off" tabindex="1" title="repeat off">repeat off</a></li>
                    </ul>
                </div>
                <div class="jp-playlist">
                    <ul>
                        <li></li>
                    </ul>
                </div>
                <div class="jp-no-solution">
                    <span>Update Required</span>
                    To play the media you will need to either update your browser to a recent version or update your <a href="http://get.adobe.com/flashplayer/" target="_blank">Flash plugin</a>.
                </div>
            </div>
        </div>

and insert that in Audio.cshtml, replacing all the previous content.
  • Very important ... insert the following statements before the script above in Audio.cshtml:
@{
    Style.Require("MediaPlayer");
    Script.Require("jQueryPlayer");
    Script.Require("jPlayerPlaylist");
}
  • In the script above the parameter jsonPlaylist needs to be assigned a JSON object containing your playlist in the form:
[
            {
                title: "The White Hen She Cackles",
                wav: "/Media/Default/MediaGalleries/Choir/TheWhiteHen.wav"
            }, { etc. }, {etc.}
                  ]
I did all this and it worked after many hours of struggle.
  • Next steps: the assignment of the jsonPlaylist parameter above can be done as a javascript object literal just to get a quick result but ideally it should be fetched from a URL using an ajax call. The URL resource would need to be defined as a Module Controller, say void JSONResult GetPlaylist() returning a JSONResult. The playlist structure would be defined as another class in Models. The advantage of this approach is that the client scripting is kept out of the server side code and makes the whole design more easy to understand, debug and future proof.