A short addendum to my previous post…

I forgot to explain the reason I decided to write my own scheduler. I could’ve used cron or atd, but those daemons aren’t the most user-friendly to quickly set schedules for. cron may be standard on Linux and BSD systems but the format is arcane, error-prone and non-intuitive. It’s not horrible but I’m a bit surprised something more sensible hasn’t replaced it. atd is more human, but I wanted a configuration file where I didn’t have to know the date when a show began to record it – only the weekday. Then the script would figure out what date that weekday fell on and act accordingly.

Actually it turns out you can sort of do this with atd, although it’s not documented, at least not on the man page, and the time and weekday are reversed. To run a command at 7pm on the upcoming Wednesday:

$at 19:00 Wed << END
? echo Hello world.
warning: commands will be executed using /bin/sh
job 7 at Wed Sep  4 19:00:00 2013

$ atq
7       Wed Sep  4 19:00:00 2013 a ozzmosis

The other advantage is the configuration of my scheduler accepts an end time, which allows it to calculate the recording duration and display it to the user.

The other issue with the cron and atd daemons is that you don't get to see the output of the command in realtime. Instead you get an email after the command has completed, which isn't always ideal for doing scheduled recordings. There are probably a few ways around that, but I'm not keen on them.

Due to the script requiring the Python interpreter, and it never actually terminating (unless you hit Ctrl+C), there is a small amount of memory overhead from having Python loaded in memory all the time. On modern PCs this is trivial, though. There is also no measurable CPU overhead from having the script continuously running in the background - the call to time.sleep() takes care of that.

Lastly, the source code to the script is released to the public domain. You are free to do what you want with it and credit me if you feel like it (or not). I'm sure it has other uses.


Recently for various reasons my blog has become a very low priority, but I should belatedly fulfil a promise I made in the last post where I mentioned a Python script for recording digital television in Linux.

To run the script the only system requirements are a working DVB device (eg. PCI or USB tuner) that tzap can talk to, and a recent version of Python 2.x. Python 2.6.5 works fine on my system running Ubuntu Lucid 10.04. You will need to have tzap working correctly beforehand. See my previous blog post.

I had intended to clean up the code a little but never got around to it. I’m not proud of the date parsing code in it. Looking at it now I can barely understand what it’s doing, but I’ve been using it for a long time now without problems. Anyway, you can download it from here:


The script looks for ~/etc/tvsched.conf and puts the recorded streams in /media/xfs/vidcap. Those paths are hard-coded in the script – obviously you’ll need to change them to suit your system.

tvsched.conf is a comma-separated value (CSV) formatted file with a list of TV shows to record. Comments are allowed if they are prefixed with ‘#’ at the start of the line. Blank lines are allowed, and ignored.

# day, start, end, channel, show-name
Sat, 22:50, 08:00, ABC1, rage-DATE
Sun, 9:30p, 2:00am, TEN Digital, f1-2013-belgium-race

The format should be fairly self-explanatory, with the following comments:

Days of the week can begin with any unambiguous form of the English day of the week. Two letters is enough to be unambiguous, therefore “Mo” is accepted for “Monday”, “Tues” is accepted as “Tuesday”, etc.

The start and end times can be in either 12-hour or 24-hour format, specifying hours and minutes. If using 12-hour format, “a”, “am”, “p” and “pm” are acceptable.

The start and end times can cross midnight.

The channel name should match a channel in the channels.conf file that tzap is using. This is case insensitive – “abc1” is the same as “ABC1” as far as tzap is concerned.

The show name can be any name but should not have spaces in it, otherwise the recorded file will end up in the wrong place. The script doesn’t actually check for that, so be careful.

The string ‘DATE’ in the show name is automatically replaced with the current date in YYYY-MM-DD format.

The script automatically creates a directory under /media/xfs/vidcap/ to store the recorded .mpg file. The .mpg file itself has the format “capture-YYYY-MM-DD-hhmmss.mpg”.

The script re-parses the tvsched.conf roughly every 20 seconds and shows the parsed output to the screen. It will show the start date, start time, end time, recording duration, channel, and the show name you’ve provided.

An unusually long recording duration could mean that you’ve made a mistake entering the start or end time – usually by accidentally mixing up 12 and 24 hour time.

You can lower this 20 second refresh value if you like, but the screen will scroll faster with the parsed output.

The script will abort if tvsched.conf cannot be parsed correctly.

