How to Watch Digital Television in Two Easy Steps with GStreamer and V4L

This article will explain how to use GStreamer to capture Digital Television (DTV) streams; it will focus on terrestrial DTV and ATSC broadcasts in the Silicon Valley area to provide examples, but the principles are the same for every other DTV standard or supported location.

If you want to follow the examples, you will at the very least need a Linux machine with GStreamer and v4l-utils, and a DTV capture device. For my ATSC testing setup I use a WinTV-HVR 950Q USB stick (Hauppauge), connected to a Debian desktop computer that runs the latest code for GStreamer and dvbv5-scan from their respective git repositories, both uninstalled. This setup works well for me as a developer but if you simply want to play DTV streams on your machine, the version from your distribution’s binary packages should suffice.

A Few Notes on Receiver Setup

You’ll need to have your receiver setup properly to capture multi-media content from a radio signal. For this to happen, the capture device needs to have an antenna attached and be positioned in an area with coverage. There are several online sources for information on the latter, for the antenna itself my advice is to get a cheap one like the AmazonBasics Ultra Thin Indoor TV Antenna – 35 Mile Range and go from there. I have used this antenna and other slim ones from Mohu and Winnegard with similar results (~40 channels), both in south San Jose and north Mountain View. Do not blindly buy a cheap amplified antenna without first making sure there’s no passive way around your reception problems, such as ensuring proper antenna positioning, using a better cable for the feed, or investing in another antenna with better gain. The latter usually means you’ll get a more directional antenna, and in turn, only be able to get a signal from a single tower. Keep this in mind!

The Process

This two-step process is quite simple after the preliminary requirements have been dealt with. All you have to do is to perform a channel scan, save its results to a file, and have GStreamer use its contents to figure out each channel’s configuration parameters to tune, capture, demux, decode, and render the channel’s digital content on the screen.

Step 1: Perform a Channel Scan

Depending on how you want to look at this, a DTV broadcast – let’s call it a channel for short – is nothing like an analog TV broadcast, but they do share some compatible aspects. For example, a basic set of RF parameters define both of them, including frequency and modulation. However, there are quite a few newer, analog-incompatible properties that show up in the digital domain, like MPEG Program IDs, Error Correction Codes, etc. All of these parameters, both the basic analog and their digital counterparts, are needed to tune into the channels and ultimately play the broadcasted content. For example, here’s the set of parameters defining KQED in the bay area, an ATSC broadcast:

 AUDIO_PID = 67 68 69
 FREQUENCY = 689000000

The lists grows quite a bit for other broadcast standards, like my home-country’s ISDB-T (a variation of the Brazilian standard, but that’s another story) which is why people seldom remember a given digital channel’s parameters like they used to back in the days when “Channel 5” meant something other than a bootleg version of expensive perfume. We now use hardware and software to identify and store these parameters; the process is known in the tech vernacular as “scanning,” and the next few paragraphs will explain how it’s done.

First, you’ll need to get a “frequency file” for your specific geographic location; this is used to feed a program, like dvbv5-scan, that will output a set of discovered channels (and their associated parameters) stored as a DVB configuration file that the playback software will use.

In Debian, the dtv-scan-tables package provides frequency-table files for pretty much all countries in the known universe :-) These files are the result of the Linux TV community’s efforts to provide open access to this information. If your distribution doesn’t provide this package, or you want to have access to its latest information for your area, you can get the corresponding file directly from their upstream repository.

In the following command-line example you can see the corresponding file for my area being passed as the last argument to dvbv5-scan:

dvbv5-scan -O DVBV5 -o channels-dvbv5.conf /usr/share/dvb/atsc/us-CA-SF-Bay-Area

Obviously, for this to work you need to have your DTV capture dongle (and antenna) attached to your computer. The number of channels added to the resulting channels-dvbv5.conf file will depend mostly on how well your antenna is positioned and your area is covered by broadcast towers. You can get this kind of coverage information from official sources like the FCC in the USA, or community/commercial ones like, but there are countless other similar sites you can use so feel free to look around as necessary.

Step 2: Use GStreamer to Capture and Play Digital Television Broadcasts

This part can be incredibly complex and complete or extremely easy and incomplete depending on who you ask. Since this is a two step guide, you shouldn’t expect the former.

As long as dvbv5-scan was able to discover the parameters of at least one channel, you are ready for the final step: to actually watch DTV. For the task we’ll use GStreamer’s magical gst-play, passing the channel name as a parameter (grep the generated channels-dvbv5.conf for your selection, I’m going to be using San Jose’s “KQED+”) and pointing to the parameters file by setting an environment variable. It looks like this

GST_DVB_CHANNELS_CONF=channels-dvbv5.conf gst-play-1.0 dvb://KQED+

Now, the underlying system spawned by this innocent looking gst-play line is, in reality, far more complex. For the capture part alone, it wraps the interaction of at least two dvb-related GStreamer elements: dvbsrc and dvbbasebin. These elements can be configured in a zillion, and I mean it, a zillion different ways. Dvbsrc has some fifty configurable properties that even allow it to tune from space! I plan to write a more in-deep guide that covers a more manual approach later on, so the intention of this first guide was only to get you started, not dizzy.

Good luck and have fun!

Author: Reynaldo Verdejo

Husband, Dad, and Multimedia FOSS developer by trade in between. His work is primarily found in GStreamer and FFmpeg, but he has also contributed to an assorted list of free and open source software during his more than a decade-long software development career.