diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2004-02-29 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2004-02-29 18:00:00 +0100 |
commit | 5a4eb3f1041b8a53826cebe570f9d201f3d35826 (patch) | |
tree | 4444f7bec812600713430e7f0570dfdd0bf9136e /PLUGINS/src | |
parent | 3fc29659759abb10154b78f9e3568407e523e1fc (diff) | |
download | vdr-patch-lnbsharing-5a4eb3f1041b8a53826cebe570f9d201f3d35826.tar.gz vdr-patch-lnbsharing-5a4eb3f1041b8a53826cebe570f9d201f3d35826.tar.bz2 |
Version 1.3.5vdr-1.3.5
- Fixed reading the EPG preferred language parameter from 'setup.conf'.
- Fixed switching to a visible programme in case the current channel has neither
a video nor an audio PID.
- Fixed editing channels (SID now range checked) and creating new channels (NID,
TID and RID are now set to 0).
- Fixed transponder handling to make it work with satellites that provide two
transponders on the same frequency, with different polarization, like Hispasat
at S30.0W (thanks to Thomas Bergwinkl for pointing this out). See man vdr(5)
for details about the enhanced channel ID format.
- Since there appears to be no general solution for the UPT error yet, a recording
now initiates an "emergency exit" if the number of UPT errors during one
recording exceeds 10 (suggested by Gregoire Favre). Since the UPT error doesn't
happen on my system, this has not been explicitly tested.
The "preliminary fix" for the UPT error in VDR/dvbdevice.c has been disabled
by default, since it makes channel switching unpleasently slow. If you want
to have that workaround back, you can uncomment the line
//#define WAIT_FOR_LOCK_AFTER_TUNING 1
in VDR/dvbdevice.c.
- Adapted the 'sky' plugin to use the actual channel IDs, and to fetch EPG data
from www.bleb.org.
- Limited automatic retuning to devices that actually provide the transponder
(necessary for the 'sky' plugin).
- Fixed handling receivers in the 'sky' plugin, so that a recording on the same
channel won't interrupt an ongoing Transfer Mode.
- Added subtable ID and TSDT handling to 'libsi' (thanks to Marcel Wiesweg).
- Fixed some Russian OSD texts (thanks to Vyacheslav Dikonov).
- Added the 'running status' to the EPG events. This is necessary for implementing
the VPS function for recording.
- Removed the obsolete 'present' and 'following' handling from the EPG data.
- The EPG data is now always kept sorted chronologically in the internal data
structures. This also means that any EPG data retrieved through the SVRDP
command LSTE is guaranteed to be sorted by start time.
- Now using the 'running status' in the channel display, so that a programme
that has an end time that is before the current time, but is still running,
will still be shown in the display (provided the broadcasters handle the
'running status' flag correctly). This also applies to programmes that have
a start time that is in the future, but are already running.
- Implemented an "EPG linger time", which can be set to have older EPG information
still displayed in the "Schedule" menu (thanks to Jaakko Hyvätti).
- Added PDCDescriptor handling to 'libsi'.
- Implemented handling the VPS timestamps (aka "Programme Identification Label")
for full VPS support for timers (provided the tv stations actually broadcast
this information). The VPS time is displayed in the event info page if it exists
and is different than the event's start time.
- Extended the SVDRP command LSTE to allow limiting the listed data to a given
channel, the present or following events, or events at a given time (thanks to
Thomas Heiligenmann).
- Fixed a typo in libsi/si.h (thanks to Stéphane Esté-Gracias).
- Timers can now be set to use the VPS information to control recording a programme.
The new setup options "Recording/Use VPS" and "Recording/VPS margin", as well as
the "VPS" option in the individual timers, can be used to control this feature
(see MANUAL for details).
Note that this feature will certainly need a lot of testing before it can be
called "safe"!
- The "Schedule" and "What's on now/next?" menus now have an additional column
which displays information on whether there is a timer defined for an event,
whether an event has a VPS time that's different than its start time, and
whether an event is currently running (see MANUAL under "The "Schedule" Menu"
for details).
Diffstat (limited to 'PLUGINS/src')
-rw-r--r-- | PLUGINS/src/sky/HISTORY | 8 | ||||
-rw-r--r-- | PLUGINS/src/sky/README | 29 | ||||
-rw-r--r-- | PLUGINS/src/sky/channels.conf.sky | 38 | ||||
-rwxr-xr-x | PLUGINS/src/sky/getskyepg.pl | 136 | ||||
-rw-r--r-- | PLUGINS/src/sky/sky.c | 96 |
5 files changed, 221 insertions, 86 deletions
diff --git a/PLUGINS/src/sky/HISTORY b/PLUGINS/src/sky/HISTORY index d3da71e..c1c5f98 100644 --- a/PLUGINS/src/sky/HISTORY +++ b/PLUGINS/src/sky/HISTORY @@ -16,3 +16,11 @@ VDR Plugin 'sky' Revision History 2004-01-04: Version 0.2.0 - Implemented automatic PID switching and channel detection + +2004-02-15: Version 0.3.0 + +- Now using the actual channel IDs a derived from the data stream. +- Switched EPG data retrieval to http://www.bleb.org. +- Added automatic DST detection to getskyepg.pl. +- Fixed handling receivers, so that a recording on the same channel + won't interrupt an ongoing Transfer mode. diff --git a/PLUGINS/src/sky/README b/PLUGINS/src/sky/README index bd089cc..185a98b 100644 --- a/PLUGINS/src/sky/README +++ b/PLUGINS/src/sky/README @@ -28,23 +28,18 @@ control the Digibox. In order to access the Sky channels VDR needs to know the channel number under which each channel is stored in the Sky Digibox. These numbers are -used as 'frequency' parameters in the channels.conf definitions of the Sky -channels (see the file 'channels.conf.sky'). Since these numbers are always -less than 1000, they can be easily distinguished from normal satellite -transponder frequencies. The VPID is 160 and the APID is 80 for all Sky -channels. These are just fake PIDs, since the Kfir card always uses these -fixed PIDs. The 'Ca' parameter of the Sky channels is set to 301, which -is defined as "Videoguard, Sky Digital" in VDR's 'ca.conf' file. Again, please -note that VDR doesn't do any decrypting here, this is just to mark these -channels as "conditionally accessible" and have a way of setting the CICAM -value for the Kfir device in VDR's Setup menu. - -The Sky EPG is available on the Internet at http://www.ananova.com. +stored in the file 'channels.conf.sky', together with the channel IDs as +derived from the actual channel data and the names under which the EPG +data for each channel can be found (see below). Copy this file to your +plugins config directory, in a subdirectory named 'sky', as in + +/video/plugins/sky/channels.conf.sky + +The Sky EPG is available on the Internet at http://www.bleb.org. The Perl script getskyepg.pl extracts the EPG data from these pages -and sends it to VDR via an SVDRP connection. The channel numbers Sky -uses to generate the EPG pages are stored as the 'sid' parameter in -the channels.conf definitions of the Sky channels. You can keep your -EPG data up-to-date by entering a call to getskyepg.pl into your -/etc/crontab. Call 'getskyepg.pl -h' for a list of options. +and sends it to VDR via an SVDRP connection. The channel names as +used on the bleb.org pages are defined in the channels.conf.sky file. +You can keep your EPG data up-to-date by entering a call to getskyepg.pl +into your /etc/crontab. Call 'getskyepg.pl -h' for a list of options. The getskyepg.pl script requires the programs /usr/bin/wget and /usr/bin/logger to be installed on your system. diff --git a/PLUGINS/src/sky/channels.conf.sky b/PLUGINS/src/sky/channels.conf.sky index f4a437b..ba262f8 100644 --- a/PLUGINS/src/sky/channels.conf.sky +++ b/PLUGINS/src/sky/channels.conf.sky @@ -1,4 +1,34 @@ -Sky One:106:h:S28.2E:0:160:80:0:301:222 -itv2:226:h:S28.2E:0:160:80:0:301:451 -sci-fi:130:h:S28.2E:0:160:80:0:301:161 -Paramount Comedy:127:h:S28.2E:0:160:80:0:301:185 +# Sky channel definitions +# +# Syntax: +# +# ChannelID:ChannelNumber:EPGname +# +# where +# +# ChannelID is the channel ID as derived from the actual channel +# data as broadcast in the data stream (see man vdr(5)). +# +# ChannelNumber is the number of this channel as you have to +# enter it on the DigiBox remote control. +# +# EPGname is the name of the page at www.bleb.org that has EPG +# data for this channel (without the '.xml'). If no such +# page exists, 'x' is entered. +# +S28.2E-2-2027-4705:106:sky_one +S28.2E-2-2027-5104:107:sky_one_mix +S28.2E-2-2054-10240:226:itv2 +S28.2E-2-2023-4905:130:scifi +S28.2E-2-2025-5904:127:paramount +S28.2E-2-2009-6201:551:discovery +S28.2E-2-2020-4809:310:sky_cinema +S28.2E-2-2007-4303:301:sky_movies1 +S28.2E-2-2007-4302:302:sky_movies2 +S28.2E-2-2007-4403:303:sky_movies3 +S28.2E-2-2011-4402:304:sky_movies4 +S28.2E-2-2011-4503:305:sky_movies5 +S28.2E-2-2011-4502:306:sky_movies6 +S28.2E-2-2020-4603:307:sky_movies7 +S28.2E-2-2007-5502:308:sky_movies8 +S28.2E-2-2020-4602:309:x diff --git a/PLUGINS/src/sky/getskyepg.pl b/PLUGINS/src/sky/getskyepg.pl index 46c2d7f..77768ad 100755 --- a/PLUGINS/src/sky/getskyepg.pl +++ b/PLUGINS/src/sky/getskyepg.pl @@ -1,14 +1,14 @@ #!/usr/bin/perl -# getskyepg.pl: Get EPG data from Sky's web pages +# getskyepg.pl: Get EPG data for Sky channels from the Internet # # Connects to a running VDR instance via SVDRP, gets the channel data -# for the Sky channels and connects to Sky's web pages to extract the +# for the Sky channels and connects to Internet web pages to extract the # EPG data for these channels. The result is sent to VDR via SVDRP. # # See the README file for copyright information and how to reach the author. # -# $Id: getskyepg.pl 1.2 2003/04/02 16:21:47 kls Exp $ +# $Id: getskyepg.pl 1.3 2004/02/15 13:35:52 kls Exp $ use Getopt::Std; use Time::Local; @@ -16,31 +16,33 @@ use Time::Local; $Usage = qq{ Usage: $0 [options] -Options: -d hostname destination hostname (default: localhost) +Options: -c filename channel config file name (default: channels.conf.sky) + -d hostname destination hostname (default: localhost) -p port SVDRP port number (default: 2001) -S source channel source (default: S28.2E) -D days days to get EPG for (1..7, default: 2) }; -die $Usage if (!getopts("d:D:hp:S:") || $opt_h); +die $Usage if (!getopts("c:d:D:hp:S:") || $opt_h); +$Conf = $opt_c || "channels.conf.sky"; $Dest = $opt_d || "localhost"; $Port = $opt_p || 2001; $Source = $opt_S || "S28.2E"; $Days = $opt_D || 2; -$SkyWebPage = "www.ananova.com/tv/frontpage.html"; +$SkyWebPage = "www.bleb.org/tv/data/listings"; $WGET = "/usr/bin/wget -q -O-"; $LOGGER = "/usr/bin/logger -t SKYEPG"; -$DST = -3600; ##XXX TODO find out whether DST is active! +$DST = -3600; # Daylight Saving Time offset $SecsInDay = 86400; -$MaxFrequency = 1000; -$idxName = 0; -$idxFrequency = 1; -$idxSource = 3; -$idxSid = 9; +@Channels = (); + +$idxSource = 0; +$idxNumber = 1; +$idxName = 2; Error("days out of range: $Days") unless (1 <= $Days && $Days <= 7); @@ -57,34 +59,52 @@ sub Error sub GetChannels { - SVDRPsend("LSTC"); - my @channels = (); - for (SVDRPreceive(250)) { - my @a = split(':', substr($_, 4)); - if ($a[$idxSource] eq $Source && $a[$idxFrequency] < $MaxFrequency) { - push(@channels, [@a]); - } - } - return @channels; + open(CHANNELS, $Conf) || Error("$Conf: $!"); + while (<CHANNELS>) { + chomp; + next if (/^#/); + my @a = split(":"); + push(@Channels, [@a]) unless ($a[$idxName] eq "x"); + } + close(CHANNELS); } +GetChannels(); + sub GetPage { my $channel = shift; my $day = shift; - my $url = "$SkyWebPage?c=$channel&day=day$day"; + $day--; + my $url = "$SkyWebPage/$day/$channel.xml"; Log("reading $url"); my @page = split("\n", `$WGET '$url'`); Log("received " . ($#page + 1) . " lines"); return @page; } +sub StripWhitespace +{ + my $s = shift; + $s =~ s/\s*(.*)\s*/$1/; + $s =~ s/\s+/ /g; + return $s; +} + +sub Extract +{ + my $s = shift; + my $t = shift; + $s =~ /<$t>([^<]*)<\/$t>/; + return StripWhitespace($1); +} + # In order to get the duration we need to buffer the last event: $Id = ""; $Time = 0; $Title = ""; -$Episode = ""; -$Descr = ""; +$Subtitle = ""; +$Desc = ""; sub GetEpgData { @@ -94,40 +114,64 @@ sub GetEpgData $Time = 0; for $day (1 .. $Days) { my $dt = 0; - my $ap = ""; my @page = GetPage($channel, $day); + my $data = ""; for $line (@page) { - if ($line =~ /^<\/tr><tr /) { - # extract information: - my ($time, $title, $episode, $descr) = ($line =~ /^.*?<b>(.*?)<\/b>.*?<b>(.*?)<\/b> *(<i>.*?<\/i>)? *(.*?) *<\/small>/); - my ($h, $m, $a) = ($time =~ /([0-9]+)\.([0-9]+)(.)m/); - # handle am/pm: - $dt = $SecsInDay if ($ap eq "p" && $a eq "a"); - $ap = $a; - $h += 12 if ($a eq "p" && $h < 12); - $h -= 12 if ($a eq "a" && $h == 12); + chomp($line); + if ($line =~ /<programme>/) { + $data = ""; + } + elsif ($line =~ /<\/programme>/) { + my $title = Extract($data, "title"); + my $subtitle = Extract($data, "subtitle"); + my $desc = Extract($data, "desc"); + my $start = Extract($data, "start"); + # 'end' is useless, because it is sometimes missing :-( + # my $end = Extract($data, "end"); + if (!$subtitle) { + # They sometimes write all info into the description, as in + # Episode: some description. + # Why don't they just fill in the data correctly? + my ($s, $d) = ($desc =~ /([^:]*)[:](.*)/); + if ($s && $d) { + $subtitle = $s; + $desc = $d; + } + } + # 'start' and 'end' as time of day isn't of much use here, since + # the page for one day contains data that actually belongs to the + # next day (after midnight). Oh well, lets reconstruct the missing + # information: + $start = "0" . $start if (length($start) < 4); + my ($h, $m) = ($start =~ /(..)(..)/); + $dt = $SecsInDay if ($h > 12); # convert to time_t: my @gmt = gmtime; $gmt[0] = 0; # seconds $gmt[1] = $m; # minutes $gmt[2] = $h; # hours - $time = timegm(@gmt) + ($day - 1) * $SecsInDay + $dt + $DST; + $time = timegm(@gmt) + ($day - 1) * $SecsInDay + ($h < 12 ? $dt : 0); + # comensate for DST: + $time += $DST if (localtime($time))[8]; # create EPG data: if ($Time) { $duration = $time - $Time; SVDRPsend("E $Id $Time $duration"); SVDRPsend("T $Title"); - SVDRPsend("S $Episode"); - SVDRPsend("D $Descr"); + SVDRPsend("S $Subtitle"); + SVDRPsend("D $Desc"); SVDRPsend("e"); $numEvents++; } # buffer the last event: $Id = $time / 60 % 0xFFFF; # this gives us unique ids for every minute of over 6 weeks $Time = $time; - ($Title = $title) =~ s/<[^>]+>//g; - ($Episode = $episode) =~ s/<[^>]+>//g; - ($Descr = $descr) =~ s/<[^>]+>//g; + $Title = $title; + $Subtitle = $subtitle; + $Desc = $desc; + } + else { + $data .= $line; } } } @@ -137,14 +181,10 @@ sub GetEpgData sub ProcessEpg { - Log("getting Sky channel definitions"); - my @channels = GetChannels(); - Error("no Sky channels found") unless @channels; - Log("found " . ($#channels + 1) . " channels"); - for (@channels) { - my $channel = @$_[$idxSid]; - my $channelID = "@$_[$idxSource]-0-@$_[$idxFrequency]-$channel"; - Log("processing channel @$_[0]"); + for (@Channels) { + my $channel = @$_[$idxName]; + my $channelID = @$_[$idxSource]; + Log("processing channel $channel - $channelID"); SVDRPsend("PUTE"); SVDRPreceive(354); GetEpgData($channel, $channelID); diff --git a/PLUGINS/src/sky/sky.c b/PLUGINS/src/sky/sky.c index 750d778..6196eef 100644 --- a/PLUGINS/src/sky/sky.c +++ b/PLUGINS/src/sky/sky.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: sky.c 1.4 2004/01/04 15:29:15 kls Exp $ + * $Id: sky.c 1.6 2004/02/15 14:59:46 kls Exp $ */ #include <sys/socket.h> @@ -14,16 +14,53 @@ #include <vdr/plugin.h> #include <vdr/sources.h> -static const char *VERSION = "0.2.0"; +static const char *VERSION = "0.3.0"; static const char *DESCRIPTION = "Sky Digibox interface"; // --- cDigiboxDevice -------------------------------------------------------- +#define DUMMYAPID 80 +#define DUMMYVPID 160 + +class cSkyChannel : public cListObject { +public: + tChannelID channelID; + int digiboxChannelNumber; + bool Parse(const char *s); + }; + +bool cSkyChannel::Parse(const char *s) +{ + char *id = NULL; + if (2 == sscanf(s, "%a[^:]:%d", &id, &digiboxChannelNumber)) + channelID = tChannelID::FromString(id); + free(id); + return digiboxChannelNumber && channelID.Valid(); +} + +class cSkyChannels : public cConfig<cSkyChannel> { +public: + cSkyChannel *GetSkyChannel(const cChannel *Channel); + }; + +cSkyChannel *cSkyChannels::GetSkyChannel(const cChannel *Channel) +{ + tChannelID ChannelID = Channel->GetChannelID(); + for (cSkyChannel *sc = First(); sc; sc = Next(sc)) { + if (ChannelID == sc->channelID) + return sc; + } + return NULL; +} + +cSkyChannels SkyChannels; + class cDigiboxDevice : public cDevice { private: int source; int digiboxChannelNumber; int fd_dvr; + int apid, vpid; cTSBuffer *tsBuffer; int fd_lirc; void LircSend(const char *s); @@ -47,6 +84,7 @@ cDigiboxDevice::cDigiboxDevice(void) source = cSource::FromString("S28.2E");//XXX parameter??? digiboxChannelNumber = 0; fd_dvr = -1; + apid = vpid = 0; struct sockaddr_un addr; addr.sun_family = AF_UNIX; strn0cpy(addr.sun_path, "/dev/lircd", sizeof(addr.sun_path));//XXX parameter??? @@ -93,7 +131,7 @@ void cDigiboxDevice::LircSend(int n) bool cDigiboxDevice::SetPid(cPidHandle *Handle, int Type, bool On) { - dsyslog("SetPid %d %d", Handle->pid, On); + //dsyslog("SetPid %d %d", Handle->pid, On); return true; } @@ -122,6 +160,16 @@ bool cDigiboxDevice::GetTSPacket(uchar *&Data) int r = tsBuffer->Read(); if (r >= 0) { Data = tsBuffer->Get(); + if (Data) { + // insert the actual PIDs: + int Pid = (((uint16_t)Data[1] & PID_MASK_HI) << 8) | Data[2]; + if (Pid == DUMMYAPID) + Pid = apid; + else if (Pid == DUMMYVPID) + Pid = vpid; + Data[1] = ((Pid >> 8) & 0xFF) | (Data[1] & ~PID_MASK_HI); + Data[2] = Pid & 0xFF; + } return true; } else if (FATALERRNO) { @@ -149,9 +197,10 @@ bool cDigiboxDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool bool hasPriority = Priority < 0 || Priority > this->Priority(); bool needsDetachReceivers = true; - if (ProvidesSource(Channel->Source()) && Channel->Ca() == 0x30) {//XXX - if (Receiving()) { - if (digiboxChannelNumber == Channel->Frequency()) { + cSkyChannel *SkyChannel = SkyChannels.GetSkyChannel(Channel); + if (SkyChannel) { + if (Receiving(true)) { + if (digiboxChannelNumber == SkyChannel->digiboxChannelNumber) { needsDetachReceivers = false; result = true; } @@ -168,16 +217,21 @@ bool cDigiboxDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool bool cDigiboxDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { - if (fd_lirc >= 0 && !Receiving()) { // if we are receiving the channel is already set! - digiboxChannelNumber = Channel->Frequency(); - //XXX only when recording??? -> faster channel switching! - LircSend("SKY"); // makes sure the Digibox is "on" - //XXX lircprint(fd_lirc, "BACKUP"); - //XXX lircprint(fd_lirc, "BACKUP"); - //XXX lircprint(fd_lirc, "BACKUP"); - LircSend(digiboxChannelNumber); + if (fd_lirc >= 0 && !Receiving(true)) { // if we are receiving the channel is already set! + cSkyChannel *SkyChannel = SkyChannels.GetSkyChannel(Channel); + if (SkyChannel) { + digiboxChannelNumber = SkyChannel->digiboxChannelNumber; + apid = Channel->Apid1(); + vpid = Channel->Vpid(); + //XXX only when recording??? -> faster channel switching! + LircSend("SKY"); // makes sure the Digibox is "on" + //XXX lircprint(fd_lirc, "BACKUP"); + //XXX lircprint(fd_lirc, "BACKUP"); + //XXX lircprint(fd_lirc, "BACKUP"); + LircSend(digiboxChannelNumber); + } } -return true; + return true; } // --- cPluginSky ------------------------------------------------------------ @@ -225,8 +279,16 @@ bool cPluginSky::ProcessArgs(int argc, char *argv[]) bool cPluginSky::Initialize(void) { // Initialize any background activities the plugin shall perform. - new cDigiboxDevice; - return true; + const char *ConfigDir = ConfigDirectory(Name()); + if (ConfigDir) { + if (SkyChannels.Load(AddDirectory(ConfigDir, "channels.conf.sky"), true)) { + new cDigiboxDevice; + return true; + } + } + else + esyslog("ERROR: can't get config directory"); + return false; } void cPluginSky::Housekeeping(void) |