Podcast::Publisher - Module for creating and managing podcasts


     use Podcast::Publisher;
     my $podcast = Podcast::Publisher->new;
     $podcast->set_logger( sub { my $msg = shift; print $msg; } );
     $podcast->set_error_logger( sub { my $msg = shift; print STDERR $msg; } );
     my $xml = "./podcast.xml";
     $podcast->set_file( $xml );
     $podcast->set_remote_root( "http://localhost.localdomain/podcast/publishing/" );
     $podcast->set_db_connection( { 'driver' => "mysql", 
                                    'username' => 'foo',
                                    'password' => 'bar',
                                    'host' => 'localhost',
                                    'database' => 'podcast' } );
     # If we change podcast information, synchronize this information in the MP3 file itself
     $podcast->set_synchronize( 1 );
     $podcast->set_metadata( { 'title' => "Chris' Podcast",
                              'description' => "All About Chris",
                              "docs" => "http://localhost",
                              "editor" => "podcastmanager\@localhost",
                              "webmaster" => "podcastmanager\@localhost",
                          } );
     # This adds an item to the database, and synchronizes the 
     # MP3 Tag information in the file with the database
     $podcast->add_new_episode( { 'title' => 'Some title',
                                  'author' => 'Chris of course'
                                  'category' => 'Jazz'
                                  'description' => 'First in a series of many'
                                  'mp3' => '/home/foobar/mp3s/episode1.mp3' } );
     $podcast->set_upload_settings( { 'host' => 'localhost.localdomain',
                                      'username' => 'someuser',
                                      'password' => 'somepass',
                                      'path' => 'podcast/publishing/',
                                      'remote_root' => 'http://localhost.localdomain/podcast/publishing/' } );


Chris Dawson, chris aT webcastinabox d0t c0m


(c) Webcast in a Box, Inc 2005

This library is free software; you can redistribute it and or modify it under the same terms as Perl itself.


Podcast::Publisher is an object oriented library which can dynamically construct podcast xml feeds with item metadata tagging, enclosure byte length calculations, automatic and transparent MP3 tag information synchronization, intelligent file upload management, and process logging. This library is also available at

This library requires a database (currently supports MySQL, probably postgres as well).


Some metadata is not stored properly in the MP3 file if you use synchronization, but this will be fixed very soon.



$podcast = Podcast::Publisher->new();

Creates a podcast object.



Uploads all files to the proper location. Each episode MP3 file is uploaded. The upload() method intelligently uploads files based on an MD5 digest hash of the file. If it is the first time the file has been uploaded, the file is uploaded, and a MD5 digest hash file is uploaded alongside it. The next time, the digest hash is generated again, and compared against the file on the server. If the digest hash changes (if the MP3 file changes size, or the metadata changes) then the file is uploaded again. If the file has not changed, then the upload is skipped. Finally the podcast.xml file is uploaded.

enable_cleanup( ... )

$podcast->enable_cleanup( { ... } );

This method allow you to tell the publisher to delete files on the remote server which are no longer in the podcast. If called with no parameters, it deletes all files on the remote server which are not in the podcast RSS file. If someone who recently grabbed your podcast RSS is downloading an MP3 from a podcast file which you just updated, this could cause strange errors. To remedy this you can provide a hashref with the 'expires' parameter to indicate how many seconds out of date a file can be before deletion. So, if you call enable_cleanup() like this:

    $podcast->enable_cleanup( { 'expires' => 7 * 24 * 60 * 60 } );

you'll delete files which are not stored in the podcast RSS, and are older than a week. While this doesn't guarantee that you didn't just modify a podcast RSS, it gives you a little more leeway. This is generally a convenience method which prevents your FTP server from getting filled with lots of files; if you feel confident doing the cleanup by hand, the results will probably be better.

Caveat: Don't call this function if you store anything else in the FTP directory where the podcast and associated MP3 files are stored. The module tries to be careful about deleting what it knows about, but this is an asynchronous process.



Disables cleanup of files. See enable_cleanup().


$podcast->set_upload_settings( { ... } );

Creates a new FTP object which is used to upload RSS and MP3 files. This method accepts a hashref with the following keys: host, username, password, path


$podcast->set_timezone( 'PST' )

Set the timezone. This is used when generating timestamps for the podcast RSS file. Thurs 2005/06/23 12:34:56 GMT, for example. GMT is used if this is unset.



Retrieve all the episodes as a bunch of hashrefs. If you want to iterate over each of the items and retrieve data you can do so with this method.

# This prints the title of the first episode, print $podcast->get_episodes()->[ 0 ]->{ 'title' };


$podcast->set_episode_upload_metadata( index, metadata );

This sets the first episode to upload to with username/password "username" and "password" and put the files into "mypodcast/directory/path"

$podcast->set_episode_upload_metadata( 0, { 'protocol' => 'ftp', 'host' => '', 'username' => 'username', 'password' => 'password', 'path' => 'mypodcast/directory/path' } );

    $podcast->delete_episode( 1 );

This method deletes the episode from the podcast, and updates the RSS. You provide the episode ID.

    $podcast->hide_episode( 1 );

This method hides the episode from view, removing it from the podcast RSS. It does not delete it from the database.

    $podcast->unhide_episode( 1 );

The opposite of hide_episode; adds the episode to the RSS.


Returns metadata about the podcast feed as a hashref

    $podcast->set_profile( "./main.xml" );

Profiles can be used to store metadata for retrieval later. First, call set_profile with a filename, and then call set_metadata with metadata. The next time you can simply call set_profile to retrieve those settings.

    $podcast->set_metadata( { ... } );

Sets metadata, and writes it to a configuration file for later retrieval. If you have not first called set_profile(), a default profile is used.

Use the following keys: title, description, language, docs, editor, webmaster, generator. pubDate and lastBuildDate are optional; if you leave them out you'll get the date right now. This metadata is placed in the header of the RSS file.


Write out the RSS file. You should call set_file() first to establish an RSS filename.

    $podcast->set_file( $file );

Sets the filename to use when writing the RSS file.


$podcast->set_db_connection( { .. } )

Set the database settings. You should provide these keys: dsn, username, password The dsn will be one of the standard DBD::* drivers, like mysql and the appropriate connection information.

Examples: DBI:mysql:podcast=;host=localhost

    $podcast->add_new_episode( { .. } );

Adds a new episode to the podcast RSS feed, and optionally updates metadata in the associated file to synchronize with the database information, if the synchronize flag is set. Use the following keys in the hashref provided: title, author, category, pubDate, description, mp3

    $arrayref= $podcast->get_titles();

Convenience method to get all titles as an array ref.

    $podcast->update_episode( { .. } );

Updates episode data. Provide the same hash ref as in add_new_episode but you must also provide a value for the key 'id' which is the numeric key to the episode to edit.

    $podcast->set_remote_root( "" );

Set the remote root for the podcasts RSS. Items which are uploaded will be references with this URL as the base.

    $podcast->set_local_root( "/home/foobar/podcasts/episodes" );

Set this if you provide only relative pathnames to your episode MP3 files and not the fully specified paths. If you do this, all MP3s should be in the same directory.

    $podcast->set_maximum_episodes( 20 );

By default the RSS generated will use the last 15 episodes. If you wish to use more or less than this, set the value here.


    Synchronize changes to the MP3 with changes to the database

3 POD Errors

The following errors were encountered while parsing the POD:

Around line 69:

You forgot a '=back' before '=head1'

Around line 93:

You forgot a '=back' before '=head1'

Around line 100:

'=item' outside of any '=over'

=over without closing =back