Wednesday, October 15, 2008

mp3Manager.cfc for updating ID3 tags with coldfusion

I needed to modify MP3 ID3 tags on our server with Coldfusion. To do so I downloaded three different Java mp3 libraries. One did not work at all, the other two would read the ID3 tags but not update the data.

Frustrated, I went on the prowl again for another library and I found MyID3: a Java ID3 Tag Library. You will also need to download the Jakarta Regexp and Nanoxml jars as well.

Thank you Charles M. Chen for a library that's simple, well documented and works!

Also, thanks to Ray Camden for posting "Reading MP3 ID3 tags with ColdFusion" on his Coldfusion Jedi blog. That gave me a great head start.

Here's how you might use the component...

<!--- Read the ID3 comments field --->
<cfset mp3Manager = createObject("component",'components.managers.mp3Manager') />
<cfset mp3Manager.init(mp3FilePath) />
<cfset comment = mp3Manager.getComment() />

<!--- Update the ID3 comments field --->
<cfset mp3Manager = createObject("component",'components.managers.mp3Manager') />
<cfset mp3Manager.init(mp3FilePath) />
<cfset mp3Manager.setComment(strComments) />

And here is a simple version of the CFC. I hope you find it helpful.

<cfcomponent displayname="mp3Manager" output="false">  

   <!--- ============================================== --->
   <cfset variables.fileObj = "">
   <cfset variables.filename = "">
   <cfset variables.metadata = "">
   <cfset variables.metadataset = "">
   <cfset variables.id3 = "">   

   <!--- ============================================== --->
   <cffunction name="init" access="public" returnType="mp3Manager" output="false">
      <cfargument name="filename" type="string" required="false">

      <cfif structKeyExists(arguments, "filename")>
          <cfset variables.id3 = createObject("java", "org.cmc.music.myid3.MyID3") />
          <cfset variables.metadata = createObject("java", "org.cmc.music.metadata.MusicMetadata") />
          <cfset variables.metadataset = createObject("java", "org.cmc.music.metadata.MusicMetadataSet") />
          <cfset read(filename) />
      </cfif>

        <cfreturn this>
   </cffunction>

   <!--- ============================================== --->
   <cffunction name="read" access="public" returnType="void" output="false">
      <cfargument name="filename" type="string" required="true">

      <cfif not fileExists(arguments.fileName)>
         <cfthrow message="#arguments.fileName# does not exist.">
      </cfif>

      <cfset variables.filename = arguments.filename>

      <cftry>
         <cfset variables.fileObj = createObject("java","java.io.File").init(expandPath(variables.filename)) />
         <cfset variables.id3.init() />
         <cfset variables.metadataset = variables.id3.read(variables.fileObj) />
         <cfset variables.metadata = variables.metadataset.getSimplified() />
         <cfcatch>
            <cfthrow message="Invalid MP3 file: #arguments.filename# #cfcatch.message#">
         </cfcatch>
      </cftry>
   </cffunction>

   <!--- ============================================== --->
   <cffunction name="getComment" access="public" returnType="string" output="false">
      <cfreturn trim(variables.metadata.getComment())>
   </cffunction>

   <!--- ============================================== --->
   <cffunction name="setComment" access="public" returnType="void" output="false">
      <cfargument name="argComment" type="string" required="false">
      <cfset variables.metadata.setComment(argComment) />
      <cfset variables.id3.update(variables.fileObj, variables.metadataset, variables.metadata) />
   </cffunction>

   <!--- ============================================== --->
</cfcomponent>