Record your favorite radio shows and generate a podcast with the episodes.

Podcast as shown by iTunes 7Ok, this is something that i had in mind since some time ago but i didn’t had the time to actually do it. But now i finished it.
The situation is like this, there is a radio show that i love, but the problem is that this radio show starts at 12 AM and finishes at 2 AM, and usually, I’m doing any other thing at that time in the night.
So, i decided to create some simple script to record the audio in one of my servers (by using the Radio station internet broadcast).

For all this to work, you will need the following things:

  1. PHP 5.1.6 or newer
  2. MPlayer
  3. the GPAC utilitles
  4. the Nero Digital AAC Encoder

The idea for the bash script to record the audio stream is based on a nice tutorial by Phil Salkie, but honestly, i think i improved it a lot, specially because it uses a FIFO as temporary storage, and because it compresses the audio to a more recent audio format like HE-AAC.

Basically, the following bash script will record any audio stream of your choice and will convert it to a HE-AAC file inside an m4a container compatible with any audio player out there AND iTunes / iPod of course ;)

After the audio file is done, the second script will generate a podcast feed (RSS) compatible with iTunes or any podcast client out there, like for example Juice.

Here is the script to capture the radio show and convert it to a M4A file (AAC Plus inside an MP4 container).

#!/bin/bash
TERM="linux"
# RANDOM GUID GENERATION
SUM=`date`
SUM2=`echo $SUM | md5sum | cut -c 1-8`

# INITIALIZATION VARIABLES
DATE=`date +%F`  # Save the date as YYYY-MM-DD
FILE=/home/plusmedia/public_html/media/$DATE---$SUM2.mp4  # WHERE TO SAVE THE STREAM ?
STREAM=mms://200.43.193.143/radio10  # The URL of the stream to save.
FIFO=/tmp/stream.wav  # We create a FIFO as intermediate storage for the encoding.
ARTWORK=/home/plusmedia/public_html/lvst.jpg  # Path to some artwork file for iTunes, can be JPG or PNG.
DURATION=122m # How many minutes should we record ?

# MP4 TAGS
AUTHOR="Some Author"
ALBUM="Some Radio Show"
TITLE="Some Radio Program - $DATE" 

# We use mplayer to capture the stream to a wav file being stored into a FIFO.
mkfifo $FIFO
/usr/bin/mplayer $STREAM -af resample=44100:0:2,volume=0:1,pan=1:0.5:0.5,comp -ao pcm:file="$FIFO" -vo null -vc dummy < /dev/null 2>&1 >/dev/null & pA=$!

# Encoding the fifo to AAC with the Nero Digital Encoder for Linux.
/usr/bin/neroAacEnc -br 24000 -he -if $FIFO -of $FILE & pB=$!

sleep $DURATION  # wait for the show to be over

kill $pA # end the mplayer process
sleep 2s # IMPORTANT! wait a while for the Nero encoder to finish and close the opened files.

echo "CREATING M4A AND APPLYING TAGS..."
/usr/bin/MP4Box -add "$FILE#audio" -itags cover="$ARTWORK":artist="$AUTHOR":comment="$DATE":album_artist="$AUTHOR" -lang english -new "${FILE%.*}.m4a"
sleep 1s
echo "Generating Podcast Item..."
# We have a new episode recorded, so it is time to call the podcast generation script to update the RSS feed.
/home/plusmedia/podcast

echo "Deleting FIFO and temporary files..."
rm $FIFO -f
rm $FILE -f

echo "done!"

And this is the PHP script to generate the “iTunes Compliant” podcast feed:

