1

I'm an absolute newbie with javascript, but I'm just trying to tweak JPlayer to use an XML file for the playlist instead of the hard-coded playlist. So, here's the bit of code that creates the playlist:

//<![CDATA[
$(document).ready(function(){

    var Playlist = function(instance, playlist, options) {
        var self = this;

        this.instance = instance; // String: To associate specific HTML with this playlist
        this.playlist = playlist; // Array of Objects: The playlist
        this.options = options; // Object: The jPlayer constructor options for this playlist

        this.current = 0;

        this.cssId = {
            jPlayer: "jquery_jplayer_",
            interface: "jp_interface_",
            playlist: "jp_playlist_"
        };
        this.cssSelector = {};

        $.each(this.cssId, function(entity, id) {
            self.cssSelector[entity] = "#" + id + self.instance;
        });

        if(!this.options.cssSelectorAncestor) {
            this.options.cssSelectorAncestor = this.cssSelector.interface;
        }

        $(this.cssSelector.jPlayer).jPlayer(this.options);

        $(this.cssSelector.interface + " .jp-previous").click(function() {
            self.playlistPrev();
            $(this).blur();
            return false;
        });

        $(this.cssSelector.interface + " .jp-next").click(function() {
            self.playlistNext();
            $(this).blur();
            return false;
        });
    };

    Playlist.prototype = {
        displayPlaylist: function() {
            var self = this;
            $(this.cssSelector.playlist + " ul").empty();
            for (i=0; i < this.playlist.length; i++) {
                var listItem = (i === this.playlist.length-1) ? "<li class='jp-playlist-last'>" : "<li>";
                listItem += "<a href='#' id='" + this.cssId.playlist + this.instance + "_item_" + i +"' tabindex='1'>"+ this.playlist[i].name +"</a>";

                // Create links to free media
                if(this.playlist[i].free) {
                    var first = true;
                    listItem += "<div class='jp-free-media'>(";
                    $.each(this.playlist[i], function(property,value) {
                        if($.jPlayer.prototype.format[property]) { // Check property is a media format.
                            if(first) {
                                first = false;
                            } else {
                                listItem += " | ";
                            }
                            listItem += "<a id='" + self.cssId.playlist + self.instance + "_item_" + i + "_" + property + "' href='" + value + "' tabindex='1'>" + property + "</a>";
                        }
                    });
                    listItem += ")</span>";
                }

                listItem += "</li>";

                // Associate playlist items with their media
                $(this.cssSelector.playlist + " ul").append(listItem);
                $(this.cssSelector.playlist + "_item_" + i).data("index", i).click(function() {
                    var index = $(this).data("index");
                    if(self.current !== index) {
                        self.playlistChange(index);
                    } else {
                        $(self.cssSelector.jPlayer).jPlayer("play");
                    }
                    $(this).blur();
                    return false;
                });

                // Disable free media links to force access via right click
                if(this.playlist[i].free) {
                    $.each(this.playlist[i], function(property,value) {
                        if($.jPlayer.prototype.format[property]) { // Check property is a media format.
                            $(self.cssSelector.playlist + "_item_" + i + "_" + property).data("index", i).click(function() {
                                var index = $(this).data("index");
                                $(self.cssSelector.playlist + "_item_" + index).click();
                                $(this).blur();
                                return false;
                            });
                        }
                    });
                }
            }
        },
        playlistInit: function(autoplay) {
            if(autoplay) {
                this.playlistChange(this.current);
            } else {
                this.playlistConfig(this.current);
            }
        },
        playlistConfig: function(index) {
            $(this.cssSelector.playlist + "_item_" + this.current).removeClass("jp-playlist-current").parent().removeClass("jp-playlist-current");
            $(this.cssSelector.playlist + "_item_" + index).addClass("jp-playlist-current").parent().addClass("jp-playlist-current");
            this.current = index;
            $(this.cssSelector.jPlayer).jPlayer("setMedia", this.playlist[this.current]);
        },
        playlistChange: function(index) {
            this.playlistConfig(index);
            $(this.cssSelector.jPlayer).jPlayer("play");
        },
        playlistNext: function() {
            var index = (this.current + 1 < this.playlist.length) ? this.current + 1 : 0;
            this.playlistChange(index);
        },
        playlistPrev: function() {
            var index = (this.current - 1 >= 0) ? this.current - 1 : this.playlist.length - 1;
            this.playlistChange(index);
        }
    };

    var mediaPlaylist = new Playlist("1", [

        {
            name:"song1",
            mp3: "song1.mp3",
            poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"
        },
            {
            name:"song2",
            mp3: "song2.mp3",
            poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"
        },
            {
            name:"song3",
            mp3: "song3.mp3",
            poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"**
        }

    ], {
        ready: function() {
            mediaPlaylist.displayPlaylist();
            mediaPlaylist.playlistInit(false); // Parameter is a boolean for autoplay.
        },
        ended: function() {
            mediaPlaylist.playlistNext();
        },
        swfPath: "js",
        supplied: "ogv, m4v, oga, mp3"
    });
});

