There's always time to play

Wednesday, June 18, 2008

gstreamer television recording

I've been trying to record stuff from my tv tuner card using gstreamer. I like gstreamer as a multimedia framework and I like some apps that use it, so although there are enough other options I wanted to try this using gstreamer first.

The first issue was to record something from the tv card. I started by installing the video4linux gstreamer plugin. I actually started with installing version 1, then noticed there was a version 2 and because that's what the kernel uses natively I decided to go for v4l2. The gstreamer plugin is called v4l2src. I already read that to display something you need to run it through ffmpegcolorspace. To get it more useful you also need to specify resolution and framerate so to get something useful on my screen I started with
gst-launch-0.10 v4l2src device=/dev/video0 ! \
video/x-raw-yuv,width=768,height=520,framerate=\(fraction\)30000/1001 ! \
ffmpegcolorspace ! ximagesink

This works, but you still need to control the tv card or else you'll probably just see snow. There's a few different ways to control the tv card, but I wanted something as small as possible because I only needed to change the frequency to a desired frequency. I found dov4l, a small program that can do all the basic stuff that I needed done. To switch to discovery channel I could do a simple
./dov4l -f 496000000
from the folder where I unpacked the dov4l sources after I ran make. So now I actually had discovery channel displaying on my computer screen. Next step was audio. I use a bt878 tv card so I can use snd_bt87x to capture audio from the tuner device. A simple
gst-launch-0.10 alsasrc device=hw:1,0 ! alsasink
gave sound, so now I had audio and video from my tv card.

Now the hardest part was to get it all into a file. I'd seen various websites explaining some simple gstreamer stuff, and that at least taught me about muxing and demuxing. Actually, I didn't know much about the basics either. In short you usually want to encode video into something, encode audio into something and then dump it into a media container. So one common media container everyone knows is the avi format. I actually started out with ogg (vorbis and theora in an ogg container), but that gave me issues with both picture and sound so I soon moved to lame to convert my audio into mp3 and used ffenc_mpeg4 to convert my video into mpeg4. Dumping that into an avi container I ran into audio sync issues. After asking in #gstreamer on freenode I was told that the avi container doesn't handle time very well (or at all), so I should use another container and they pointed me to matroska. At this moment I was able to record to a file and view it afterwards, but that was not enough for me...

I wanted to use something modern. Although I quite like matroska containers because they're quite well supported on all platforms (vlc supports them, so any platform that supports vlc can in some way handle them) I was looking more for something like mp4. ffmpeg offers a muxing plugin for mp4, but I haven't gotten it to also use audio and I can only play it with mplayer then, so that's not really an option. I could however use something else in the matroska container. So I decided to use x264 for video. I'm on gentoo so I prefer to install by using ebuilds (although I'm using paludis so importare works for me too), so I went looking for an ebuild. The easy solution is to copy an existing gst-plugins-bad plugin ebuild (like the lame ebuild) and name it gst-plugins-x264-0.10.6.ebuild and place it in a correctly named folder in an overlay. Remove the deps that don't make sense (only lame for this specific plugin) and you should be able to install the plugin. I first tried with -0.10.7, but that wants gstreamer-0.10.19, so I decided to stick with gst-plugins-x264-0.10.6. Now I also needed something decent for audio, and I decided to go for faac, which seems to be reasonably supported these days and I ended up with the following line to do nice gstreamer recording from my tv card:
gst-launch-0.10 matroskamux name=mux ! \
filesink location=test.mkv alsasrc device=hw:1,0 ! \
audio/x-raw-int,channels=2,rate=32000,depth=16 ! \
audioconvert ! faac ! queue ! \
mux. v4l2src device=/dev/video0 ! \
video/x-raw-yuv,width=768,height=520,framerate=\(fraction\)30000/1001 ! \
ffmpegcolorspace ! x264enc ! queue ! mux.

I started with a capture resolution of 924x576, because that's what my card supports, but x264enc doesn't like that. Besides the fact that it complains that it can't encode fast when the width or height is not a multiple of 16 it wasn't properly encoding on that resolution. So as you can see I dropped it to 768x520, which gives a very decent picture, even for full screen viewing. Have fun watching!

Thursday, June 5, 2008

Ripping audio from youtube movies (using gstreamer)

Today my girlfriend needed the audio from a youtube clip, so I decided to see how easy I could get it. I started by getting the flv from the clip, one useful source for that is After I had the file I verified I could actually play it, double clicking opened totem and started playing, so far so good.

Because totem managed to play I thought gstreamer should be able to open the file and I already knew gstreamer was capable of converting and after about 3 tries I came up with the following command:
gst-launch-0.10 filesrc location=file.flv ! decodebin ! audioconvert ! lame ! filesink location=file.mp3

- opens the file
- decodes the file (I guess this is needed to rip audio only)
- does something with audio, I don't know if you always need this but I think this is a sort of wrapper to match input with output plugins
- encodes to mp3 audio
- writes to a file

There's much more you can do with gstreamer, so if you found another one of those 'this might be useful every once or twice in five years' commands please let me know in comments.

Wednesday, June 4, 2008

How to get google gadgets to get gadget metadata

So it seems that now google gadgets for linux has been announced a lot of people want to try it. Seems most of them are retarded too and can't get it working. Because I have nothing against retarded people I'm going to list what I've found out:
- The error "Failed to update gadget metadata" can mean a couple of things.
- Curl needs to use openssl for cryptography to work with ggl.
- On gentoo you seem to need recent ca-certificates. In my case, upgrading from amd64 to ~amd64 worked.
- a simple `curl` can show you why ggl can't fetch metadata.

I hope someone reads this and thinks it's useful, please leave a comment if so.