PodRadio.js – Cross-Domain JS Podcast Player

Ever wanted to load a podcast (or several) onto your web site, but didn’t have the resources to make a proxy to get around cross-domain scripting issues? Worry no more! PodRadio.js is here.

I’ll be the first to admit, it’s still in its infancy, but I managed to load and run a pretty effective demo with it. I’ll build it out with new features as time allows.

Part of how this works is by using YQL. If you’re unfamiliar with it, check out my article on using YQL for just this purpose.

Get PodRadio on GitHub

PodRadio.js

/*
Version 1.0
By Brian Rollins (BrianRollins.com)

Requires jQuery 1.4 or higher
Tested with jQuery 2.2.3

***Params***
src (String): The URL of the podcast's RSS feed.
id (String): The ID of the div the player will get written into. Also used to create unique tags for the controls.
reverse (Boolean): Reverse the order of the episodes. Usually the RSS has newest first,
                   but if you want the oldest to be first, set this to true. Default: false.

***Usage***
var newPodradio      = new podradio("http://some.rss.feed.url", "newPlayerID");
var reversedPodradio = new podradio("http://another.rss.feed.url", "anotherPlayerID", false);
*/
function podradio(src, id, reverse) {
  if(typeof(reverse)==="undefined"){
    var reverse = false;
  }
  var encodedSrc = encodeURIComponent(src);
  var t = $("#"+id);
  this.id = id;
  this.src = src;
  this.total = 0;
  this.curr = 0;
  $.ajax({
      type: "GET",
      url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'"+encodedSrc+"'&format=json&diagnostics=true&callback=",
      dataType: "json",
      context : this,
      success: function(data) {
        //console.log(data);
        //Load some of the data into the object for potential future use.
        this.results = data.query.results.rss;
        this.total = this.results.channel.item.length;
        this.curr = this.results.channel.item.length-1;
        this.title = this.results.channel.title;
        this.description = this.results.channel.description;
        this.author = this.results.channel.author;
        t.append("<h1 class='podradioPodcastTitle'>"+this.results.channel.title+"</h1>");
        if (reverse) {
          this.results.channel.item.reverse();
        }
        for (var i=this.total-1; i>=0; i-- ) {
            var item = this.results.channel.item[i];
            var d = new Date(item.pubDate);
            t.append("<div id='podRadioContainer_" +this.id+"_"+ i + "' class='podRadioContainer' style='display:none;'></div>");
            container = $("#podRadioContainer_"+this.id+"_"+i);
            container.append("<h2 class='podradioEpisodeTitle'>"+item.title+" ("+(this.total-i)+"/"+this.total+")</h2>");
            container.append("<h3 class='podradioEpisodeDate'>"+d.toLocaleDateString()+"</h3>");
            container.append("<p class='podradioEpisodeDesc'>"+item.description+"</p>");
            container.append("<audio controls id='podradioPlayer"+id+"_"+i+"'><source src='" + item.enclosure.url + "' type='" + item.enclosure.type + "'/></audio>");
        }
        if (typeof(this.ready) !== "undefined"){
          this.ready();
        }
        $("#podRadioContainer_"+this.id+"_"+this.curr).show();
      }
    }); //End AJAX call.
    this.next = function(){
      if(this.curr > 0) {
        this.goto(this.curr-1);
      }
    };
    this.prev = function(){
      if(this.curr < this.total-1){
        this.goto(this.curr+1);
      }
    };
    this.goto = function(g) {
      $("#podRadioContainer_"+this.id+"_"+this.curr).hide();
      this.curr = g;
      $("#podRadioContainer_"+this.id+"_"+this.curr).show();
    };
    this.first = function(){
      this.goto(this.total-1);
    };
    this.last = function(){
      this.goto(0);
    }
};

HTML Demo

<html>
  <head>
    <title>PodRadio.js Demo</title>
    <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
    <script src="podradio.js"></script>
    <link type="text/css" rel="stylesheet" href="style.css"/>
    <link type="text/css" rel="stylesheet" href="podradio.css"/>
  </head>
  <body>
    <h1>PodRadio.js Demo</h1>
    <h3>By <a href="http://brianrollins.com">Brian Rollins</a></h3>
    <p>A simple little demo of loading and playing podcast RSS feeds. It uses
      the Yahoo! YQL engine to bypass cross-domain issues.</p>
      <p>As you can see with the demo, you can load multiple instances of
        players on one page. The limiting factor is the client's memory
        and resources. It uses the HTML5 audio player, but you can tweak it to
        build your own controls.</p>
    <div id="player1"></div>
    <div id="player1_Controls" class="playerControls">
      <a href="#" onclick="myPlayer1.first(); return false;" class="btnControl">First</a>
      <a href="#" onclick="myPlayer1.prev(); return false;" id="player1_Prev" class="btnControl">Previous</a>
      <a class="btnControl" href="#" onclick="myPlayer1.next(); return false;" id="player1_Next">Next</a>
      <a class="btnControl" href="#" onclick="myPlayer1.last(); return false;" id="player1_Next">Last</a>
    </div>
    <div id="player2"></div>
    <div id="player2_Controls" class="playerControls">
      <a href="#" onclick="myPlayer2.first(); return false;" class="btnControl">First</a>
      <a href="#" onclick="myPlayer2.prev(); return false;" class="btnControl">Previous</a>
      <a class="btnControl" href="#" onclick="myPlayer2.next(); return false;">Next</a>
      <a class="btnControl" href="#" onclick="myPlayer2.last(); return false;">Last</a>
    </div>
    <div id="player3"></div>
    <div id="player3_Controls" class="playerControls">
      <a href="#" onclick="myPlayer3.first(); return false;" class="btnControl">First</a>
      <a href="#" onclick="myPlayer3.prev(); return false;" class="btnControl">Previous</a>
      <a class="btnControl" href="#" onclick="myPlayer3.next(); return false;">Next</a>
      <a class="btnControl" href="#" onclick="myPlayer3.last(); return false;">Last</a>
    </div>
    <script>
      var myPlayer1, myPlayer2, myPlayer3; //Need these outside the ready function.
      $("document").ready(function(){
          //Custom ready() addition to podradio.
          podradio.prototype.ready = function(){
            $("#"+this.id+"_Controls").show();
          }
          //EscapePod
          myPlayer1 = new podradio("http://escapepod.org/feed/podcast/", "player1");

          //PodCastle
          myPlayer2 = new podradio("http://feeds.escapeartists.net/PodCastle/", "player2");

          //This is a PodioBook (a serialized audiobook via podcast).
          //It works best with the oldest (first) episode at the front, so we'll reverse it.
          myPlayer3 = new podradio("http://podiobooks.com/rss/feeds/episodes/the-rookie/", "player3", true);
      });
    </script>
  </body>

</html>

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.