The part that starts with "var mediaPlaylist" is the only section i need to change. Instead of having the keys/values as name: songname, mp3: mp3, etc., I want it to pull these values from an XML file, or better yet, just push them into the array from an XML that looks like:

<song>songname</song>
<mp3>file.mp3</mp3>

The thing that's mostly confusing me here is how that function/array is set up...too many curly braces and brackets to wrap my head around. How do I get into this without breaking it?

Jack B
  • 313
  • 1
  • 3
  • 9
  • Is the XML playlist file on the same server as the page that includes the JavaScript in your question? – andyb Jun 29 '11 at 14:54
  • This doesn't really answer your question but I wanted to explain the notation of the mediaPlaylist. First, they instantiate a new object of class Playlist, which seems to take three arguments. The second argument is an array of objects, each of which has three properties, ("name", "mp3" and "poster"). Each of those curly braces is an object literal - the object equivalent of an anonymous function. The square brackets around them with commas between makes it an array of object literals. The third argument seems to be an options object, whose first two properties are callback functions. – T Nguyen Jun 29 '11 at 15:18

1 Answers1

1

If you have a server side XML playlist file in the form:

<?xml version="1.0" encoding="UTF-8"?>
<playlist>
  <entry>
    <song>songname</song>
    <mp3>file.mp3</mp3>
  </entry>
  <entry>
    <song>songname2</song>
    <mp3>file2.mp3</mp3>
  </entry>
</playlist>

then you can load this from the client via AJAX and create a JSON array from the XML. The following example uses the jQuery JavaScript framework and also the jquery-json plugin (only to format the Array nicely as JSON). You should be able to run this on Chrome or Firefox as both have a console (accessed by pressing F12 in the browser) in which I am outputting the JSON array.

Note: You could change console.log(...) to alert(...) if you don't use either of those browsers.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://jquery-json.googlecode.com/files/jquery.json-2.2.min.js"></script>
    <script type="text/javascript">
        $(function() {
            var Playlist = function(instance, playlist, options) {
                var self = this;
                this.instance = instance;
                this.playlist = playlist;
                this.options = options;
            };

            function getPlaylist(callback) {
                var songs = new Array();
                $.ajax({
                    dataType:'xml',
                    url:'songs.xml',
                    success : function (xml) {
                        $(xml).find('entry').each(function() {
                            songs.push({name: $(this).find('song').text(), mp3: $(this).find('mp3').text()});
                        });
                        callback(songs);
                    }
                });
            }

            getPlaylist(function(songs) {
                var playlistFromXML = jQuery.toJSON(songs);

                var mediaPlaylist = new Playlist('1', playlistFromXML, null);
                console.log(mediaPlaylist);
                // etc...
            });
        });
    </script>
</head><body></body></html>

Credit to How to return an array from jQuery ajax success function properly? answer as I used that approach to return a value from the jQuery $.ajax success method.

You will have to refactor the var mediaPlaylist = new Playlist() constructor into the callback function though as you cannot return the playlist value from the callback (see How can I catch the return value from the result() callback function that I'm using?)

Hope this helps :-)

Community
  • 1
  • 1
andyb
  • 43,435
  • 12
  • 121
  • 150
  • Thank you so much! I'm going to give this a shot. – Jack B Jul 01 '11 at 17:24
  • Thank you thank you thank you! I got it working. For some reason, the JSON was fudging it up so I just plugged songs in where playlistfromXML went. – Jack B Jul 01 '11 at 19:32