User Tools

Site Tools


tutorials:command_line_dvb

This is an old revision of the document!


Command line dvb-t by example

I have two budget dvb-t pci cards in a linux box that I use for saving dvb TV programs and, since I am a minimalist, sometimes viewing in real time using xine. In this brief tutorial I will explain how to access DVB broadcasts on the command line and introduce a bare bones example script that will tune a channel, encode a broadcast on the fly and save it to disk.

You might wonder why in the age of Myth TV would I bother to which I would answer that I'm happy enough to be able to open up a terminal (locally or remotely), type in a command, respond to a couple prompts, and schedule a show to be saved for later viewing. I don't need much more than that.


If you want to try any of this on your own machine you will need to install dvb-apps. If a package is not available for your distro or if you want the latest version go to http://linuxtv.org/wiki/index.php/LinuxTV_dvb-apps to get the latest tarball and roll your own. It is a trivial compile with no dependencies or config file to. Just run make then make install for instant gratification or build your own package. If you prefer, you can just run the executables strait from the build directory.

Note that some distros package dvb-apps as dvb-utils and that there is another bundle of dvb related utilities named DVBapps. If you have installed or built the correct dvb-apps, in addition to some include files, libraries and frequency listings you should have installed the follwing command line utilities

rick[~]$ ls saves/build/usr/local/bin/
atsc_epg         azap  dib3000-watch  dvbdate  dvbscan     femon  gotox  scan  tzap
av7110_loadkeys  czap  dst_test       dvbnet   dvbtraffic  gnutv  lsdvb  szap  zap

I will only discuss the use of scan and tzap in this tutorial.

In order to tune a channel with tzap or indeed other applications including mplayer and xine you will first need a channels.conf file. This is created using the scan, and a file containing initial tuning data for at least one transponder/channel for your area. Dvb-apps provides this data for the TV transponders in my area (on Mt. Dandenong) in the file /usr/local/share/dvb/dvb-t/au-Melbourne.

rick[~]$ cat /usr/local/share/dvb/dvb-t/au-Melbourne
# Australia / Melbourne (Mt Dandenong transmitters)
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
# ABC
T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Seven
T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Nine
T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Ten
T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# SBS
T 536625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE

To create my channels.conf I run scan with the path to au-Melbourne and redirect stdout to a file.

rick[~]$ scan /usr/local/share/dvb/dvb-t/au-Melbourne > channels.conf

The complete channels.config looks like this:

ABC News 24:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2314:0:560
ABC1:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:561
ABC2 / ABC4:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:2308:562
ABC1:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:563
ABC3:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2311:2312:564
ABC Dig Music:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2317:566
ABC Jazz:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2318:567
7 Digital:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:769:770:1328
7 Digital 1:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:769:770:1329
7TWO:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:801:802:1330
7mate:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:817:0:1331
7 Digital:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:769:770:1332
TV4ME:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:881:882:1335
Nine Digital:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:519:720:1072
GEM:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:1073
GO!:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:517:700:1074
ONE:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1585
TEN Digital:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1589
ONE:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1591
ELEVEN:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:516:681:1592
SBS ONE:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785
SBS TWO:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786
SBS 3:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:787
SBS 4:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:788
SBS HD:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:789
SBS Radio 1:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:798
SBS Radio 2:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:799

Once the channels.conf file has been created you can put it in ~/.mplayer or ~/.xine if you want to use either of those programs to watch digital TV. I also save a copy as /etc/channels.confto be accessed by the script I use for saving shows to disk.

Note that I have also successfully used this channels.conf on a budget WinFast dvb-s (satelite) card connected to an antenna pointed at Mt. Dandenong, however, I can not say if this would work with all dvb-s cards.

I can now use tzap to tune any channel listed in my channels.conf.

Tzap needs to know what dvb card (adapter) to use. I have two cards installed.

rick[~]$ ls /dev/dvb
adapter0  adapter1

Tzap also needs to know which frontend and which demux to use. My two budget cards can only tune one channel at a time so they only have one frontend and one demux each.

rick[~]$ ls /dev/dvb/adapter0
demux0  dvr0  frontend0  net0

