Some basics of saving dvb-t broadcasts and encoding with command line tools.



Most distros now come with kernels that are DVB-T ready and install shiney new GUI applications for viewing and saving digital TV broadcasts. However, it wasn't so long ago when I purchased my first DVB-T PCI card that it was necesary to compile my own kernel modules and sort out how to grab and save digital TV using command line tools. The rest of this page is a how-to of sorts written a while back and about saving and encoding digital on the command line.


I use tzap which is found in linuxtv-dvb-apps to lock onto a digital broadcast.. You can find it at http:linuxtv.org. If your distro does not have a package it is an easy compile. Open the tarball, go to the directory /linuxtv-dvb-apps-1.1.1/util, run "make", then cd to /linuxtv-dvb-apps-1.1.1/util/szap and you will find the executable tzap. Put tzap in /usr/bin or /usr/local/bin.

You will also need a channels.conf for your locality. Try finding one on the net. If you can't find one, use the tool scan in /linuxtv-dvb-apps-1.1.1/util/scan. The README file explains how to use it. I put my channels.conf in /etc to make it accessable to all users.

With this done I can now run the command tzap -c /etc/channels.conf -r "ABC2" with ABC2 being the second ABC channel in Melbourne, Australia. You can find my channels.conf for Melbourne here.



bash-3.1$ tzap -c /etc/channels.conf -r "ABC2"
using '/dev/dvb/adapter0/frontend0' and '/dev/dvb/adapter0/demux0'
reading channels from file '/etc/channels.conf'
tuning to 226500000 Hz
video pid 0x0905, audio pid 0x0906
status 00 | signal 00ff | snr 8000 | ber 00003fff | unc 00000000 |
status 1f | signal 002c | snr ffff | ber 00000000 | unc 00000000 | FE_HAS_LOCK
status 1f | signal 002c | snr ffff | ber 00000000 | unc 00000000 | FE_HAS_LOCK
status 1f | signal 002c | snr ffff | ber 00000000 | unc 00000000 | FE_HAS_LOCK
status 1f | signal 002c | snr ffff | ber 00000000 | unc 00000000 | FE_HAS_LOCK

In the above example there is only one dvb-t device so the device number does not have to be passed to tzap. Run tzap -h to see view options and usage. The output indicates that I have locked onto the signal. Tzap will remain running until the process is terminated.


Return to top

Remember that in Linux, devices are treated as files and that is how we access them. So if I want to access ABC2, the frequency to which my dvb-t card is locked, I can access it at /dev/dvb/adapter0/dvr0. In order to save that broadcast I open up a second terminal and do the following:



bash-3.1$ cat /dev/dvb/adapter0/dvr0 > /videos/sunday-07-04-29.ts


The above command uses cat to create a file named /videos/sunday-07-04-29.ts. The output from dvr0 is a transport stream, hence the extension .ts. When using this method I am limited to saving the broadcast as a transport stream. I will convert (encode) it later to a program stream, i.e. .mpeg-ps. The .VOB files found on DVD's are .mpeg-ps files.



bash-3.1$ ls -l /videos/sunday-07-04-29.ts
-rw-r--r-- 1 rick users 393216 2007-04-29 09:08 /videos/sunday-07-04-29.ts


Cat will keep on running until I kill it so I switch to third terminal and run ls -l. As you can see above, a minute or so after running "cat", /videos/sunday-07-04-29.ts is already at 393.2 Kb. You need lots of space to record videos. It is better to do it on a separate partition. If you leave a program streaming into a directory on your root partition until there is no space left, you may wish you hadn't.



bash-3.1$ tcprobe -i /videos/sunday-07-04-29.ts
[tcprobe] MPEG transport stream (TS)
(ts_reader.c) end of stream
(ts_reader.c) Pids: 0x906 0x905 [tcprobe] summary for /videos/sunday-07-04-29.ts, 
(*) = not default, 0 = not detected
   no audio track: use "null" import module for audio


The above output shows the results of running tcprobe from Transcode. It confirms that the file being created is an mpeg-ts. There is no seperate audio track. I can also use Mplayer to analyse the video.



