This is a little tutorial how to set up a podcast for external mp3-files on your Drupal site. Drupal currently creates appropriate <enclosure/> elements for mp3's hosted within Drupal, but what if you want to store you mp3's on a different server?

Services used in this tutorial

  • Drupal 4.6
  • Ourmedia for hosting mp3-files (You can of course use whatever server you want to host your files, Ourmedia is just an example of an excellent free service for this, and they're using Drupal!)
  • Feedburner for doing the last magic

What you will achieve after struggling through the text below

http://feeds.feedburner.com/drupal-podcast

1. The mp3 file

As said I'm using Ourmedia to host my mp3's. For the purpose of this tutorial I've uploaded a small file called stop.mp3 on my free account. The address to that file is http://archive.org/download/stop.mp3/stop.mp3.

2. Drupal

First create a term for this podcast (you'll understand why later). This is done under administer/categories. If you don't have a vocabulary already, choose "add vocabulary", and give it a name ("categories" will do). Then create a term and give it a proper name (I simply named it "podcast").

Ok, now it's time to create the entry! You can use whatever content type you want, but I suggest you use a blog entry. Give it a title and then select the term we created earlier, in my case "podcast".

In the body we put a link to our mp3-file. You can also write some text here, but the important part is the <a> tag. This is the HTML for my body:

Check out this <a href="http://archive.org/download/stop.mp3/stop.mp3">first podcast</a>

Now submit the blog entry.

Drupal has the nice feature that it creates a feed for every term, this will come in handy now! You should be able to click on the term "podcast" and then get a list of every entry submitted with that term (in my case only one entry is posted yet). At the bottom of the page you have an orange XML-button which links to the feed of this term. Click on it and notice the URL in the address bar (something like http://www.example.com/taxonomy/term/1/0/feed). Actually you can write this address down as we will use it in the last and final step of this tutorial.

3. Using Feedburner to create the podcast

Ok, now we have a feed with a link to our mp3 in Drupal. But what we really want is that magic </enclosure> element, how on earth can we fix that?? Luckily for us, there is a free and excellent service (again!!) called Feedburner. Point your feeds there and you will have all sorts of cool stuff like statistics and browser-friendly feeds. What it also does is that it creates </enclosure> elements out of links to mp3's, handy!

Create a feedburner account and log in. Then write the URL to the podcast feed we created in Drupal (something like http://www.example.com/taxonomy/term/1/0/feed) in the address field on Feedburner. Then hit "Next". If everything went fine you now are prompted with a page with "QuickFeed Services" options. Scroll down and select SmartCast. I've also selected Browser-Friendly Burner and Item Stats, but that's optional. Now save the settings.

On "View XML..." you have your final podcast, isn't that cool??!

Now you can promote this Feedburner URL on your Drupal homepage (our use the aggregator module to import it back to Drupal -isn't that ironic...)

Note: Currently Drupal doesn't support <enclosure> elements for external mp3's, but I'm sure it will in some way in the future. Using Drupal together with Feedburner is a good way of having this future available today.

Comments

tendencies’s picture

> Note: Currently Drupal doesn't support elements for external mp3's, but I'm sure it will in some way in the future.

I propose my hack to have this feature with an external mp3.

Edit includes/common.inc and search the function format_rss_item()

...
$output .= ' <link>'. check_url($link) ."</link>\n";
  preg_match_all("|href\=\"?'?`?([[:alnum:]%:?=&@/._-]+\.mp3)\"?'?`?|i", $description, &$matches);
  foreach ($matches[1] as $key => $value) {
       $output .= ' <enclosure url="'.$value.'" type="audio/mpeg"/>\n';
  }
  $output .= ' <description>'. check_plain($description) ."</description>\n";
...
Ian Ward’s picture

I was trying this out and noticed the length parameter is missing in the enclosure element, so the feed does not validate. The length is actually just the file size, so here's what I did to get the file size from the remote file:

I first added this small function to common.inc, credits to http://www.php.net/manual/en/function.filesize.php#54358

 function filesize_url($url){
   return ($data = @file_get_contents($url)) ? strlen($data) : false;
} 

And then i added this $length variable to the addition to common.inc from tendencies:

 $output .= ' <link>'. check_url($link) ."</link>\n";
  preg_match_all("|href\=\"?'?`?([[:alnum:]%:?=&@/._-]+\.mp3)\"?'?`?|i", $description, &$matches);
  foreach ($matches[1] as $key => $value) {
       $length = filesize_url($value);
       $output .= ' <enclosure url="'.$value.'" length="'.$length.'" type="audio/mpeg" />';
  }
  $output .= ' <description>'. check_plain($description) ."</description>\n"; 

and now it validates.

Ian

forresto’s picture

Your filesize_url() was not working for me, possibly because archive.org (thus ourmedia.org) uses redirects for mp3. For example, http://www.archive.org/download/Holler/DarkHoller.mp3 redirects to http://ia300137.us.archive.org/3/items/Holler/DarkHoller.mp3

Is it valid to just say length="-1" or something along those lines?

ezra-g’s picture

I'll be your newbie for this discussion:
Where should this code be added to common.inc?I appended it at the end of common.inc and recieve

Fatal error: Call to undefined function: filter_xss_bad_protocol() in ...includes/common.inc on line 694

Any suggestions?

Thanks.

Ezra Barnett Gildesgame

kus’s picture

some enhancement for videos.


  preg_match_all("|href\=\"?'?`?([[:alnum:]%:?=&@/._-]+\.mp3)\"?'?`?|i", $description, &$matches);
  foreach ($matches[1] as $key => $value) {
      $output .= ' <enclosure url="'.$value.'" type="audio/mpeg"/>';
  }

  preg_match_all("|href\=\"?'?`?([[:alnum:]%:?=&@/._-]+\.mov)\"?'?`?|i", $description, &$matches);
  foreach ($matches[1] as $key => $value) {
      $output .= ' <enclosure url="'.$value.'" type="video/quicktime"/>';
  }

  preg_match_all("|href\=\"?'?`?([[:alnum:]%:?=&@/._-]+\.wmv)\"?'?`?|i", $description, &$matches);
  foreach ($matches[1] as $key => $value) {
      $output .= ' <enclosure url="'.$value.'" type="video/x-ms-wmv"/>';
  }
  
  preg_match_all("|href\=\"?'?`?([[:alnum:]%:?=&@/._-]+\.mpg)\"?'?`?|i", $description, &$matches);
  foreach ($matches[1] as $key => $value) {
    $output .= ' <enclosure url="'.$value.'" type="video/mpeg"/>';
  }

  
acochran’s picture

Probably not as we can see that Drupal is removing features with each release.

WorldFallz’s picture

...Drupal is removing features with each release

lolol, not even remotely...

===
"Give a man a fish and you feed him for a day.
Teach a man to fish and you feed him for a lifetime."
-- Lao Tzu
"God helps those who help themselves." -- Benjamin Franklin
"Search is your best friend." -- Worldfallz

mbacas’s picture

Why not just link to the OurMedia feed? Why go through all the trouble of creating a new setup?

- Mark

kus’s picture

cause i have a lot of feeds running...

qblack1’s picture

Thanks for the excellent post. Just a small question...

You said:
Ok, now it's time to create the entry! You can use whatever content type you want, but I suggest you use a blog entry. Give it a title and then select the term we created earlier, in my case "podcast".

You say "select the term"

I can create the term under the category "category", my term is "podcast". That works fine.

Now creating a blog entry, no problem.

But I don't see where I can select the categorization/term...

I have the taxonomy module running. Is there another one needed? Or am I just missing something right in front of me.

thanks

budda’s picture

You need to associate the taxonomy vocabulary "categories" with a node-type. In your case 'blog'.

--
Drupal consultancy

qblack1’s picture

You imply in your post that Drupal doe support enclosure elements for internal mp3s.

Is this true?

I have a podcast mp3 on my side in "files/xxxxxx.mp3". How would I go about using that without going through the procees you outline for external mp3s?

Thanks

Shane Birley’s picture

From what I have read, 4.6 has enclosures. If you are wanting to host the MP3 files yourself (or video files for that matter) - all you need to do is attach using the upload feature in Drupal to your blog entry, story entry, etc.

Drupal then creates the enclosures for it.

The reason for external MP3 and video file hosting is because many web hosts do not allow for much drive space.

-
Shane Birley
Vicious Bunny Creative
http://www.vbcreative.com

---
Shane Birley
Left Right Minds
https://www.leftrightminds.com

rimshot’s picture

This is the best advise I've heard all day. Why mess around with all those other modules when if a simple rss feed most people need for their mp3's will do just fine. Thanks Shane for the clear explanination. Saved me a bunch of time monkeying around.

rickvug’s picture

What about if you want to have two files attached to one message? Better yet, what if you want to attach both an audio and video of the same content to a single post while letting users choose between subscribing to just the audio or just the video?

Just asking out loud, as I have a feeling that I will run into this issue in the future. Anyone else have to solve a similar problem?

Rick

-------------------------------------------------------------------
Rick Vugteveen |rickvug.com @rickvug on Twitter

Shane Birley’s picture

...but RSS 2.0 only support a single enclosure (which is why the first file is the one enclosed). You could have multi-attachments, but RSS simply doesn't have more than on. This is by design. I am sure the spec will eventually change.

---
Shane Birley
Vicious Bunny Creative
http://www.vbcreative.com

---
Shane Birley
Left Right Minds
https://www.leftrightminds.com

rickvug’s picture

I was actually suspicious that this was the case. Thinking about this further, the functionality that would be a solution to this problem is one of the following:

1) Having the extra attachment create a new RSS feed
2) Have the ability for two nodes to share comments amongst each-other.

In the end, all I need is for users to be able to have the option to choose to subscribe to the audio or video version of the same content (In this case a weekly sermon). This is easily possible but brings with it the issue of keeping the discussion centralized in one thread for each week. An easy "solution" would be to have one node not allow comments and instead point to the other, but this is a bit of a work around hack.

-------------------------------------------------------------------
Rick Vugteveen |rickvug.com @rickvug on Twitter

Shane Birley’s picture

One thing to consider is to have two different RSS streams, one for audio, and one for video. It would require two posts, but might be a better way to organize the information without hacking anything. It might be the simpler for everyone - besides, you may only have one or the other some weeks (ie: video camera fails, tape fails, or audio recording fails).

It really depends on how many techy people are involved with the web site. If there are nerds available, great - if not, then having two posts might be the easy way around.

---
Shane Birley
Vicious Bunny Creative
http://www.vbcreative.com

---
Shane Birley
Left Right Minds
https://www.leftrightminds.com

rickvug’s picture

It may not be the best solution technically but it will work. Maybe I would keep comments closed on the audio and point them over to the video thread if they want to talk about the message.

Thanks for taking the time to reply.

-------------------------------------------------------------------
Rick Vugteveen |rickvug.com @rickvug on Twitter

tunesmith’s picture

I have this problem with my setup too. It's actually a larger problem. I want to post my files, and have a regular old blog entry about them with a lot of text, complete with having comments enabled. But I also want it to be part of a podcast, and not deal with feedburner trying to package up all the text from the entry into the podcast feed.

I'm not sure how to accomplish this yet, so my best idea so far is to have a dummy podcast feed that feedburner builds from, but then have an entirely separate blog.

So, the process for you would be:
a) Create a podcast audio category that you post the audio file too - no text beyond what you want to be in the podcast feed, and disable comments. Create feedburner podcast feed from this. Keep it hidden on your drupal site (other than its direct url); meaning don't promote it to the front page.
b) Create a podcast video category the same way.
c) Then just create a blog entry that points to both files, that has discussion enabled. This is promoted to the front page.

As for the podcast feed, I think iTunes podcast feeds just redirect users to one page for the entire podcast, not individual entry pages, so I don't think you're missing much there...? But if people can go do an entry page for a particular podcast episode, then this is a flaw I don't see a solution for. would love to hear how other people would solve this.

ewlloyd’s picture

Hi,

Your article (and some of the comments that followed) inspired me to take this one step further -- RSS Remote Enclosure. It takes the URL of your remote media file and text for the link, and generates a proper <enclosure> tag in the feed. It can also add links to the feed text and the links bar below the node body (per Administrator perogative).

Just imagine! No fiddling with FeedBurner (although they do bring some value-adds to the table)! No more training newbies how to create an <a> tag! And no complicating your upgrade path by hacking Drupal core!

Check it out -- if you're running a podcast, you'll be glad you did!