Tzap uses adapter0, demux0 and frontend0 by default, so I will only have to specify which adapter to use when tuning a channel. I will also need to also tell tzap where the channel.conf is and what channel to tune. If I want to set upthe device dvr0 for recording an mpeg-ts (transport stream) I should also use the flag -r. The device net0 is used when feeding packets into the network protocol stack, i.e. streaming a program.

rick[~]$ tzap -a 0 -c /etc/channels.conf -r "ABC1" 
using '/dev/dvb/adapter0/frontend0' and '/dev/dvb/adapter0/demux0'
reading channels from file '/etc/channels.conf'
tuning to 226500000 Hz
video pid 0x0200, audio pid 0x028a
status 01 | signal 2a2a | snr 8000 | ber 00003fff | unc 00000000 | 
status 1f | signal 2b2b | snr ffff | ber 00000000 | unc 00000000 | FE_HAS_LOCK
status 1f | signal 2b2b | snr ffff | ber 00000000 | unc 00000000 | FE_HAS_LOCK
status 1f | signal 2b2b | snr ffff | ber 00000000 | unc 00000000 | FE_HAS_LOCK
<snipped>

Once tzap has tuned the channel it will remain tuned until the process is terminated. The whatever is being broadcast on that tuned channel is available via dvr0 although you need to do something with it.