bash-3.1$ mplayer -vo dummy -identify /videos/sunday-07-04-29.ts
MPlayer 1.0rc1-3.4.6 (C) 2000-2006 MPlayer Team
CPU: AMD Athlon(tm) XP 2800+ (Family: 6, Model: 10, Stepping: 0)
CPUflags:  MMX: 1 MMX2: 1 3DNow: 1 3DNow2: 1 SSE: 1 SSE2: 0
Compiled with runtime CPU detection.

Playing /videos/sunday-07-04-29.ts.
TS file format detected.
NO VIDEO! NO AUDIO!  NO SUBS (yet)!
No stream found.

Exiting... (End of file)


Return to top

The transport stream format is O.K. if I just want a quick look at something but if I wanted to keep it for later viewing or create a video DVD I would encode to an mpeg-ps format. There is more than one way to do this but I use mencoder, which comes with Mplayer. Syntax for a basic encoding follows:



mencoder -of mpeg -ni -mpegopts format=dvd:vbitrate=9000 -o sunday-07-04-29.mpg \
-oac copy -ovc copy sunday-07-04-29.ts


Note: the first line of this command ends with " \ ". When used in a script or on the command line this indicates that the command continues on the next line. You need to separate it from your break in the command with a space.

Upon completion of this command I will now have a video encoded to an mpeg-ps format and I can check out it's properties with mplayer.



bash-3.1$ mplayer -vo dummy -identify /videos/sunday-07-04-29.ts
MPlayer 1.0rc1-3.4.6 (C) 2000-2006 MPlayer Team
CPU: AMD Athlon(tm) XP 2800+ (Family: 6, Model: 10, Stepping: 0)
CPUflags:  MMX: 1 MMX2: 1 3DNow: 1 3DNow2: 1 SSE: 1 SSE2: 0
Compiled with runtime CPU detection.

Playing sunday-07-04-29.mpg.
ID_VIDEO_ID=0
ID_AUDIO_ID=0
MPEG-PS file format detected.
VIDEO:  MPEG2  720x576  (aspect 3)  25.000 fps  9000.0 kbps (1125.0 kbyte/s)
ID_FILENAME=sunday-07-04-29.mpg
ID_DEMUXER=mpegps
ID_VIDEO_FORMAT=0x10000002
ID_VIDEO_BITRATE=9000000
ID_VIDEO_WIDTH=720
ID_VIDEO_HEIGHT=576
ID_VIDEO_FPS=25.000
ID_VIDEO_ASPECT=0.0000
ID_AUDIO_FORMAT=80
ID_AUDIO_BITRATE=0
ID_AUDIO_RATE=0
ID_AUDIO_NCH=0
ID_LENGTH=65.52
Error opening/initializing the selected video_out (-vo) device.

Exiting... (End of file)


This encoding will do just fine if I am saving videos to disk for later viewing or if I want to edit out commercials and such using Gopdit, my prefered mpeg-ps editor.

However, I use a longer mencoder command to prepare my videos for burning to a DVD. The command listed below usually decreases the size of the video and my experience has been that I have less problems with audio/video sync. It will encode either a tranport stream or a program stream. Both this command and the one above produce a PAL video.



mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd \
-vf scale=720:576,harddup -srate 48000 -lavcopts \
vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:#Wrapped!
keyint=15:acodec=ac3:abitrate=192:aspect=16/9 \
-ofps 25 $INPUT_FILE -o $OUTPUT_FILE


Note: I have broken the third line of the above command with a comment preceded by " # ". The third line in the above example is a continuation of the second line. If you copy it, join the two lines with no #, comment or space between them there is no way to break that line with a forward slash.

Return to top

To make life simple, and because I am incapable of remembering the syntax of long commands, everything required could be put into a script The snippet below shows how I could use tzap to lock on to a signal and dvbstream to save it to disk as an mpeg-ps in a script.


	# If frontend0 is active, kill it.
       fuser -k /dev/dvb/adapter0/frontend0
		
	# Tune in and lock channel
	/usr/local/bin/tzap -c /etc/channels.conf -r "ABC2" &
	# Then get the pid of tzap
	TZAP_PID=$!
		
	# Ok so far? Lets get that channel up with dvbstream
       /usr/local/bin/dvbstream -f 226.5 2307 2308 -ps -o > $VIDEO_DIR/$NAME.mpg & 
       DVBSTREAM_PID=$!
             
       # Set duration of recording after converting minutes to seconds
	DURATION=$(($TIME*60))
	sleep $DURATION
                
       kill $TZAP_PID
       kill $DVBSTREAM_PID                
         

