Audio books

I've been listening to MP3 audio books during my daily commute to work for quite a few years.

The biggest problem with listening to books is losing your place or getting back to the place you left off after you've taken a break in listening.

During the first year or so, I used a CD MP3 player. Here there was no memory of where I'd left off at all. So the last thing I would do when I was finished listening was to note the track number and minutes/seconds into the track (I used to dial it on my cell phone; a great way to remember a number). When I got back in the car and wanted to resume listening I would have to go back to the correct track, minutes and seconds where I had left off. Very tedious!

After the CD player I had a Pocket PC (I got it from my work -- Destinator Technologies, makers of GPS navigation software). On the Pocket PC I could install a decent MP3 player, one that could help me to keep track of where I was in the book. I used Mirko Schenk's excellent open source MortPlayer. This player even has a special mode to use when playing audio books (which is something I later found out the best MP3 players (like iPod) have to help listen to audio books).

After leaving Destinator and my borrowed PPC behind, I had to find some new way of listening to books during my commute. Going back to the CD player was out of the question because it had a problem with playing tracks in the correct order. This led to life threatening situations where I'd try to find my place in some book while speeding down the highway. Not something I wanted to go back to.

As I also needed to get a cell phone, I thought that I might be able to combine the 2 functions and get a phone with an MP3 player. After much investigation, I got the Motorola MOTORazr V6 MAXX which was supposed to have good MP3 playing capabilities. It turns out that it is a nice phone (my first non-Nokia, and not bad at all) but completely useless for listening to audio books. There is no way to save your place in an MP3, or even in a play list. So each time you want to start a listening session, you would have to laboriously find your place.

So finally I bought a cheap little flash memory based MP3 player from a company called "Bross" (for some every time I turn the device on and I see the word Bross on the screen I always think of someone saying "Hey bro's, how's it goin'?"). Strangely enough, I haven't been able to find any reference to an MP3 player manufactured by Bross anywhere on the internet.

The device has 1GB (which is plenty for audio books), and cost only 140 Israeli Shekels (~$35). It works fine, though with some slightly annoying quirks. One quirk is that sometimes the first first track in a folder will be some file in the middle of the list of files (track 23 out of 100, for example). The tracks are all named uniformly and have no tag info at all. There is no reason I can see why the first track displayed for the folder would not be track 1... The device has a USB port for managing its memory.

Here's a blurry picture of the player taken with my phone's camera:


The device has the crucial feature required to allow it to be used for listening to audio books: it remembers where it was stopped even after turning it off and changing the batteries. This site has a detailed post about what to look for when buying an MP3 player for listening to audio books.

Unfortunately though, sometimes it does forget the previous location inside an MP3 track, forcing me to search through the track for the point I left off. To make this as painless as possible, I've written a script which ensures that my MP3 files are never longer than 5 minutes long each. The script is written in Python, and uses mpgedit to first make 1 huge MP3 file and mp3splt to split it into smaller files.

The script will accept arguments, but the defaults are such that if you run it in a folder with a bunch of MP3s that are in the correct playing order when sorted by name, you will get good results. Some other processing that might be useful to do to the MP3s is to increase the volume (this is done in the script using mp3gain but currently commented out) or to decrease the sample rate in case you are limited in space and have MP3s with a bit rate of over ~44kbps (not needed for speech recordings) -- easily done using lame.

Here's the script:
import getopt, sys, glob, shutil, os, re
from subprocess import call

def usage():
usage_text="""
usage: ebook-mp3.py [-n ] [-d ] [-p ]
"""
print usage_text

def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "n:d:p:")
except getopt.GetoptError:
# print help information and exit:
usage()
sys.exit(2)
mpgedit = r"D:\Program Files\mpgedit.org\mpgedit\mpgedit_nocurses.exe"
mp3splt = r"D:\etc\mp3splt-2.1\mp3splt.exe"
mp3gain = r"D:\Program Files\MP3Gain\mp3gain.exe"
new_name = None
dest_dir = "."
source_pattern = "*.mp3"
for o, a in opts:
if o in ("-n"):
new_name = a
if o in ("-d"):
dest_dir = a
if o in ("-p"):
source_pattern = a
source_files = glob.glob(source_pattern)
if new_name == None:
new_name = raw_input("Enter base name for split files:")
mpgedit_args = [mpgedit, '-o', new_name, '-e-']
mpgedit_args.extend(source_files)
call(mpgedit_args)
for filename in source_files:
os.remove("%s.idx" % filename[ : -4])
# call([mp3gain, "/r", new_name])
call([mp3splt, "-q", "-n", "-a", "-t", "5.0", "-d", dest_dir, new_name])
os.remove(new_name)
for filename in glob.glob("%s*.mp3" % new_name):
shorter_filename = re.sub(r"%s_(\d{3})\.00_(\d{3})\.00" % new_name,
r"%s_\1_\2" % new_name, filename)
os.rename(filename, shorter_filename)

if __name__ == "__main__":
main()

...and even more personal.