#!/usr/bin/php
setIndent = true;
    $xmlObject->openMemory();
    $xmlObject->startDocument('1.0','UTF-8');
    $xmlObject->startElement ('rss'); //
    $xmlObject->writeAttribute( 'xmlns:itunes', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
    $xmlObject->writeAttribute( 'version', '2.0');
	$xmlObject->startElement ('channel');
	$xmlObject->writeElement ('title', $title);
	$xmlObject->writeElement ('link', $link);
	$xmlObject->writeElement ('language', $language);
	$xmlObject->writeElement ('copyright', $copyright);
	$xmlObject->writeElement ('itunes:subtitle', $itunesSubtitle);
	$xmlObject->writeElement ('itunes:author', $itunesAuthor);
	$xmlObject->writeElement ('itunes:summary', $itunesSummary);
	$xmlObject->writeElement ('itunes:explicit', $itunesExplicit);
	$xmlObject->writeElement ('description', $description);
		$xmlObject->startElement ('itunes:owner');
		$xmlObject->writeElement ('itunes:name', $ownerName);
		$xmlObject->writeElement ('itunes:email', $ownerEmail);
		$xmlObject->endElement();
	$xmlObject->startElement ('itunes:image');
		$xmlObject->writeAttribute ('href', $baseURL.$image);
	$xmlObject->endElement();
		$xmlObject->startElement ('itunes:category');
		$xmlObject->writeAttribute ('text', $mainCategory);
			$xmlObject->startElement ('itunes:category');
			$xmlObject->writeAttribute ('text', $childCategory);
			$xmlObject->endElement();
		$xmlObject->endElement();
// 	ITEMS
	$files = scandir($mediaDIR);
	$sortedFiles = array();
	foreach ($files as $filePath) {
		$fileItem = array( 	'modified'  => filemtime($mediaDIR.$filePath),
							'path'		=> $filePath
		            	 );
		array_push ($sortedFiles, $fileItem);
	}
	usort($sortedFiles, "cmp");
	foreach ($sortedFiles as $value) {
		$extension = substr($value['path'], strrpos($value['path'], "."));
		if ($extension == $fileExtension) {
			$nameParts = explode("---", parseFileName($value['path']));
			$xmlObject->startElement ('item');
			$dateComponent = strtotime($nameParts[0]);
			$xmlObject->writeElement ('title', $itemTitle.strftime('%A, %B %d, %Y', $dateComponent));
			$xmlObject->writeElement ('itunes:author', $itunesAuthor);
			$xmlObject->writeElement ('itunes:subtitle', $itunesSubtitle);
			$xmlObject->writeElement ('itunes:image', $baseURL.$image);
			$xmlObject->writeElement ('pubDate', date('r', $dateComponent));
			$xmlObject->startElement ('enclosure');
				$xmlObject->writeAttribute( 'url', $baseURL.$mediaURL.$value['path']);
				$xmlObject->writeAttribute( 'length', filesize($mediaDIR.$value['path']));
				$xmlObject->writeAttribute( 'type', 'audio/x-m4a');
			$xmlObject->endElement(); //
			$xmlObject->writeElement ('guid', $baseURL.$mediaURL.$value['path']);
			$xmlObject->endElement(); //
		}
	}
	$xmlObject->endElement(); //
    $xmlObject->endElement(); // 

// 	Write XML data to file...
    writeXmlFile($xmlObject->outputMemory(true), $XML);    

function writeXmlFile($contents, $file) {
	$fh = fopen($file, 'w') or die("can't open file");
	fwrite($fh, $contents);
}

function parseFileName($fileName) {
	$input = explode(".",$fileName);
	$noExt = $input[0];
	return $noExt;
}

// Custom array ordering function for usort
// orders by REVERSE order (Biggest timestamp goes FIRST).
function cmp($a, $b)
{
    return strcmp($b["modified"], $a["modified"]);
}
?>

The PHP script will scan a given directory for files with the extension “m4a” (or any other extension configured in the $fileExtension variable), it will order the files by their created date (in reverse order) and will generate a file called “podcast.xml” that you can access with iTunes on mac or PC, or you could use any other podcast client like Juice.

You should for example call the bash script “recorder” and call the php script “podcast”, then chmod +x both files to make them executables, and then just run the bash script by typing:

./recorder

Obviously, the idea behind all this is that you should create a crontab entry to run the process automatically, in my case, it runs everyday at 12:00 AM and i did set the duration variable to 121 minutes (2 hours and a bit).
All the rest should be smooth and automatic if you configured correctly the initialization variables in both scripts.


4 Responses to “Record your favorite radio shows and generate a podcast with the episodes.”

  1. Nice, but I would have expected at least a link to my original post with the same idea 2 years ago: http://www.schwindt.org/blog/archives/18

    by Juan Schwindt, October 13th, 2007 at 12:44 am


  2. Hey Juan, i didn’t know that you had publicly available scripts and instructions for download at your blog….
    Point me to the scripts and instructions page and i will add the link without a problem.
    Also, i see that you are saying too at your blog, that your idea was based on the same Linux Journal article that i am linking at this post, so i don’t really understand your claims…
    I guess that I just took the original idea being by Phil from LJ and not yours.

    by Diego Massanti, October 13th, 2007 at 1:02 am


  3. Hi, i just wanted to know, how would I go about using these scripts on a hosted Linux web server? For example i want to automate a recording from station then make it be stored in a specific folder, to be listen to by viewers on the site at a later date. I am assuming i can install mplayer and the other parts into the directory on the webserver and beging from there and run a cron job from there etc..

    it would be really helpful if you could help, thanks!!

    by Orlando, July 14th, 2008 at 7:48 pm


  4. eh ne diyelim i

    by mydonose, October 5th, 2008 at 6:47 pm