Transform an OpenLearn unit into a podcast to learn on the move

The OpenLearn project offers a lot of courses that you can take for free, or even remix. When you have the time to sit in front of your computer this is great, but what about those other times you can't spend time looking at your computer, but the opportunity to learn might brighten up your day? These times might include occasions such as a long car journey, when you are off jogging or waiting at a bus stop. Well these can be learning times too, all we need to do is to shift the format of the material from something you need to look at to something you can listen to. If you follow my personal blog, you may have seen a post entitled: “Extreme mashup: Turning a text RSS feed into a radio station”, here we will use some of those same ideas to turn our OpenLearn unit into a podcast.

You don't need any expensive tools to produce a podcast from an OpenLearn unit, here we will use open source packages to grab the RSS feed of an OpenLearn unit and turn it into a spoken file. A small script will be used to process the feed which will be passed though a speech synthesiser. It will output MP3 files which can be used on a wide variety of personal audio players. I've used Espeak as the text to speech program, this is available for Ubuntu & Debian (just install the espeak package) and also Windows and Mac (grab the download from the Espeak website: http://espeak.sourceforge.net/) .

An interesting aspect of the Espeak software is the ability to make it speak in different accents, in fact you can alter many attributes about how the file will be read out. Already many people are used to changing how a computer speaks to them by doing things like changing the voice on their SatNav, and now you can do this with a learning podcast! At the top of the script I have a couple of define() statements, one for the words per minute spoken (you might want to change this according to preference) and the second for the accent used (to see available options run espeak --voices from the command line). There are also other options available – consult the Espeak documentation for details.

A small PHP script handles the process of converting the RSS to speech. The script has been adapted from my original blog post a little to make it better tuned for spoken educational material. I've added in a track number, to keep the units in order, the album name is set to the unit name and the 'artist' has been set as 'OpenLearn'. It works by converting each RSS item into an SSML, a special markup describing spoken documents. As an interesting aside I noticed that if you play the resulting files in Mozilla Songbird you will also see a few OpenLearn related pictures, videos and blog posts thanks to the rather wonderful mashTape plugin.

The last piece of the jigsaw is turning the output of Espeak (an uncompressed WAV file) into an MP3 file that we could use in an audio player. Here I am using a project called LAME which has been ported to various platforms (Ubuntu & Debian install the lame package, other platforms see http://lame.sourceforge.net/links.php#Binaries). You could easily use something else in place of LAME, for example you might want a different output format such as OGG.

Rather than write my own code to process the RSS feed, I've used the excellent SimplePie library (http://simplepie.org/) which takes all of the hard work of processing feeds away. To use the script you will need to download the SimplePie library and put it in the same directory as your script. You will also need to ensure that Espeak and LAME are installed and reachable from the command line. Also, make a new directory called “output”, this will hold the finished MP3 files.

 

The RSS icon by an OpenLearn unitWhen running the script, pass it the URL of the RSS feed for the OpenLearn course that you are interested in. You can get this by going to the page listing the courses (e.g. http://openlearn.open.ac.uk/course/category.php?id=5&perpage=15&page=1) and clicking on the RSS logo under a course name. To run the script your command might look like this (on Windows enter php ol2podcast.php ...):

./ol2podcast.php http://openlearn.open.ac.uk/rss/file.php/stdfeed/3636/formats/OER_1_rss.xml

It will take a few minutes to generate all of the MP3 files. While the script is being run you may notice some temporary files being made, one of these is the WAVfile produced by Espeak, the other is the SSML file that the RSS feed item is converted into. This is the file that is read out by Espeak. Once completed you can transfer the MP3 files to a portable audio player and learn on the move!

The text of the script is below, and a sample of the MP3 files generated is attached.

 

#!/usr/bin/env php
<?php
/**
 * Convert an OpenLearn RSS Feed into a spoken audio file
 * By Liam Green-Hughes
 */
require 'simplepie_1.2/simplepie.inc';

define('WORDS_PER_MINUTE', 140); // rate text will be spoken
define('VOICE', 'en-uk-rp');  // Espeak voice to use, run "espeak --voices" for a list
 
// print out a help message if needed
if (sizeof($argv) == 1 || $argv[0] == '--help') {
  echo "Usage ".$argv[0]." RSS_URL\n";
  echo "\tRSS_URL\tThe feed address of the OpenLearn unit as it would be typed in a browser.\n";
  exit();
}

$url = $argv[1];
// Parse the RSS document with SimplePie
$feed = new SimplePie();
$feed->set_feed_url($url);
$feed->init();
$unit_title = str_replace('RSS Feed for the unit ','', $feed->get_title());
 
// loop through items
foreach($feed->get_items() as $tracknumber =>  $item)
{ 
  echo "Processing: ".$item->get_title()."\n";
  // build the file name "author - title"
  
  $filename = sprintf('output/%s - %02d - %s',
    preg_replace("/[^a-zA-Z0-9\s]/", "", $unit_title),
    $tracknumber+1,
    preg_replace("/[^a-zA-Z0-9\s]/", "", $item->get_title()));
  // output an SSML document
  $fp = fopen($filename.".ssml", 'w');
  fwrite($fp, "<?xml version='1.0'?>\n");
  fwrite($fp, "<speak xmlns='http://www.w3.org/2001/10/synthesis'\n");
  fwrite($fp, "       xmlns:dc='http://purl.org/dc/elements/1.1/'\n");
  fwrite($fp, "       version='1.0'>\n");
  // title
  fwrite($fp, "  <metadata>\n<dc:title xml:lang='en'>");
  fwrite($fp, $item->get_title()."</dc:title>\n</metadata>\n");
  // content
  // keep only p, em, b and i tags
  $content = strip_tags($item->get_content(),'<p><em><b><i>');
  // map the em, b, and i tags to SSML <emphasis> tag
  $content = str_replace(array('<em>','<b>', '<i>'), '<emphasis>', $content);
  $content = str_replace(array('</em>','</b>', '</i>'), '</emphasis>', $content);
  fwrite($fp, $content."\n");
  // end the document
  fwrite($fp, "</speak>\n");
  fclose($fp);
  // now generate an audio file with espeak
  shell_exec(sprintf('espeak -v %s -s %d -m -f "%s.ssml" -w "%s.wav"', VOICE, WORDS_PER_MINUTE, $filename, $filename));
  // convert to MP3 with lame
  shell_exec(sprintf('lame --tt "%s" --tl "%s" --tn %d --ta "%s" "%s.wav" "%s.mp3"', $item->get_title(), $unit_title, $tracknumber+1, "OpenLearn",  $filename, $filename));
  // delete the wav and ssml files as they are now not needed
  unlink($filename.'.wav');
  unlink($filename.'.ssml');
}
AttachmentSize
ol2podcast.php_.txt2.38 KB
Creating open educational resources - 01 - Introduction.mp3317.25 KB

Comments

It would be great to see a

It would be great to see a demo of this to understand how well it sounds and how it does with pronunciation (with many tts systems much training of the lexicon is needed for english texts since it is not a phonetic language)and also how it stacks up with a DAISY DTB that Andrew Brasher tried out (DAISY DTBs are actually beeing looked at in depth for OU use through the Digital Audio Project).

Andy Lane

Mashups

Hi Liam

Thanks, great post! Perhaps we could offer this as a service?!

I hadn't come across Songbird before - good to know about. One Java based alternative to eSpeak would be Free TTS. And I wonder, is it possible to add pauses, emphasis and so on? Something to discuss further.

Regards, Nick

Hi Nick, Yes absolutely, we

Hi Nick,

Yes absolutely, we can add in quite a lot of description about how the text should be read out using the SSML markup standard. Check out lines 49-50 of the script:
  $content = str_replace(array('<em>','<b>', '<i>'), '<emphasis>', $content);
  $content = str_replace(array('</em>','</b>', '</i>'), '</emphasis>', $content);

Here the HTML tags for emphasis, bold and italic are conveted to the <emphasis> SSML tag as just an indication of what is possible, you could also add other conversions such as changing pitch, speed or spelling out a word.