LinHES Forums http://forum.linhes.org/ |
|
DVB channnel setup http://forum.linhes.org/viewtopic.php?f=3&t=2120 |
Page 1 of 1 |
Author: | nigelpearson [ Wed Aug 04, 2004 12:57 am ] |
Post subject: | DVB channnel setup |
Setting up channels in MythTV for DVB is a bit tricky because you need the frequency of the transponder, the bandwidth, the encoding rates, the modulation scheme, hiererchy and at least 3 IDs for each channel. This guide was what I used to help me: http://www.ethics-gradient.net/myth/mythdvb.html but it is still hard going. If you have already got DVB channel data (e.g. from the linuxtv-dvb-apps scan utility) then there are a few ways to import this data into the MythTV database: 1) zap2myth from here: http://www.cs.man.ac.uk/~brejc8/dvb 2) A script for inserting channel data from a channels.conf file, here: Code: #!/usr/bin/perl -w
# ============================================================================ # = NAME # channels.conf-import # # = PURPOSE # Insert DVB channel information into the MythTV database # # = USAGE # channels.conf-import # channels.conf-import -c # Parse czap format channels.conf file # channels.conf-import -s # Parse szap format channels.conf file # channels.conf-import -t # Parse tzap format channels.conf file # channels.conf-import -d # Extra debugging output # channels.conf-import -n # No execute (safe or simulation) mode # # = PREREQUISITES # 1. A MythTV backend with valid VideoSource data # (i.e. a listings provider which has downloaded channel information) # 2. A channels.conf file generated from linuxtv-dvb-apps util/scan. # DVB-T (i.e. tzap) is assumed # # = DESCRIPTION # For each channel in the database, this script tries to match # a line from channels.conf. If it doesn't find a good match, # it will prompt the user for a search term. # (e.g. My database had "Seven", # but the network publishes itself as "7 Digital") # # = KNOWN BUGS # If this is run before any channel data is inserted # into the MythTV database, it silently hangs. # # = REVISION # $Id$ # # = AUTHORS # Malcolm Smith, Nigel Pearson # ============================================================================ use strict; use DBI(); use Getopt::Long; use File::Basename; # configuration #my $channelsconf = "/root/.szap/channels.conf"; #my $channelsconf = "/usr/src/DVB/apps/szap/channels.conf-dvbt-oxford"; my $channelsconf = "channels.conf"; # type of channels.conf file my $channelsconftype = "tzap"; my $sourceid = 1; # whether to ask for some "optional" fields my $ask_networkid = 0; my $ask_providerid = 0; my $ask_serviceid = 1; my $ask_transportid = 0; my $sql1="Invalid"; # do nothing my $simulate = 0; # extra console output my $DEBUG = 0; # ============================================================================ # Parse any command-line arguments # my $arg; for $arg ( @ARGV ) { if ( $arg eq '-c' ) { $channelsconftype = 'czap' } elsif ( $arg eq '-d' ) { $DEBUG = 1 } elsif ( $arg eq '-n' ) { $simulate = 1 } elsif ( $arg eq '-s' ) { $channelsconftype = 'szap' } elsif ( $arg eq '-s' ) { $channelsconftype = 'tzap' } elsif ( $arg eq '-v' ) { $channelsconftype = 'vdr' } else { die "Invalid argument '$arg'\n" } } # ============================================================================ # variable definition # my $doinserts; my $dofind; my $networkid; my $transportid; my @channeldata; my %channelhash; my $db_host; my $db_user; my $db_name; my $db_pass; # ============================================================================ # Given a list of parsed fields, generate an SQL statement to # insert these # fields and values into the dvb_channel table sub genChan($@) { my ($chanid, @fields) = @_; my $sql = 'REPLACE INTO dvb_channel (chanid, ' . join (', ', @fields) . ")\n" . "VALUES ($chanid, "; my $field; foreach $field ( @fields ) { if ( defined $channelhash{$field} ) { my $val = $channelhash{$field}; if ( $val =~ /^\d*$/ ) # If value is a number { $sql .= "$val, " } else { $sql .= "'$val', " } } else { print "\$channelhash{'$field'} does not exist\n" } } chop $sql;chop $sql; # Remove trailing ', ' return "$sql);\n"; } # ============================================================================ # Routines to parse ZAP-style files # sub fix_zFEC { $channelhash{'fec'} =~ s/FEC_//g; $channelhash{'fec'} =~ s/_/\//g; } sub fix_zInversion { if ($channelhash{'inversion'} eq "INVERSION_ON" ) { $channelhash{'inversion'} = '1' } if ($channelhash{'inversion'} eq "INVERSION_OFF" ) { $channelhash{'inversion'} = '0' } if ($channelhash{'inversion'} eq "INVERSION_AUTO" ) { $channelhash{'inversion'} = 'a' } } sub fix_zMod { # make modulation lowercase $channelhash{'modulation'} =~ s/QAM/qam/g; } sub parseCZAP(@) { $channelhash{'frequency'} = shift @channeldata; $channelhash{'inversion'} = shift @channeldata; $channelhash{'symbolrate'} = shift @channeldata; $channelhash{'fec'} = shift @channeldata; $channelhash{'modulation'} = shift @channeldata; &fix_zInversion; &fix_zFEC; &fix_zMod; } sub parseSZAP(@) { $channelhash{'frequency'} = (shift @channeldata) . '000'; $channelhash{'polarity'} = shift @channeldata; $channelhash{'satid'} = shift @channeldata; $channelhash{'symbolrate'} = (shift @channeldata) . '000'; # on dvb-s we always have qpsk $channelhash{'modulation'} = 'qpsk'; } sub parseTZAP(@) { $channelhash{'frequency'} = shift @channeldata; $channelhash{'inversion'} = shift @channeldata; $channelhash{'bandwidth'} = shift @channeldata; $channelhash{'fec'} = shift @channeldata; $channelhash{'lp_code_rate'} = shift @channeldata; $channelhash{'modulation'} = shift @channeldata; $channelhash{'transmission_mode'} = shift @channeldata; $channelhash{'guard_interval'} = shift @channeldata; $channelhash{'hierarchy'} = shift @channeldata; # Set polarity and symbolrate here to defaults $channelhash{'polarity'} = 'V'; $channelhash{'symbolrate'} = '69000'; &fix_zInversion; &fix_zFEC; &fix_zMod; $channelhash{'bandwidth'} =~ s/BANDWIDTH_//; $channelhash{'bandwidth'} =~ s/_.*//; $channelhash{'guard_interval'} =~ s/GUARD_INTERVAL_//g; $channelhash{'guard_interval'} =~ s/_/\//g; if ($channelhash{'hierarchy'} eq "HIERARCHY_NONE" ) { $channelhash{'hierarchy'} = 'n' } else { $channelhash{'hierarchy'} = 'auto' } $channelhash{'lp_code_rate'} =~ s/FEC_//g; $channelhash{'lp_code_rate'} =~ s/_/\//g; $channelhash{'transmission_mode'} =~ s/TRANSMISSION_MODE_//g; $channelhash{'transmission_mode'} =~ s/K//g; } sub parseZAP { if ( $channelsconftype eq 'szap' ) { &parseSZAP(@channeldata) } elsif ( $channelsconftype eq 'czap' ) { &parseCZAP(@channeldata) } elsif ( $channelsconftype eq 'tzap' ) { &parseTZAP(@channeldata) } else { die "Illegal channelconftype in perl script" } $channelhash{'vpid'} = shift @channeldata; $channelhash{'apid'} = shift @channeldata; $channelhash{'serviceid'} = shift @channeldata; chop $channelhash{'serviceid'}; } # ============================================================================ # Routines to parse VDR-style file sub parseVDRs { die "Sorry - Nigel hasn't implemented VDRs parsing yet"; } sub parseVDRc { die "Sorry - Nigel hasn't implemented VDRc parsing yet"; } sub parseVDRt { die "Sorry - Nigel hasn't implemented VDRt parsing yet"; } sub parseVDR { if ( grep m/:T:27500:/, @channeldata ) { &parseVDRt } elsif ( grep m/:M.*:C:/, @channeldata ) { &parseVDRc } else { &parseVDRs } } # ============================================================================ # Read the mysql.txt file in use by MythTV. # could be in a couple places, so try the usual suspects open(CONF, "/usr/share/mythtv/mysql.txt") or open(CONF, "/usr/local/share/mythtv/mysql.txt") or die ("Unable to open /usr/share/mythtv/mysql.txt: $!\n\n"); while (my $line = <CONF>) { chomp($line); $line =~ s/^str //; my ($var, $val) = split(/\=/, $line, 2); next unless ($var && $var =~ /\w/); if ($var eq 'DBHostName') { $db_host = $val; } elsif ($var eq 'DBUserName') { $db_user = $val; } elsif ($var eq 'DBName') { $db_name = $val; } elsif ($var eq 'DBPassword') { $db_pass = $val; } } close CONF; # Connect to the database my $dbh = DBI->connect("dbi:mysql:database=$db_name:host=$db_host", $db_user, $db_pass) or die "Cannot connect to database: $!\n\n"; if ($simulate) { print "Simulation mode. SQL not done.\n"; }; # Now retrieve data from the channel table. my $tb_channel = $dbh->prepare("SELECT * FROM channel WHERE sourceid=$sourceid"); $tb_channel->execute(); while (my $ref = $tb_channel->fetchrow_hashref()) { $dofind = 0; print "\nFound a row: chanid = $ref->{'chanid'}, name = $ref->{'name'}\n"; # search corresponding rows in dvb_channel my $tb_dvb_channel = $dbh->prepare("SELECT * FROM dvb_channel WHERE chanid=" . $ref->{'chanid'}); my $count_dvbchannel = $tb_dvb_channel->execute(); if ($count_dvbchannel >= 1) { # channel already exists in dvb_channel print "Found $count_dvbchannel corresponding row(s) in dvb_channel table\n"; # integrity check: there have to be at least two rows in dvb_pids my $tb_dvb_pids = $dbh->prepare("SELECT * FROM dvb_pids WHERE chanid=" . $re f->{'chanid'}); my $count_dvbpids = $tb_dvb_pids->execute(); if ($count_dvbpids < 2) { print "Warning: Less than 2 dvb_pids not found\n"; } print "Do you want to re-insert? [n]/y:"; my $selection = <>; chomp($selection); if ($selection eq "y" ) { $dofind = 1 ; } $tb_dvb_pids->finish(); } else { # no corresponding row in dvb_channel, so let's insert data print "no corresponding row in dvb_channel, need data, searching channels.conf\n"; $dofind = 1; } if ($dofind) { open (CHANNELSCONF, "cat $channelsconf | grep -i \"" . $ref->{'name'} . "\" |") or die "failed opening channels.conf: $!"; my @channelsconf = <CHANNELSCONF>; close CHANNELSCONF; my $channelsconfrows=$#channelsconf + 1; if ( $channelsconfrows == 0 ) { print "Zero rows found. Do you want to enter a search term? [n]/y:"; my $selection = <>; chomp($selection); if ($selection eq "y" ) { print "Enter search term:"; $selection = <>; chomp($selection); open (CHANNELSCONF, "cat $channelsconf | grep -i \"" . $selection . "\" |") or die "failed opening channels.conf: $!"; @channelsconf = <CHANNELSCONF>; close CHANNELSCONF; $channelsconfrows=$#channelsconf + 1; } } print "found $channelsconfrows matching rows in channels.conf\n"; for (my $i = 1;$i < $channelsconfrows + 1; $i++) { if ( $DEBUG ) { print "$i: $channelsconf[$i-1]" } else { # Print just the name, frequency and ids @channeldata=split(/:/, $channelsconf[$i-1]); print "$i: ", shift @channeldata, "\t:", shift @channeldata; my $sid = pop @channeldata; my $aid = pop @channeldata; my $vid = pop @channeldata; print ":...:$vid:$aid:$sid"; } } print "What to do [number to select, anything else to ignore]? "; my $selection = <>; chomp($selection); #print $selection . "\n"; if ($selection =~ /^\d+$/) { ($DEBUG) && print "using row $selection\n"; # get the information out of the channelsconf row @channeldata=split(/:/, $channelsconf[$selection-1]); %channelhash = (); # Clear previous insert's values $channelhash{'satid'} = 0; # Default of NULL is inappropriate shift @channeldata; # Station-published service name not used if ( $channelsconftype =~ m/zap$/ ) { &parseZAP } elsif ($channelsconftype eq 'vdr') { &parseVDR(@channeldata) } if ( $DEBUG ) { print "fec : $channelhash{'fec'}, ", "fec_lp : $channelhash{'lp_code_rate'}\n"; print "inversion : $channelhash{'inversion'}\n"; print "transmission_mode : $channelhash{'transmission_mode'}\n"; print "guard_interval : $channelhash{'guard_interval'}\n"; print "hierarchy : $channelhash{'hierarchy'}\n"; print "chanid : $ref->{'chanid'}\n"; print "frequency : $channelhash{'frequency'}\n"; print "bandwidth : $channelhash{'bandwidth'}\n"; print "polarity : $channelhash{'polarity'}\n"; print "symbolrate : $channelhash{'symbolrate'}\n"; print "satid : $channelhash{'satid'}\n"; print "modulation : $channelhash{'modulation'}\n"; print "VPID : $channelhash{'vpid'}\n"; print "APID : $channelhash{'apid'}\n"; } if ( $ask_serviceid && ! defined $channelhash{'serviceid'} ) { print "serviceid : "; $channelhash{'serviceid'}=<>; chomp ($channelhash{'serviceid'}); } else { print "serviceid : $channelhash{'serviceid'}\n"; } if ( $ask_transportid && ! defined $channelhash{'transportid'} ) { print "transportid : "; $channelhash{'transportid'}=<>; chomp ($channelhash{'transportid'}); } else { $channelhash{'transportid'} = '0'; print "transportid : $channelhash{'transportid'}\n"; } if ( $ask_networkid && ! defined $channelhash{'networkid'} ) { print "networkid : "; $channelhash{'networkid'}=<>; chomp ($channelhash{'networkid'}); } else { $channelhash{'networkid'} = '0'; print "networkid : $channelhash{'networkid'}\n"; } if ( $ask_providerid && ! defined $channelhash{'providerid'} ) { print "providerid : "; $channelhash{'providerid'}=<>; chomp ($channelhash{'providerid'}); } else { $channelhash{'providerid'} = '0'; print "providerid : $channelhash{'providerid'}\n"; } $doinserts=1; } else { $doinserts=0; } if ($doinserts==1) { # insert1: dvb_channel print "Channel type : $channelsconftype\n"; if ($channelsconftype eq 'szap') { $sql1 = &genChan($ref->{'chanid'}, ('serviceid', 'networkid', 'transportid', 'frequency', 'inversion', 'symbolrate', 'polarity', 'satid', 'modulation') ); } if ($channelsconftype eq 'szap') { $sql1 = &genChan($ref->{'chanid'}, ('serviceid', 'networkid', 'transportid', 'frequency', 'inversion', 'symbolrate', 'polarity', 'satid', 'modulation') ); } if ($channelsconftype eq 'tzap') { $sql1 = &genChan($ref->{'chanid'}, ('serviceid', 'networkid', 'providerid', 'transportid', 'frequency', 'inversion', 'symbolrate', 'fec', 'polarity', 'modulation', 'bandwidth', 'lp_code_rate', 'transmission_mode', 'guard_interval', 'hierarchy') ); } #insert2: vpid my $sql2 = "REPLACE INTO dvb_pids (chanid, pid, type) VALUES (" . $ref->{'chanid'} . ", $channelhash{'vpid'}, \'v\');"; #insert3: apid my $sql3 = "REPLACE INTO dvb_pids (chanid, pid, type) VALUES (" . $ref->{'chanid'} . ", $channelhash{'apid'}, \'a\');"; print "Generated SQL:\n$sql1\n$sql2\n$sql3\n"; if ($simulate) { print "Simulation mode. SQL not done.\n"; } else { $dbh->do($sql1); $dbh->do($sql2); $dbh->do($sql3); print "SQL insert complete.\n"; } } } $tb_dvb_channel->finish(); } $tb_channel->finish(); $dbh->disconnect(); |
Author: | cesman [ Wed Aug 04, 2004 3:19 am ] |
Post subject: | |
Thanks again! Added to the alpha. |
Author: | nigelpearson [ Wed Aug 04, 2004 4:52 am ] |
Post subject: | |
Oops. Just found a mistake in the script. The DVB-C output wasn't there. The first Code: if ($channelsconftype eq 'szap') { should have been$sql1 = &genChan($ref->{'chanid'}, ('serviceid', 'networkid', 'transportid', 'frequency', 'inversion', 'symbolrate', 'polarity', 'satid', 'modulation') ); } Code: if ($channelsconftype eq 'czap') { (I have only tested this with DVB-T)
$sql1 = &genChan($ref->{'chanid'}, ('serviceid', 'networkid', 'transportid', 'frequency', 'inversion', 'symbolrate', 'bandwidth', 'modulation', 'fec') ); } The script isn't foolproof yet, but after some more testing (maybe by KnoppMyth R5 users?) I will ask for it to be added into the contrib directory of mythtv's source tarball. |
Author: | nigelpearson [ Sun Aug 15, 2004 8:08 pm ] |
Post subject: | |
Fix to make it accept the '-t' argument. Change: Code: elsif ( $arg eq '-s' ) to{ $channelsconftype = 'tzap' } Code: elsif ( $arg eq '-t' )
{ $channelsconftype = 'tzap' } Discovered by Dan |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |