I recently got to appreciate the possibilities offered by GStreamer when I started playing with my new toy and the videos it records.

Nothing to say about the videos themselves, except that the quality is really good, with a maximum resolution of 640x480, sound (mono), and a maximum length of 10 minutes, more than enough for short video clips. Not that I shoot lots of video clips, but I do from time to time and for the sake of archiving them I needed to fix the rotated videos (a really bad habbit of mine to shoot with my camera rotated 90° clockwise), and of course store them in an open format that I'm sure can be decoded even in 50 years.

For this purpose, GStreamer seemed like the perfect tool. By default the videos, once transferred to my laptop, open with Totem (with GStreamer as a backend). There was the first glitch: no sound for my videos in Totem, and as a side effect, the video would sometimes not play (but sliding a little bit would trigger it correctly). However, both VLC and MPlayer could successfully decode both the video and the sound. A quick look at the console output of MPlayer showed that indeed the sound is not decoded by FFmpeg, which kind of explains why GStreamer cannot decode it:

ISO: File Type Major Brand: Original QuickTime
Quicktime/MOV file format detected.
VIDEO:  [avc1]  640x480  24bpp  29.970 fps    0.0 kbps ( 0.0 kbyte/s)
xscreensaver_disable: Could not find XScreenSaver window.
GNOME screensaver disabled
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)
==========================================================================
==========================================================================
Forced audio codec: mad
Opening audio decoder: [imaadpcm] IMA ADPCM audio decoder
AUDIO: 44100 Hz, 1 ch, s16le, 177.1 kbit/25.10% (ratio: 22136->88200)
Selected audio codec: [imaadpcm] afm: imaadpcm (IMA ADPCM)
==========================================================================

Whatever the imaadpcm audio codec is, I could not find any GStreamer plugin (good, ugly or bad) to decode it. So the solution I came up with was to use MPlayer to extract the audio track to PCM uncompressed sound and then use the GStreamer magic to encode it in the suitable format (namely Vorbis) and remux it with my video into an Ogg container, previously encoded to a suitable format itself (namely Theora).

Here is how to extract the audio track using MPlayer (will be dumped to a file named audiodump.wav):

mplayer -vc null -vo null -ao pcm -benchmark video.mov

Here is how to play the extracted sound using gst-launch:

gst-launch filesrc location=audiodump.wav ! wavparse ! osssink

I won't go into details on how to use gst-launch to build and test GStreamer pipelines, the man page is a good pointer to start, and there exist a bunch of good tutorials. Here is a slightly more complicated pipeline that encodes the extracted audio track to Ogg Vorbis:

gst-launch filesrc location=audiodump.wav ! wavparse ! audioconvert ! vorbisenc ! oggmux ! filesink location=audio.oga

Next step is to extract and decode the video:

gst-launch filesrc location=video.mov ! qtdemux ! ffdec_h264 ! xvimagesink

We can now play both the video and audio parts in sync:

gst-launch filesrc location=audiodump.wav ! wavparse ! osssink filesrc location=video.mov ! qtdemux ! ffdec_h264 ! xvimagesink

Almost there, now let's encode everything and stuff it into an ogg container:

gst-launch filesrc location=audiodump.wav ! wavparse ! audioconvert ! vorbisenc ! oggmux name=muxer muxer. ! filesink location=video.ogv filesrc location=video.mov ! qtdemux ! ffdec_h264 ! theoraenc ! muxer.

Now rotating the video is just a matter of adding a videoflip element to the pipeline (can you guess where?), and the quality of the resulting video can be adjusted with the properties of the vorbisenc and theoraenc elements.

With the help of a simple shell script gathering these elements and placed in my $HOME/.gnome2/nautilus-scripts/, I can rotate and re-encode my videos with a simple click in Nautilus. Easy!

Now the next step would be to add relevant metadata to the videos, such as the author, the place where it was shot and the date and time. Unfortunately, according to Wikipedia, "Currently, there is no official standard for including metadata in Ogg containers [...] Metadata must currently be included in the codec. There is fairly good software support for Vorbis metadata — often referred to as comments. But software support for Theora and FLAC comments in Ogg containers is very limited." Yes, it sucks... The solution is to go with the Vorbis comments, but it does not seem feasible to set tags using only gst-launch (or did I miss something?): one needs to develop a GStreamer application, using for example one of the numerous bindings. Needless to say, I'm going for the Python one!