Converting Media Center recordings to .mp3
fmw | November 25, 2009Windows Media Center allows me to record BBC Radio broadcasts (DVB-T) as well as TV broadcasts, but I don’t want to listen to them from a PC, I want to listen to them from my iPod/iPhone when it suits me.
There are a few bits of software out there which do TV to iPhone conversion, but I couldn’t find anything which just did the audio. I used to use Digital Media Converter by Deskshare on my Vista MC box, but it doesn’t appear to support .wtv.
Ok, I could convert .wtv to .dvr-ms. You can right-click a .wtv file and convert it, or if you want to script it, the tool you need is here
c:\windows\ehome\wtvconverter.exe
Run from a cmd prompt and it’ll tell you its usage.
Digital Media Converter is also a bit too interactive – I want something I can schedule in the background to automagically pickup recorded radio files, convert them and put them in a place where I can serve them to my iPhone as podcasts. The file copying I can do with perl or in a .bat file, and the converting should ideally be a simple command line tool.
DVRMSToolBox looked promising but ffmpeg wouldn’t reliably convert my recording files and it seems directed to solving a slightly different problem – that of removing adverts and converting audio and video together. And it was a very big complicated set of bits of pieces for what I wanted.
But I’m a programmer! This should be easy – and actually, it pretty much is.
If you want to cut to the chase, the wtv2mp3 software is under downloads in the menu bar above.
Modern version of Windows include something called DirectShow, which is a flexible media rendering and manipulation system, built around the idea of filters. A graph is constructed as a sequence of rendering and transforming filters and then executed. The key to the task at hand is creating the right graph.
There is a simple tool available from Microsoft (but it’s all over the net) called GraphEdit, but I stumbled on GraphEditPlus and initially installed the 30 day trial. Simply choosing ‘Render file’ from the File menu automatically creates a graph to play the file.
Then it’s a case of changing the graph for what we want. Firstly, we can delete all but the top line sequence of filters since we’re only interested in audio. Then we can replace the final ‘Default DirectSound Device’ with an mp3 encoder, and fortunately there’s a DirectShow filter version of the OpenSource LAME encoder. Finally, we can take the output of the LAME Audio Encoder and pipe it into a File writer filter.
This does exactly what we want. But wait, there’s more! GraphEditPlus has an option to generate C++ code for a standalone app for any graph, if you pay for the full version – and you should (I did). When you compile it, it works. But we’re not quite out of the woods yet. I wanted to tweak the code to accept the source and destination filenames from the command line, but in the default graph above there’s no programmatic way to set the source file.
This is because the initial graph was auto-generated by choosing ‘Render file’ from the File menu. If the first filter is deleted and replace by picking ‘StreamBufferSource’ from the list of filters, then all is well.
I also had a problem when I came to first run it on a second machine (i.e., not my development machine). It seems I accidentally picked up an older version of the LAME DirectShow filter which won’t connect to the File Writer output filter. The version must be 3.98.2 (or presumably greater).
Then I wondered if I could programmatically control the LAME encoder bitrate and so on. I got hold of the LAME DirectShow sources and #included iaudioprops.h.
//add LAME Audio Encoder CComPtr<IBaseFilter> pLAMEAudioEncoder; hr = pLAMEAudioEncoder.CoCreateInstance(CLSID_LAMEAudioEncoder); CHECK_HR(hr, "Can't create LAME Audio Encoder"); // BEGIN alter LAME Audio Encoder properties IAudioEncoderProperties *pIP; hr = pLAMEAudioEncoder->QueryInterface(IID_IAudioEncoderProperties, (void **)&pIP); CHECK_HR(hr, "Can't access LAME Audio Encoder Properties"); hr = pIP->set_Bitrate(dwBitRate); CHECK_HR(hr, "Can't set the bitrate"); hr = pIP->set_Quality(dwQuality); CHECK_HR(hr, "Can't set the quality"); pIP->Release(); // END alter LAME Audio Encoder properties hr = pGraph->AddFilter(pLAMEAudioEncoder, L"LAME Audio Encoder"); CHECK_HR(hr, "Can't add LAME Audio Encoder to graph");
And that’s it, really. Installation instructions are on the download page.
Incidentally, it is possible to convert dvr-ms to mp3 in a similar fashion (slightly different graph) but since the former is a historical format, I haven’t implemented it.

