Steven Erat's Blog
 
 
Viewing By Entry
 
 

TalkingTree  Updated: Now Playing Pod for BlogCFC

 

Listen to iTunes for fun and profit!

The Now Playing pod has been updated to take advantage of the additional info present in the iTunes plug-in on Windows such as Amazon Associate ID URL, Amazon album artwork, and Apple Music Store URL. I've also added a Creative Commons license, and changed the pod behavior so when iTunes is stopped a message states that no song is playing but provides text, artwork, and URL of last song played.

The pod will link the album art or title to the Amazon URL with your Associate ID if you configure the Now Playing plug-in that way and if the plug-in sends that information with the now_playing.xml XML packet. The current Mac version of the iTunes plug-in cannot be configured for Amazon or Apple Music store, but if you use iTunes on Windows then you're good to go. At work I listen to iTunes on Mac, so you will only see the linked artwork in my pod on the left when I'm at home.

Download Now Playing Pod. This work is licensed under a Creative Commons License.

Creative Commons License



<cfsetting enablecfoutputonly=true>
<cfprocessingdirective pageencoding="utf-8">
<!---
   name      : now_playing.cfm
   version      : 0.93
   author      : steven erat
   license      : now_playing.cfm Pod for BlogCFC, Copyright © 2006 Steven Erat, licensed under
                    a Creative Commons Attribution-NonCommercial-ShareAlike License
                    (http://creativecommons.org/licenses/by-nc-sa/2.5/)
   created      : monday, feb 20, 2006
   updated      : saturday, feb 25 2006 - bug fixes, added Amazon/Apple URL and image features, utf-8 fix
   history      : saw a now playing pod on matt woodward's (blogfusion) blog.
                    thought blogcfc should have it, too. built to work with xml exported
                    from brandon fuller's now playing plugin for itunes, available at
                    http://brandon.fuller.name./archives/hacks/nowplaying/
   purpose      : show what's playing on itunes on your blogcfc, and maybe make some profit with Amazon
   assumptions   : (1)assumes the plug-in data file is called 'now_playing.xml' (default)
              (2)assumes that the file is written to a subdirectory called 'nowplaying/'
                    in the blog root directory (same level as includes/ and tags/)
   usage      : (1)install the plug-in for itunes (purchase required)
              (2)create a subdirectory called 'nowplaying' such as {blog_root}/nowplaying/,
                     this subdirectory is recommended since the artwork jpg files will be uploaded too.
              (3)configure plugin to upload (ftp) the now_playing.xml file to that directory
              (4)customize the few the settings below, and save this file to {blog_root}/includes/pods/
              (5)configure tags/layout.cfm to display this pod betwixt the other pods
              (6)once itunes stops playing for a while and starts playing again,
                     it will take snooze(minutes) that much time to realize itunes is active again
              (7)the Windows version of plug-in has more features than on Mac, and allows for
                     usage of Amazon album cover, Amazon URLs with Associate ID, or Apple Music Store URLs
--->

<!--- CUSTOMIZE POD SETTINGS HERE --->

   <!--- name of the plug-in data file that was uploaded --->
   <cfset myNowPlayingFilename = "now_playing.xml">
   
   <!--- starting at top of document root, what is the directory containing
    the blog files so start path with a forward slash like "/blog",
       but if blog is at top of doc root use just empty string "" --->

   <cfset myBlogRootDir = "/blog">
   
   <!--- name of the subdirectory where data file resides --->
   <!--- this setting will be used by itself and also combined
    with myBlogRootDir to form an absolute path such as /blog/nowplaying/ --->

   <cfset myNowPlayingSubDir = "nowplaying">
   
   <!--- "\" for Windows, or "/" for Unix,Linux,Mac --->
   <!--- this refers to the ColdFusion server's OS, not your iTune's OS --->
   <cfset myFileSeparator = "\">
   
   <!--- this will display as the pod title (styled by .menuTitle) --->
   <cfset myPodTitle = "playing on itunes">
   
   <!--- what text should be displayed if iTunes is stopped --->
   <cfset myIdleMessage = "recently played">
   
   <!--- to cut down on checking the filesystem for updates,
       set the following parameters according to your preferences,
       may want to set longest time higher if you want your podcasts
       to show for the full duration --->

   <cfset myAverageSongPlayTime = 3>
   <cfset myLongestPlayTime = 10>
   
<!--- END ALL CUSTOMIZATIONS, NO REAL NEED TO EDIT FURTHER --->

<!--- redirect to website root dir if pod is viewed directly outside of blog --->
<cfif cgi.script_name contains "/includes/pods/">
   <cflocation addtoken="No" url="#variables.myBlogRootDir#">
</cfif>

<!--- start custom functions --->
<cffunction name="checkinterval"
      access="public"
      description="check if n minutes have passed since last song was uploaded"
      hint="helps to reduce the frequency of checking timestamp of now_playing.xml"
      returntype="struct"
      output="no">

      <cfargument name="timestamp" required="yes" type="date">
      <cfargument name="min" required="yes" type="numeric">
      <cfargument name="max" required="yes" type="numeric">
      <cfset var minutessincelastupdate = datediff('n',arguments.timestamp,now())>
      <cfset var result = structNew()>
      <cfset result.minutes = minutessincelastupdate>
      <cfif (minutessincelastupdate gte arguments.min and minutessincelastupdate lte arguments.max)>
         <cfset result.status = true>
         <cfreturn result>
      <cfelse>
         <cfset result.status = false>
         <cfreturn result>
      </cfif>
</cffunction>

<cffunction name="snooze"
      access="public"
      description="return true (snoozing) until n minutes have passed (not snoozing)."
      hint="This function dependent on application scope, and improves efficiency for when iTunes is idle"
      returntype="boolean"
      output="no">

      <cfargument name="minutes" required="yes" type="numeric">
      <cfif structkeyexists(application,"nowplaying") and structkeyexists(application.nowplaying,"snooze") and structkeyexists(application.nowplaying.snooze,"start#arguments.minutes#")>
          <cfif datediff('n',application.nowplaying.snooze["start#arguments.minutes#"],now()) gte arguments.minutes>
            <!--- reset the alarm clock --->
            <cfset application.nowplaying.snooze["start#arguments.minutes#"] = now()>
            <!--- wake up --->
            <cfreturn false>
         <cfelse>
            <!--- snooze for a while --->
            <cfreturn true>
         </cfif>
      <cfelse>
         <!--- get here on startup or reinit --->
         <cfset application.nowplaying.snooze["start#arguments.minutes#"] = now()>
         <!--- snooze for a while --->
         <cfreturn true>
      </cfif>
      <cfreturn true>
</cffunction>

<cffunction name="refreshplaylist"
      access="public"
      description="check to see if now_playing.xml has changed"
      returntype="struct"
      output="no">

      <cfargument name="nowplayingdir" required="yes" type="string">
      <cfargument name="nowplayingfile" required="yes" type="string">
      <cfargument name="lastsongtimestamp" required="yes" type="date">
      <cfset var nowplayingfiledata = "">
      <cfset var minutessincelastupdate = "">
      <cfset var result = structnew()>
      <cftry>
         <cfdirectory name="nowplayingfiledata" action="list" directory="#arguments.nowplayingdir#" filter="#arguments.nowplayingfile#">
         <!--- if current xml file has timestamp newer than timestamp in memory, update the in memory version --->
         <cfif arguments.lastsongtimestamp lt nowplayingfiledata.datelastmodified>
            <cfset result.datelastmodified = nowplayingfiledata.datelastmodified>
            <cfset result.status = true>
            <cfreturn result>
         <cfelse>
            <cfset result.datelastmodified = "">
            <cfset result.status = false>
            <cfreturn result>
         </cfif>
      <cfcatch>
         <cfset result.datelastmodified = "">
         <cfset result.status = false>
         <cfreturn result>
      </cfcatch>
      </cftry>
</cffunction>

<cffunction name="getcurrentsong"
   access="public"
   description="use with now playing plug-in for itunes"
   returntype="struct"
   output="no">

   <cfargument name="nowplayingdir" required="yes" type="string">
   <cfargument name="nowplayingfile" required="yes" type="string">
   <cfset var nowplayingxml="">
   <cfset var nowplayingobj="">
   <cfset var song = structnew()>
   <cfset var nowplayingfullfilepath = "#arguments.nowplayingdir##arguments.nowplayingfile#">
   <cfif fileexists(nowplayingfullfilepath)>
      <cftry>
         <cflock type="exclusive" name="nowplayingfilelock" timeout="10" throwontimeout="no">
            <cffile action="read" file="#nowplayingfullfilepath#" variable="nowplayingxml" charset="utf-8">
         </cflock>
         <!--- wish I didn't have to do this, but with the xml declaration xmlparse barfs --->
         <cfset nowplayingxml = replace(nowplayingxml,"<?xml version='1.0' encoding='utf-8'?>",'',"one")>
         <cfset nowplayingobj = xmlparse(nowplayingxml)>
         <cfset song.isplaying = nowplayingobj.now_playing.xmlattributes.playing>
         <cfif song.isplaying>
            <!--- basic information found in Mac and Windows plug-in for iTunes --->
            <cfset song.artist = nowplayingobj.now_playing.song.artist.xmltext>
            <cfset song.title = nowplayingobj.now_playing.song.title.xmltext>
            <cfset song.album= nowplayingobj.now_playing.song.album.xmltext>
            <cfset song.genre = nowplayingobj.now_playing.song.genre.xmltext>
            <cfset song.comments = nowplayingobj.now_playing.song.comments.xmltext>
            <cfset song.artworkid = nowplayingobj.now_playing.song.artworkid.xmltext>
            <!--- intialize optional values --->
            <cfset song.imageURL = "">
            <cfset song.urlAmazon = "">
            <cfset song.urlApple = "">
            <!--- optional information available in the iTunes plugin for Windows --->
            <cfif isdefined("nowplayingobj.now_playing.song.image.xmltext")>
               <cfset song.imageURL = nowplayingobj.now_playing.song.image.xmltext>
            </cfif>
            <cfif isdefined("nowplayingobj.now_playing.song.urlAmazon.xmltext")>
               <cfset song.urlAmazon = nowplayingobj.now_playing.song.urlAmazon.xmltext>
            </cfif>
            <cfif isdefined("nowplayingobj.now_playing.song.urlApple.xmltext")>
               <cfset song.urlApple = nowplayingobj.now_playing.song.urlApple.xmltext>
            </cfif>
         </cfif>
      <cfcatch>
         <cfset song.isplaying = 0>
      </cfcatch>
      </cftry>
   <cfelse>
      <cfset song.isplaying = 0>
   </cfif>
   <cfreturn song>
</cffunction>
<!--- end custom functions --->

<!--- set a debug flag to clear stored pod data --->
<cfif isdefined("url.reinit") and isuserinrole("admin")>
   <cfset structdelete(application,"nowplaying")>
</cfif>

<cfif not isdefined("application.nowplaying.datafile") or not isdefined("application.nowplaying.datadir")>
   <cfset application.nowplaying = structnew()>
   <!--- set the name of the xml file uploaded by the itunes plugin --->
   <cfset application.nowplaying.datafile = variables.myNowPlayingFilename>
   <!--- assumes that a directory called "nowplaying" exists in the blog's root dir
       and this is where you have configured the itunes plugin to upload to --->

   <cfset application.nowplaying.datadir = getdirectoryfrompath(cgi.path_translated) & variables.myNowPlayingSubDir & variables.myFileSeparator>
</cfif>

<cfset variables.nowplaying = structnew()>
<cfset variables.nowplaying.datafile = application.nowplaying.datafile>
<cfset variables.nowplaying.datadir = application.nowplaying.datadir>
<cfset variables.nowplaying.idle = false>

<cfif not structkeyexists(application.nowplaying,"idle")>
   <cflock name="applicationnowplayingidle" type="exclusive" timeout="5" throwontimeout="no">
      <cfset application.nowplaying.idle = false>
   </cflock>
</cfif>

<!--- on startup or reinit this will get called to satisfy the need for last song timestamp --->
<cfif not isdefined("application.nowplaying.lastsong.datelastmodified")>
   <!--- lock for race condition --->
   <cflock name="applicationnowplayinglastsongdatelastmodified" type="exclusive" timeout="5" throwontimeout="no">
      <cfset application.nowplaying.lastsong.datelastmodified = now()>
      <cfset variables.nowplaying.lastsong.datelastmodified = duplicate(application.nowplaying.lastsong.datelastmodified)>
   </cflock>
<cfelse>
   <!--- lock for race condition, and read from cached app scope into local scope --->
   <cflock name="applicationnowplayinglastsongdatelastmodified" type="readonly" timeout="5" throwontimeout="no">
      <cfset variables.nowplaying.lastsong.datelastmodified = duplicate(application.nowplaying.lastsong.datelastmodified)>
   </cflock>
</cfif>

<cfset variables.nowplaying.readsongfromcache = false>

<!--- check to see if current song has changed and do refreshplaylist():
      - checkinterval() will only attempt to refreshplaylist() (by checking now_playing.xml timestamp)
       between the min and max timespan.
      - if more than n minutes have passed, exceeding checkinteval's max value,
       then no refreshplaylist() will be attempted because it is assumed iTunes is not playing anymore
      - snooze(n) is used to periodically wake up and refreshplaylist(),
       and is useful to break out of the idle time when iTunes has stopped but is now playing again.
      - Example: checkinterval(variables.nowplaying.lastsong.datelastmodified,3,10) or not snooze(5)   
          - Here refreshplaylist() will check now_playing.xml 3 minutes after the last song was started
         - refreshplaylist() will stop checking 10 minutes after last song started (assuming long podcast)
         - and snooze(5) will let refreshplaylist() check the time on now_playing.xml every 5 minutes
          where snooze() will break out of the lull when iTunes idle time exceeds checkinterval's max time of 10 minutes. --->

<cfset currentinterval = checkinterval(variables.nowplaying.lastsong.datelastmodified,variables.myAverageSongPlayTime,variables.myLongestPlayTime)>

<cfif currentinterval.status is true or (currentinterval.minutes GT variables.myLongestPlayTime and snooze(5) is not true)>
   <cfset variables.nowplaying.refreshresult = refreshplaylist(variables.nowplaying.datadir,variables.nowplaying.datafile,variables.nowplaying.lastsong.datelastmodified)>
   <cfif variables.nowplaying.refreshresult.status is true>
      <!--- lock for race condition while updating cached timestamp of last song (equal to timestamp of current song) --->
      <cflock name="applicationnowplayinglastsongdatelastmodified" type="exclusive" timeout="5" throwontimeout="no">
         <cfset application.nowplaying.lastsong.datelastmodified = variables.nowplaying.refreshresult.datelastmodified>
      </cflock>
      <!--- set or reset the local current song struct data --->
      <cfset variables.nowplaying.currentsong = getcurrentsong("#variables.nowplaying.datadir#","#variables.nowplaying.datafile#")>
      <!--- do not overwrite app var if song is not playing since "last song" info will be displayed anyway--->
      <cfif variables.nowplaying.currentsong.isplaying is true>
         <!--- lock for race condition while updating cache of current song data --->
         <cflock name="applicationnowplayingcurrentsong" type="exclusive" timeout="5" throwontimeout="no">
            <cfset application.nowplaying.currentsong = variables.nowplaying.currentsong>
         </cflock>
      </cfif>
      <cflock name="applicationnowplayingidle" type="exclusive" timeout="5" throwontimeout="no">
         <cfset application.nowplaying.idle = false>
      </cflock>
      <!--- only clear on index.cfm since others like stats.cfm don't use caching --->
      <cfif cgi.script_name contains "/index.cfm">
         <!--- clear the scopecache to refresh blog view with new song shown in pod --->
         <cfmodule template="../../tags/scopecache.cfm" scope="application" clearall="true">
      </cfif>
      <cfset variables.nowplaying.currentsong.isplaying = true>
   <cfelse>
      <cfset variables.nowplaying.readsongfromcache = true>
      <cfset variables.nowplaying.currentsong.isplaying = true>
   </cfif>
<cfelse>
   <cfset variables.nowplaying.readsongfromcache = true>
   <cfset variables.nowplaying.currentsong.isplaying = true>
</cfif>

<!--- test for first ocassion exceeding the max long play time,
    and clear scopecache to show no song is playing --->

<cfif currentinterval.minutes GTE variables.myLongestPlayTime>
   <cflock name="applicationnowplayingidle" type="readonly" timeout="5" throwontimeout="no">
      <cfset variables.nowplaying.idle = duplicate(application.nowplaying.idle)>
   </cflock>
   <cfif variables.nowplaying.idle is false>
      <cflock name="applicationnowplayingidle" type="exclusive" timeout="5" throwontimeout="no">
         <cfset application.nowplaying.idle = true>
         <cfset variables.nowplaying.idle = true>
         <!--- only clear on index.cfm since others like stats.cfm don't use caching --->
         <cfif cgi.script_name contains "/index.cfm">
            <!--- clear the scopecache to refresh blog view to show no song is playing --->
            <cfmodule template="../../tags/scopecache.cfm" scope="application" clearall="true">
         </cfif>
      </cflock>
   </cfif>
</cfif>

<!--- should only go into this when starting up --->
<cfif not isdefined("application.nowplaying.currentsong")>
   <!--- lock for race condition while updating cached timestamp of last song (equal to time of current song) --->
   <cflock name="applicationnowplayinglastsongdatelastmodified" type="exclusive" timeout="5" throwontimeout="no">
      <cfset application.nowplaying.lastsong.datelastmodified = now()>
   </cflock>
   <!--- set or reset the local current song struct data --->
   <cfset variables.nowplaying.currentsong = getcurrentsong("#variables.nowplaying.datadir#","#variables.nowplaying.datafile#")>
   <!--- lock for race condition while updating cache of current song data --->
   <cflock name="applicationnowplayingcurrentsong" type="exclusive" timeout="5" throwontimeout="no">
      <cfset application.nowplaying.currentsong = variables.nowplaying.currentsong>
   </cflock>
</cfif>

<cfif variables.nowplaying.readsongfromcache or variables.nowplaying.idle>
   <cflock name="applicationnowplayingcurrentsong" type="readonly" timeout="5" throwontimeout="no">
      <cfset variables.nowplaying.currentsong = duplicate(application.nowplaying.currentsong)>
   </cflock>
</cfif>

<!--- the myIdleMessage text will appear myLongestPlayTime minutes --->
<cfif variables.nowplaying.idle>
   <!--- change the pod title from now playing message to recently playing message --->
   <cfset variables.myPodTitle = variables.myIdleMessage>
</cfif>
            
<!--- this is the meat of the pod, what gets shown on screen --->
<cfmodule template="../../tags/podlayout.cfm" title="#variables.myPodTitle#">
   <cfoutput>
      <table>
      <cftry>
            <tr><td>
            <strong>#variables.nowplaying.currentsong.title#</strong>
            <br/>by #variables.nowplaying.currentsong.artist#
            <br/>on             
            <cfif variables.nowplaying.currentsong.album neq "">
               <!--- throw an Amazon link around album title text if no artwork available --->
               <cfif variables.nowplaying.currentsong.imageURL eq ""
               and variables.nowplaying.currentsong.artworkID eq ""
               and variables.nowplaying.currentsong.urlAmazon neq "">

               <a href="#variables.nowplaying.currentsong.urlAmazon#"
               title="Get #variables.nowplaying.currentsong.urlAmazon# by #variables.nowplaying.currentsong.artist# on Amazon">
#variables.nowplaying.currentsong.album#</a>
               <cfelse>
                  #variables.nowplaying.currentsong.album#
               </cfif>   
            </cfif>
            </td></tr>      
            
            <!--- show the uploaded artwork in amazon link with associate id if present --->
            <cfif variables.nowplaying.currentsong.urlAmazon neq "" and fileexists("#variables.nowplaying.datadir#now_playing-#variables.nowplaying.currentsong.artworkid#.jpg")>
               <tr><td>
                  <a href="#variables.nowplaying.currentsong.urlAmazon#"><img src="#variables.myBlogRootDir#/#myNowPlayingSubDir#/now_playing-#variables.nowplaying.currentsong.artworkid#.jpg"
                  border="0" width="80" height="80" align="left"
                  alt="Get #variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist# on Amazon"
                  title="Get #variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist# on Amazon">
</a>
               </td></tr>
            <!--- show amazon artwork and amazon link with associate id if present --->
            <cfelseif variables.nowplaying.currentsong.imageURL neq "">
               <tr><td>
                  <cfif variables.nowplaying.currentsong.urlAmazon neq "">
                     <a href="#variables.nowplaying.currentsong.urlAmazon#"><img src="#variables.nowplaying.currentsong.imageURL#"
                     border="0" width="80" height="80" align="left"
                     alt="Get #variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist# on Amazon"
                     title="Get #variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist# on Amazon">
</a>
                  <cfelse>
                     <img src="#variables.nowplaying.currentsong.imageURL#"
                     border="0" width="80" height="80" align="left"
                     alt="#variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist#"
                     title="#variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist#">

                  </cfif>
               </td></tr>
            <!--- show artwork if available; display at half size 80x80 instead of 160x160 --->
            <cfelseif fileexists("#variables.nowplaying.datadir#now_playing-#variables.nowplaying.currentsong.artworkid#.jpg")>
               <tr><td>
                  <cfif variables.nowplaying.currentsong.urlApple neq "">
                     <a href="#variables.nowplaying.currentsong.urlApple#"><img
                     src="#variables.myBlogRootDir#/#myNowPlayingSubDir#/now_playing-#variables.nowplaying.currentsong.artworkid#.jpg"
                     border="0" width="80" height="80" align="left"
                     alt="Get #variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist# on Apple's iTunes Music Store"
                     title="Get #variables.nowplaying.currentsong.album# by #variables.nowplaying.currentsong.artist# on Apple's iTunes Music Store">
</a>
                  <cfelse>
                     <img src="#variables.myBlogRootDir#/#myNowPlayingSubDir#/now_playing-#variables.nowplaying.currentsong.artworkid#.jpg"
                     border="0" width="80" height="80" align="left"
                     alt="#variables.nowplaying.currentsong.album#, #variables.nowplaying.currentsong.artist#"
                     title="#variables.nowplaying.currentsong.album#, #variables.nowplaying.currentsong.artist#">

                  </cfif>
               </td></tr>
            </cfif>
            <!---
            <cfif variables.nowplaying.currentsong.comments neq "">
            <tr><td>
               <p style="font-size:smaller;"><i>#variables.nowplaying.currentsong.comments#</i></p>
            </td></tr>
            </cfif>
            --->
      <cfcatch>
         oops!
         <!-- #cfcatch.message#, #cfcatch.detail#, -->
      </cfcatch>
      </cftry>
         <tr><td>
            <p><a href="http://brandon.fuller.name./archives/hacks/nowplaying/"><img src="#variables.myBlogRootDir#/includes/button_now_playing.gif" width="80" height="15" alt="now playing, a plug-in for itunes" title="now playing, a plug-in for itunes" border="0" align="left"></a></p>
          </td></tr>
      </table>
      <!-- Now_playing.cfm Pod for BlogCFC, Copyright (c) 2006 Steven Erat, (http://www.talkingtree.com/)
          released under a Creative Commons Attribution-NonCommercial-ShareAlike License -->
      <!-- Creative Commons License -->
      <!--
      <rdf:RDF xmlns="http://web.resource.org/cc/"
       xmlns:dc="http://purl.org/dc/elements/1.1/"
       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns##">

      <Work rdf:about="">
      <license rdf:resource="http://creativecommons.org/licenses/by-nc-sa/2.5/" />
      </Work>
      
      <License rdf:about="http://creativecommons.org/licenses/by-nc-sa/2.5/">
       <requires rdf:resource="http://web.resource.org/cc/Attribution" />
       <permits rdf:resource="http://web.resource.org/cc/Reproduction" />
      
       <permits rdf:resource="http://web.resource.org/cc/Distribution" />
       <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
       <requires rdf:resource="http://web.resource.org/cc/ShareAlike" />
       <prohibits rdf:resource="http://web.resource.org/cc/CommercialUse" />
       <requires rdf:resource="http://web.resource.org/cc/Notice" />
      </License>
      
      </rdf:RDF>
      -->
    </cfoutput>
</cfmodule>
<cfsetting enablecfoutputonly=false>

 


TalkingTree  Now Playing pod for BlogCFC - What's playing on your iTunes?

 

Recently envious of Matt Woodward's Now Playing on iTunes pod on his blog, a blog built with BlogFusion, I investigated what might be involved in producing an equivalent pod for BlogCFC software users.

I read the installation and usage guide for the Now Playing plug-in, available for a small charge from Brandon Fuller, and it seemed very easy to setup in iTunes. I logged into PayPal, bought a Now Playing license, and immediately received my key in the mail. The plug-in for Mac has few features than the one for Windows by the way. I think he will implement the Mac features in the not too distant future tho.

The plug-in will upload a small xml file called now_playing.xml to a specified directory on your FTP server where your ColdFusion server and blog reside. For each song played, the now_playing.xml file is uploaded with the metadata associated with the song currently playing. If the song has an artwork image associated with it, that image is also uploaded.

To display the song on my blog, I had to write a pod for BlogCFC that would not only parse the the now_playing.xml file to display info like the song name, artist, and album in the pod, but I also had to design a way for the pod to behave efficiently so as to minimize the number of times it reads the timestamp on now_playing.xml and parsing the file only if the pod detects that the file has been updated.

So you can see to the left that the Now Playing pod for BlogCFC is being used here. A few assumptions are made for efficiency, and they are configurable in the code. The pod assumes by default that it should only check for a new file after at least 3 minutes have passed since the last time it checked, which I estimate to be an average running time for a song. After 3 minutes it will check the timestamp for every page request until the now_playing.xml file has been updated or until the default max value of 60 minutes where the pod goes into a kind of sleep mode where it assumes that you have stopped playing iTunes. There's also a snooze feature that really kicks in after 60 minutes and will then wake up to check for a new file only once every 5 minutes by default, waiting for you to start iTunes again.

The pod usage is described in the comments, but all you have to do is save the pod cfm file to the {blog_root}/includes/pods/ directory and create a new directory {blog_root}/nowplaying/. Then configure your iTunes plugin to upload to {blog_root}/nowplaying/. The additional directory is recommended because if the song has artwork the image is also uploaded, so its better put all that in their own directory.

Please check it out and report and problems to me. So far I think I've ruled out any glaring problems, but you never know.

Download Now Playing Pod for BlogCFC

 


 

 

Calendar

 
Sun Mon Tue Wed Thu Fri Sat
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Search This Site

 
This is an exact search only

About This Site

 
I live west of Boston and work for Adobe with ColdFusion and Flex, and specialize in Linux. I'm also interested in travel and science, and I'm studyng photography at CDIA. Curious about my banner image?

More about me

Recent Entries

 
Smashing Copyright on Stunnin..
ColdFusion 8.01 64-bit and Su..
Bare Knuckle Boxer
Adobe's Angela Drury, Photogr..
Working with Models: A tough ..

Recent Comments

 
Posted By Mark Lynch:
I've just posted a solution for this problem for Ubuntu machines. [link] Cheers, Mark Lynch ...

Posted By Steven Erat:
Mostly like you DO NOT want to make CFIDE publicly available on internet websites, which was the whole point of th is blog entry. You DO want CFIDE a ...

Posted By Tanvir Gaus:
I have CFIDE in \wwwroot\ but my clients are virtual hosted like \wwwroot\abc.com or \wwwroot\xyz.com none is getting the CFIDE. Is there any way of p ...

recently played

 
Layout Tool Disguised as Aperture's Book Making Function
by Derrick Story
on FOO Casts: Podcasts from O'Reilly and Friends

now playing, a plug-in for itunes

Categories

 
RSS Adobe (28)
RSS Bicycling (9)
RSS Blogging (37)
RSS Books (13)
RSS Breeze (12)
RSS CFMX Podcasts (10)
RSS ColdFusion (416)
RSS Computer Technology (49)
RSS Events (25)
RSS Flash (3)
RSS Flex (17)
RSS Gadgets (10)
RSS HiTech Industry (15)
RSS Java (25)
RSS Learning (54)
RSS Linux (70)
RSS Mac OS X (21)
RSS Macromedia (28)
RSS Meetup (34)
RSS New England (58)
RSS Odds & Ends (25)
RSS Outdoors (32)
RSS Personal (26)
RSS Photography (103)
RSS Photoshop (28)
RSS Podcasts (18)
RSS Rants (18)
RSS Restaurants (8)
RSS Science (34)
RSS Spain (16)
RSS Travel (42)
RSS Video (20)
RSS Webcam (3)
RSS Writing (10)

Blogs I Read

 
Scrum Sucks
Ben Forta
Ray Camden
Kinky Solutions
Matt Woodward
Red Hat Blogs
O'Reilly Digital Media
O'Reilly Radar
John Nack
The Strobist
Scott Kelby
Matt Kloskowski
Stephen Shankland
Digital Photography School
Engadget
Science Blog
3rd House Journal

RSS

 


Add to Google
Add to My Yahoo!

Aggregated By

 


Consumed By Feed-Squirrel.com
Aggregated by ColdFusionBlogger.org

Credits and Stuff

 
BlogCFC - Free ColdFusion Powered Blog Software
CJM Group - ColdFusion Website Hosting


 
 
blog | photos | flickr | referers | webcam | stats | about | contact
 
Copyright © 2008 Steven Erat. All rights reserved.
This is a personal weblog. The opinions expressed here represent my own and not those of my employer