Over a single weekend, the above tvsched.conf file would result in two recordings:


The filenames are approximate, since the script only wakes up 20 seconds, therefore the ‘seconds’ part of the filename may not be zeroed.

I run the script under GNU Screen, so it can be detached. You could also use tmux.


About two years ago I switched operating systems from Windows XP to Ubuntu Linux on my main desktop PC. One of the things I wanted to do was watch digital free-to-air (FTA) TV using this setup. I have a Twinhan Alpha USB DVB receiver which is recognised by Ubuntu automatically, so it was just a matter of chosing the right software. Initially looked at MeTV, Kaffeine and MythTV. MeTV was probably the least difficult to configure. Kaffeine was OK, albeit with a more cumbersome user interface. MythTV seemed overkill for what I wanted, with an odd user interface, too many dependencies (notably MySQL) and too many features I didn’t need.

I’d long been a user of the Windows port of MPlayer, and after a bit of web searching I discovered that MPlayer in Linux could also play video directly from the DVB receiver, provided you had a channels.conf (valid for your reception area) in your $HOME/.mplayer/ directory. This is mine, for digital TV reception in Melbourne, Australia:



With some exceptions, the above file was generated from running the following command:

scan /usr/share/dvb/dvb-t/au-Melbourne > $HOME/.mplayer/channels.conf

The exceptions are:

(1) there seems to be a bug in the ‘scan’ command that prevents it from selecting the correct audio channels on the HD channels, eg. the last three numbers for ONE HD are reported as “514:0:1585” rather than “514:672:1585”. For the HD channels (ABC News 24, 7mate, GEM, ONE HD & SBS HD) I had to use an external set-top box to find the middle number for the correct audio channel. It’s possible more recent versions of ‘scan’ may have corrected this.

(2) in Ubuntu Lucid 10.04 the /usr/share/dvb/dvb-t/au-Melbourne file is missing the entry for community television Channel 31 that began broadcasting on digital TV recently. The complete file is:


# Australia / Melbourne (Mt Dandenong transmitters)
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Seven
T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Nine
T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Ten
T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
T 536625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
# C31
T 557625000 7MHz 3/4 NONE QPSK 8k 1/16 NONE

Now you can test it!

mplayer 'dvb://Nine Digital'

Rather than typing this command each time I have several tcsh aliases configured for each channel:


alias mplayer-dvb "mplayer -cache 1024 -framedrop -x 688 -y 384"
alias mplayer-dvb-lq "mplayer -cache 2048 -framedrop -x 688 -y 384 -vfm ffmpeg -lavdopts lowres=1:fast:skiploopfilter=all:threads=2"

alias onehd "mplayer-dvb-lq 'dvb://ONE HD'"
alias 11sd "mplayer-dvb 'dvb://ELEVEN'"
alias tensd "mplayer-dvb 'dvb://TEN Digital'"
alias 10sd tensd

alias ninesd "mplayer-dvb 'dvb://Nine Digital'"
alias 9hd ninehd
alias 9sd ninesd
alias gosd "mplayer-dvb 'dvb://GO!'"
alias gem "mplayer-dvb-lq 'dvb://GEM'"

alias 7sd "mplayer-dvb 'dvb://7 Digital'"
alias 7two "mplayer-dvb 'dvb://7TWO'"
alias 7mate "mplayer-dvb-lq 'dvb://7mate'"

alias abc24 "mplayer-dvb-lq 'dvb://ABC News 24'"
alias abc1 "mplayer-dvb 'dvb://ABC1'"
alias abc2 "mplayer-dvb 'dvb://ABC2'"
alias abc3 "mplayer-dvb 'dvb://ABC3'"

alias sbs1 "mplayer-dvb 'dvb://SBS ONE'"
alias sbs2 "mplayer-dvb 'dvb://SBS TWO'"
alias sbs sbs1
alias sbshd "mplayer-dvb-lq 'dvb://SBS HD'"
alias ch31 "mplayer-dvb 'dvb://C31'"
alias c31 ch31

In $HOME/.tcshrc I have added the following command to load the above aliases automatically whenever I start tcsh:

source $HOME/etc/dvb-aliases

You’ll notice initially that there are ‘mplayer-dvb’ and ‘mplayer-dvb-lq’ aliases called by the aliases further down:

‘mplayer-dvb-lq’ is for viewing HD channels on an older PC. Currently
I’m using a 3.4 GHz IBM ThinkCentre, and mplayer can’t quite keep-up
with decoding full 1080i MPEG2 HD broadcasts in real time. Using the
“-vfm ffmpeg -lavdopts lowres=1:fast:skiploopfilter=all:threads=2”
mplayer switches lowers the resolution so it can be viewed in real
time without excessive CPU overhead. There are occasional visual
artefacts, and obvious degradation in video quality, but the end
result is still quite watchable.

‘mplayer-dvb’ is for viewing SD channels.

In the past where I’ve had poor reception, setting a small (1024 KB) cache (-cache 1024) seemed to prevent mplayer from prematurely dying whenever there was no signal. Note that the larger the cache, the more delayed your programme will be – time-shifted by a few seconds or more. For HD broadcasts I have a 2048 KB cache, due to their higher bitrate. You could experiment with these cache sizes or perhaps leave them out entirely.

The -framedrop option tells mplayer to “skip displaying some frames to maintain A/V sync on slow systems”. Even on fast systems this option may be useful where the CPU is overloaded by other tasks, eg. video encoding.


Ozzy Osbourne made a new song available online earlier this week as a teaser to his new album ‘Soul Sucka’ scheduled to be released later in the year. The song is called ‘Let Me Hear You Scream’. Guitarist Gus G replaces Zakk Wylde, with Wylde leaving Ozzy’s band after having been with Ozzy for more than 20 years.

Unfortunately the song itself is a bit disappointing and follows much the same pattern as on the Down To Earth and Black Rain albums. Musically I feel it’s lacking in creativity and leaning too much away from the style of Black Sabbath-esque British metal. The guitar solo is interesting not for the fact that Gus G is doing anything unusual – in fact quite the opposite – if you’re familiar with Zakk Wylde’s more recent recordings with Ozzy you’d be forgiven for mistaking the solo for something Zakk might play!

For a song called ‘Let Me Hear You Scream’ you’d expect a lot of anger, but that’s about the only raw emotion you’ll get from this song. This isn’t helped by the fact the song is mastered to be as loud as possible, effectively removing any meaningful dynamic range from the recording, making it very fatiguing to listen to.

Audacity screenshot

Technical notes: The track was ripped from Noisecreep using the Firefox DownloadHelper plugin, with the MP3 extracted using FLV Extract(running under the Linux build of Mono), then loaded into Audacity running under Ubuntu Linux.


Back in August 2007 podcast pioneer Dave Slusher requested a method to take an Apple iTunes Music Store (ITMS) podcast link and translate it to return the standard XML feed of a podcast. It didn’t take long for me to write a quick and dirty Python program to do the work, but some time late last year Apple changed the file formats returned by the ITMS servers which broke my code.

This morning I rewrote it. You can download it from here.

The basic usage is:

./itunes-url-decoder.py url

Where url is the ITMS podcast link.

For example, the ITMS podcast link to the series of Triple M Get This podcasts is:

./itunes-url-decoder.py "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=330582773"

Rest in peace Danny, 1996-2009.


(Photo: Richard, left, with Ed Kavalee.)

Hard to believe that one of the Get This comedy team is no longer with us. Radio host, comedian and writer Richard Marsland passed away yesterday aged only 32. I met him briefly at the "Save Get This" rally outside the Melbourne Triple M studios in November last year. A very entertaining guy who will be missed by many.

RIP, Richard.


"In Windows XP, you can get Explorer to exit cleanly by getting to the shutdown dialog (e.g., Start / Turn Off Computer, or Start/Shutdown), then hold down the Ctrl+Alt+Shift keys and click the"Cancel" button."



Sad news tonight as I received an e-mail with news that Alan Waddell of Walk Sydney Streets passed away overnight.

I did not know him personally but when I was feeling uninspired, his photos and captions would convince me to get up, go outside and explore the world – from cycling to places in Melbourne I’d never been, to just going for a relaxing stroll around the block.

Alan found humour and diversity in everyday Australian suburbia. The sorts of places many of us would never go out of our way to visit unless we had to, Alan would travel there and discover something new and unique. He will be missed. RIP Alan, 1914-2008.


“Close-up images of Australian homes, businesses and famous landmarks in cities, towns and remote areas are now available on Google Maps Australia, absolutely free.” – The Age

This is great. Should make planning new cycling routes much more fun, too!