I've changed the title of the blog to being my name. I previously called it Mirrorshades because of a picture of my son wearing my mirrorshade sunglasses (and because I liked the cyberpunk/mirrorshade science fiction books so much in my past) which appeared in the heading of the blog. But I've since removed the picture, so at this point the name just sounds juvenile to me.

Blog updates

I've updated the blog description to something I saw on Mark Pilgrim's blog (dive into mark): useful or personal. Seems like a good intent for my blog content.

In keeping with that I've made the blog a bit more personal by including my full name ;-). Much more personal than it was before.

P2P when your PC is idle

I've noticed that keeping a BitTorrent client running can be a bit of a pain. On the one hand you don't want it on while you are using the computer (so that it doesn't suck your bandwidth), but on the other hand it's easy to forget to turn it back on after you've finished with the computer.

A solution I've found (on Windows) is to schedule the client to run when the PC is idle, also setting it to stop running when not idle.

Create a scheduled task (Start->Control Panel->Scheduled tasks) where the file to run is your P2P client (such as EMule or uTorrent). If you don't know where the file you need to run is you can get the location from the shortcut you normally use to start the client.

See the screenshots for how to configure your new task.




Note the checkbox for "Stop the task if the computer ceases to be idle". I'm not sure how well this works; if it is not set then you will have to close the client when you want to start using the internet.

Handling and Archiving Home Digital Video

I bought a digital video camera over 3 years ago (right after the birth of my first child) but have only now figured out how to best handle the video it produces.

Video is not like still pictures; you can't just print out the stills you like and stick them in an album. Ideally, after you've shot some video footage, you need to become an editor and make an effort to take your best footage to create an enjoyable movie. One of these days I'll get around to doing that...

In the meantime, I wanted to a) be able to see the video I've shot and b) store it for some future time when I might want to create some edited movies.

The procedure:

Step 1


Video capture; Transferring the video from camera to PC.

The important point of the transfer is to not lose data while transferring. In order to do this, store the video on the PC as DV AVI. This means that the stored video is the full original size and completely uncompressed. The downside of capturing the video in this format is that it takes up a lot of space (about 217 megabytes for 1 minute of video). Though with the low prices of hard disks today, this is not a big problem for most people.

I recommend using a simple and lightweight (and free) application for transferring called WinDV, detailed usage help here. WinDV works great (most importantly, it never drops frames). Once small gotcha I've noticed with it though is that the first clip saved has the current date/time, rather than the date/time when the video was recorded. Make sure you rename that clip to the correct time (which WinDV displays correctly on the screen while transferring) to help you to sort out the clips at a later time.

Step 2


Encoding (compressing)

The raw footage captured in step 1 has some problems.
1. It's huge. In its uncompressed form, only about 20 minutes will fit on a DVD.
2. It can't be easily viewed. A DVD with the raw footage can't be put into a DVD player and viewed.
3. It's interlaced. Check out the site 100fps.com for more information about what that means.

To solve these problems, I encoded the footage using the latest DivX codec (version 6.6.1), with the following settings:


Once the video is saved in this format, it is much smaller (about a 1:6 ratio) and playable on a DVD player that reads the DivX format. The quality of the encoded video is also excellent; I don’t see any degradation in quality between it and the raw footage, though there doubtless is some.

In addition to the video compression, I also compressed the audio using LAME MP3 at 128kbps CBR.

The encoding work is done with the free app VirtualDub. I found a short script to remove the tedium of creating the VirtualDub encoding jobs at this site, “Scripted VirtualDub Job Creation”.

This is the contents of the VirtualDub configuration file used to duplicate my settings:
VirtualDub.audio.SetSource(1);
VirtualDub.audio.SetMode(1);
VirtualDub.audio.SetInterleave(1,500,1,0,0);
VirtualDub.audio.SetClipMode(1,1);
VirtualDub.audio.SetConversion(0,0,0,0,0);
VirtualDub.audio.SetVolume();
VirtualDub.audio.SetCompressionWithHint(85,32000,2,0,16000,1,12,"AQAEAAAAQAIBAAAA","LAME MP3");
VirtualDub.audio.EnableFilterGraph(0);
VirtualDub.video.SetInputFormat(0);
VirtualDub.video.SetOutputFormat(7);
VirtualDub.video.SetMode(3);
VirtualDub.video.SetFrameRate(0,1);
VirtualDub.video.SetIVTC(0,0,-1,0);
VirtualDub.video.SetCompression(0x78766964,0,10000,0);
VirtualDub.video.SetCompData(145,"LWJ2MXEgMSAtdmJ2IDQ4NTQwMDAsMzE0NTcyOCwzMTQ1NzI4IC1kaXIgIkM6XERvY3VtZW50cyBhbmQgU2V0dGluZ3NcRE1SXEFwcGxpY2F0aW9uIERhdGFcRGl2WFxEaXZYIENvZGVjIiAtYiAxIC1wIC1uZiAtcHJvZmlsZT0zIC1kZWludGVybGFjZT0xAA==");
VirtualDub.video.filters.Clear();
VirtualDub.audio.filters.Clear();

Step 3


Burning onto DVD

I burned the encoded DivX AVI files onto DVDs using the omnipresent Nero.

The final DVDs are ready for viewing in modern DVD players which support DivX playback.