rick[~]$ cat /dev/dvb/adapter0/dvr0
���,j����{
          ���V12��W1���J��&���G�\���F���k�JjP�)6�)[]]lc�Q���L▒��Ǡ[DE�q�#
V+nx�:�Z�q��nzV��63k�m���[Wdf��Y,�a�m������                             ���F�mi"3a[W��j:�=�J�+
                                           n?>Ѵ�F���g���<E���gޒ�7�2*m�2F�=����]�0-��:eȱK▒�d����͒����G▒-�X�#5�▒����G��0�cW�b�0��Hгڳ
V&0¶s
     V�Ȕ{!��,F▒���+K��Ŕ��a��[V��1Xd��0���Z�sŌ0ٱ��D?�x @-��
                                                          )�@?��?��,[=&hE!2p\�C`@��e▒�KS��B=k1�`���A�2pmn<:6��G�8�@���(�;{��k����lʏ▒���{?sz��e���U��Ã
         V��$Z�i��ݬ,�)3h�-�h[L��6���w��G����P�9��Oe�M�t.l=�L���6���l|�D�Tؾ�ݖK�:���w���צ���O��j&B[0���▒ɘ��6����&+L�TFVG▒6�Q��˘�@����z�G0�V�hbcc-�s��b���X^[[?1;2c^[[?1;2cX�F��Z)��O�X�
٤��)▒ O�"0�#  �0��f@Ɔ2����
�ˌ#
<snipped>

Using cat to stdout is pretty useless but dvr0 can be redirected and saved as a transport stream (.ts) on disk or accessed by an application and viewed in real time by opening up another terminal and running the second command. The following will redirect stdout from dvr0 to a file that can be either viewed or encoded to some other format.

rick[~]$ cat /dev/dvb/adapter0/dvr0 > video_name.ts

As can be seen, the above command redirects stdout from dvr0 to stdin xine.

rick[~]$ xine stdin://mpeg2 < /dev/dvb/adapter0/dvr0
This is xine (X11 gui) - a free video player v0.99.5.
(c) 2000-2007 The xine Team.

The command to access dvr0 with mplayer is even simpler.

rick[~]$ mplayer /dev/dvb/adapter0/dvr0
MPlayer 20101218-4.5.1 (C) 2000-2010 MPlayer Team

Playing /dev/dvb/adapter0/dvr0.
TS file format detected.

VIDEO MPEG2(pid=2307) AUDIO MPA(pid=2308) NO SUBS (yet)!  PROGRAM N. 0
VIDEO:  MPEG2  720x576  (aspect 3)  25.000 fps  10000.0 kbps (1250.0 kbyte/s)
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
Selected video codec: [ffmpeg2] vfm: ffmpeg (FFmpeg MPEG-2)
==========================================================================
==========================================================================
Opening audio decoder: [mp3lib] MPEG layer-2, layer-3
AUDIO: 48000 Hz, 2 ch, s16le, 256.0 kbit/16.67% (ratio: 32000->192000)
Selected audio codec: [mp3] afm: mp3lib (mp3lib MPEG layer-2, layer-3)
==========================================================================
AO: [oss] 48000Hz 2ch s16le (2 bytes per sample)
Starting playback...
Movie-Aspect is 1.78:1 - prescaling to correct movie aspect.
VO: [xv] 720x576 => 1024x576 Planar YV12 
A:39429.8 V:39429.8 A-V: -0.000 ct: -0.345 298/298  5%  0%  0.4% 0 0
<snipped> 
</snipped>

As I mentioned above, I sometimes watch dvb in real time with xine but using tzap in one terminal and then running xine in a second is overkill. However, I do use mplayer's encoding/decoding tool, mencoder, to access dvr0 and encode the transport stream to an mpeg-ps (program stream) on the fly before it is saved to disk.

Except for the inclusion of encoding instructions and a path/name for the out file, the command is the same as for mplayer.

rick[~]$ mencoder -oac copy -ovc copy -of mpeg -mpegopts format=dvd /dev/dvb/adapter0/dvr0 -o video_file.mpg
MEncoder 20101218-4.5.1 (C) 2000-2010 MPlayer Team
success: format: 0  data: 0x0 - 0x0
TS file format detected.
VIDEO MPEG2(pid=2307) AUDIO MPA(pid=2308) NO SUBS (yet)!  PROGRAM N. 0
VIDEO:  MPEG2  720x576  (aspect 3)  25.000 fps  10000.0 kbps (1250.0 kbyte/s)
[V] filefmt:29  fourcc:0x10000002  size:720x576  fps:25.000  ftime:=0.0400
==========================================================================
Opening audio decoder: [mp3lib] MPEG layer-2, layer-3
AUDIO: 48000 Hz, 2 ch, s16le, 256.0 kbit/16.67% (ratio: 32000->192000)
Selected audio codec: [mp3] afm: mp3lib (mp3lib MPEG layer-2, layer-3)
==========================================================================
PACKET SIZE: 2048 bytes, deltascr: 43885
videocodec: framecopy (720x576 24bpp fourcc=10000002)
audiocodec: framecopy (format=50 chans=2 rate=48000 bits=16 B/s=32000 sample-1)
Limiting audio preload to 0.4s.
Increasing audio density to 4.
Writing header...
INITV: 0.200, 0.160, fps: 25.000
Pos:   1.0s     26f ( 0%) 24.88fps Trem:   0min   0mb  A-V:-0.084 [0:256]
<snipped>

I could just save every thing I want to watch as a transport stream but the overhead running mencoder is very minimal. Additionally i prefer to save shows as mpeg-ps videos and I can edit commercials from using a very fast minimalist gui application , gopdit, that was developed specically for editing program streams. If I save an hour long show as an mpeg-ts I would later have to spend as much as another hour encoding to mpeg-ps. Better just to encode o the fly.

Using two terminals and remembering commands and syntax gets to be a bit too much so I'll close this tutorial with a little example script which shows how the commands tzap and mencoder can be used in a script to record a dvb broadcast. To use this script you would have to edit the variable declarations to suit. I written an interactive script that parses channels.conf to present a list of channels then prompts for how long to save, where to save, etc.

I'll present that script later in my series of bash tutorials.

#!/bin/bash
# zap-men
# Edit variables to suit.
dvb_card=1
video_dir=/multimedia
chnl_cnf=/etc/channels.conf
channel=ABC1
duration=3600
name=luther-abc-friday.mpg
 
# Tune in and lock channel
tzap -a $dvb_card -c $chnl_cnf -r "$channel" &
tzap_pid=$!
 
# Give tzap time to tune in and lock channel
sleep 2
 
# Encode on the fly
mencoder -oac copy -ovc copy -of mpeg -mpegopts format=dvd /dev/dvb/adapter$dvb_card/dvr0 -o /multimedia/$name &
mencoder_pid=$!
 
sleep $duration
 
kill $tzap_pid
kill $mencoder_pid
 
# end of script
 
# Note:
# The ampersand "&" is used following both the tzap and mencoder command
# so that they will run in the background and the script will proceed,
# in order, to the next command.
tutorials/command_line_dvb.1330764360.txt.gz · Last modified: 2017/10/12 21:58 (external edit)