In the example above tzap usage is exactly the same but dvbstream also needs to know which channel (frequency) to grab. The numbers after "-f" are taken from my channels config.


ABC2:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64: #This line is wrapped!
TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:2308:562


Return to top

I don't need to use tzap if I have dvbstream working in my box. The first time I tried using it there were some problems with locking onto signals but tzap worked just fine so that's how I traveled for awhile.

However, it turned out that seemed that my original source for dvbstream was from cvs or something of the sort and a later compile of dvbstream-0.5 from new source worked just fine and eliminating the need to use tzap. Below is the command and output from dvbstream for ABC2. Don't give the line about "tuning DVB-T (in United Kingdom)" too much credence. That's in the code and I am in Australia.


bash-3.1$ ././dvbstream -qam 64 -cr 3_4 -gi 16 -bw 7 -tm 8 -f 226500 -ps \
-n 10 -o 2308 2307 > /videos/sunday-07-04-29_dvbstrm.mpg
dvbstream v0.5 - (C) Dave Chapman 2001-2004
Released under the GPL.
Latest version available from http://www.linuxstb.org/
Using DVB card "Conexant CX22702 DVB-T"
tuning DVB-T (in United Kingdom) to 226500000 Hz
polling....
Getting frontend event
FE_STATUS:
polling....
Getting frontend event
FE_STATUS: FE_HAS_SIGNAL FE_HAS_LOCK FE_HAS_CARRIER FE_HAS_VITERBI FE_HAS_SYNC
Bit error rate: 0
Signal strength: 43
SNR: 65535
FE_STATUS: FE_HAS_SIGNAL FE_HAS_LOCK FE_HAS_CARRIER FE_HAS_VITERBI FE_HAS_SYNC
Setting filter for PID 2308
Setting filter for PID 2307
Output to stdout
Streaming 2 streams
Audiostream: Layer: 1  BRate: 128 kb/s  Freq: 44.1 kHz
Videostream: ASPECT: 16:9  Size = 720x576  FRate: 25 fps  BRate: 15.00 Mbit/s

Let's see what mplayer has to say about the video I just created:


bash-3.1$ mplayer -vo dummy -identify test.mpg
MPlayer 1.0rc1-3.4.6 (C) 2000-2006 MPlayer Team
CPU: AMD Athlon(tm) XP 2800+ (Family: 6, Model: 10, Stepping: 0)
CPUflags:  MMX: 1 MMX2: 1 3DNow: 1 3DNow2: 1 SSE: 1 SSE2: 0
Compiled with runtime CPU detection.

Playing test.mpg.
ID_VIDEO_ID=10
ID_AUDIO_ID=0
MPEG-PS file format detected.
VIDEO:  MPEG2  720x576  (aspect 3)  25.000 fps  15000.0 kbps (1875.0 kbyte/s)
ID_FILENAME=test.mpg
ID_DEMUXER=mpegps
ID_VIDEO_FORMAT=0x10000002
ID_VIDEO_BITRATE=15000000
ID_VIDEO_WIDTH=720
ID_VIDEO_HEIGHT=576
ID_VIDEO_FPS=25.000
ID_VIDEO_ASPECT=0.0000
ID_AUDIO_FORMAT=80
ID_AUDIO_BITRATE=0
ID_AUDIO_RATE=0
ID_AUDIO_NCH=0
ID_LENGTH=159.98
Error opening/initializing the selected video_out (-vo) device.

Exiting... (End of file)


I first started playing around with DVB-T in late 2005 when I had to compile my own kernel modules for a 2.4.11 kernel and most of the applications for viewing digital TV seemd a bit problematic. However, I could get things working on the command line and being that I'm inclined to write scripts even when I don't need one, it seemed easier to just script something up for saving digital broadcasts.

Things are different now but for me MythTV, Kaffeine, et. al. are overkill for timeshifting on my own machine and since we also have a server with a DVB-T card onboard there is a need to be able to schedule and save digital broadcasts with ssh access to the server and a script to do the timeshifting

You can find information about and a link to my save-dvb script here.