August 30, 2011

mjpeg

I recently discovered iTunes U where one can listen to lectures on a variety of topics. Most files that I downloaded from there worked fine on my linux box and on my phone but some of the files failed to play correctly. The specific error message said Too many audio packets in the buffer.

Here's a pseudo-solution.

The files were .m4b files. Which is a container format -- a variant of mp4. They are usually encoded using an mjpeg encoder where each frame is basically a jpeg image.

So the first step is to extract the audio track as an mp3:

> ffmpeg -i input_file.m4b -acodec libmp3lame -ab 192000 out.mp3

Which is a good start. We can now listen to the lecture but we're missing the slides. So we need to extract the jpeg images using the following command line:
> ffmpeg -i input_file.m4b -r 1 frame_%05d.jpg

This will result in a slew of images, one for every second of the lecture. To get rid of the duplicates, I use the following ruby script. It's gross but it mostly works:

 1 #!/usr/bin/env ruby
 2 
 3 Dir.new('.').entries.inject(Hash.new) {|hash, f|
 4 
 5   if File.file? f
 6     puts "removing #{f}"; File.delete(f) if hash[File.size? f]
 7     hash[File.size? f] = f
 8   end
 9   hash
10 

Run this in the directory where the frames are and you should be on your way. Careful, that script will delete stuff.

0 comments: