CoolRaoul Posté(e) le 28 août 2013 Auteur Partager Posté(e) le 28 août 2013 Lien envoyé par MP. Merci pour ton aide Lien vers script modifié envoyé en MP aussi On continue les echanges en MP pour tester si c'est OK et une fois confirmé je diffuse cette version. 1 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
aj13fr Posté(e) le 29 août 2013 Partager Posté(e) le 29 août 2013 (modifié) Merci à CoolRaoul pour son nouveau script pour les possesseur de HdHomerun. Ca marche impec. Je lui laisse le soin de diffuser celui-ci. Attention, le HdHomerun possédant 2 tuners, verifier le nom des fichiers de configuration des chaines (0channels.conf et 1channels.conf normalement) et lancer le script pour chaque tuner afin que l'EPG apparaisse pour chacun d'eux. Je laisse CoolRaoul vous dire (comme à moi) comment faire pour cela, je préfère qu'il n'y ait qu'un seul interlocuteur pour cela. Encore Merci ! Modifié le 29 août 2013 par aj13fr 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
CoolRaoul Posté(e) le 29 août 2013 Auteur Partager Posté(e) le 29 août 2013 Je vais essayer de diffuser au plus tot, le 1er post du fil sera mis a jour et j'ajouterai les infos complémentaires ici. 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
CoolRaoul Posté(e) le 30 août 2013 Auteur Partager Posté(e) le 30 août 2013 (modifié) Lien vers la dernière version ajouté à la fin du 1er post du fil. Note: je rappelle qu'il est possible de spécifier où se trouve channels.conf sans modifier le script. Suffit de donner si nécessaire ce chemin en paramètre lors de l'appel, comme cela: xml2epg.pl -C <chemin du fichier channels.conf> <url du xml tv> De façon similaire, le chemin du répertoire EPG est aussi parametrable, switch "-d": xml2epg.pl -C <chemin du fichier channels.conf> -d <dossier EPG> <url du xml tv> Modifié le 30 août 2013 par CoolRaoul 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
philou42 Posté(e) le 8 septembre 2013 Partager Posté(e) le 8 septembre 2013 (modifié) Merci CoolRAoul pour ton script et ce super Tuto, J'ai passé mon samedi apm à mettre en place la programmation journalière de la récupération de l'EPG pour un synology DS209 et Dsm 4.2. Tout semble bien fonctionner excepté les chaines avec des noms comportant des caractères accentués dans le fichier xml. (France Ô, La chaîne Parlementaire, ....) J'ai beau essayer de modifier le fichier xml2epg.conf avec divers éditeurs sous Windows ou même directement sur le Synology avec l'editeur Nano rien n'y fait... Modifié le 8 septembre 2013 par philou42 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
CoolRaoul Posté(e) le 8 septembre 2013 Auteur Partager Posté(e) le 8 septembre 2013 J'ai beau essayer de modifier le fichier xml2epg.conf avec divers éditeurs sous Windows ou même directement sur le Synology avec l'editeur Nano rien n'y fait... Pour les accents, le fichier doit être encodé en UTF8. Sous Windows, je te conseille d'utiliser Notepad++ configuré comme ceci: 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
philou42 Posté(e) le 9 septembre 2013 Partager Posté(e) le 9 septembre 2013 Sous Windows, je te conseille d'utiliser Notepad++ configuré comme ceci: Nickel ! Merci à toi. 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Dirac Posté(e) le 10 septembre 2013 Partager Posté(e) le 10 septembre 2013 Merci coolraoul pour tes scripts ! Cela fait quasiment un an qu'ils sont install 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
CoolRaoul Posté(e) le 12 mai 2014 Auteur Partager Posté(e) le 12 mai 2014 (modifié) xmltv.dyndns.org est mort et remplacé par http://www.kazer.org/ Une petite modif dans le format des fichiers epg a necessité une correction du script. A récupérer dans le premier post du fil. Modifié le 4 juin 2014 par CoolRaoul 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Dirac Posté(e) le 4 juin 2014 Partager Posté(e) le 4 juin 2014 Merci pour ces informations de mise 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
JPR Posté(e) le 23 juillet 2016 Partager Posté(e) le 23 juillet 2016 (modifié) Bonjour, Je viens de tomber sur ce post. Est-ce que ce script est toujours d'actualité ? Pour l'instant j'utilise DVBLink sur un DS415Play avec un HDHomeRun. J'ai choisi DVBLink car il gère l'import XMLTV de mon compte Kazer.org mais je ne dirais pas non à un retour vers Video Station ... avec prise en charge du XMLTV of course Cordialement - Jean-Paul Modifié le 23 juillet 2016 par JPR 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
delianmc Posté(e) le 12 avril 2017 Partager Posté(e) le 12 avril 2017 Bonjour, J'utilise https://www.xmltvlistings.com/ pour obtenir mon xmltv et j'habite au Canada. Je ne sais pas pour l'Europe mais ici (ATSC) le sevice ID n'est pas unique ce qui fait que le script ne mappais pas convenablement le contenu du XML aux fichiers epg. J'ai donc du l'adapter pour utiliser un unique id à la place. Cette version devrait fonctionner dans tous les scénario. Désolé si le code n'utilise pas les best practice j'ai du faire un "crash course" sur perl en une soirée... Voici la version modifié: #! /usr/bin/perl # # # $Id: xml2epg.pl,v 2.14 2014/05/12 07:50:57 root Exp $ # $ENV{PATH} = "/usr/syno/bin:/usr/syno/sbin:/bin:/sbin:/usr/bin:/usr/sbin"; use strict; use warnings; use File::Basename; use File::Temp qw/ tempfile /; use Time::Local; use Getopt::Long; use POSIX qw(locale_h); use IO::File; my $progname=basename($0); #+ # use utf8 for terminal output if env specifies utf8 #- if (setlocale(LC_CTYPE) =~ /utf8/) { binmode STDOUT, ":encoding(UTF-8)"; binmode STDERR, ":encoding(UTF-8)"; } #+ # ALL FileIO is utf8 #- use open ':encoding(utf8)'; my $debug=0; my $quiet=0; my $progress=0; my $notafter; my $vsdir_path = "/usr/syno/etc/packages/VideoStation"; # default EPG directory my $epgdir_path; for my $d (qw (EPGs/0EPG EPG)) { $epgdir_path = "$vsdir_path/$d"; last if -d $epgdir_path; } # default channels.conf path my $channels_conf_path; for my $c (qw (channels/0channels.conf channels.conf)) { $channels_conf_path = "$vsdir_path/$c"; last if -r $channels_conf_path; } my $myconf_path = "/usr/local/etc/xml2epg.conf"; my $now = time(); sub info { print STDERR "$progname: @_.\n" unless $quiet; } sub debug { my $level=shift; print STDERR "DEBUG: @_\n" if $debug >= $level; } #+ # format "YYYYMMDDhhmmss[ <utc offset>] string to binary time #- sub str2time { my $string=shift; my ( $year, $mon, $mday, $hour, $min, $sec, $sign_off, $hr_off, $min_off) = ($string =~ /^ (\d{4}) (\d{2}) (\d{2}) (\d{2}) (\d{2}) (\d{2}) \s* (?:([+-])?(\d{2})(\d{2}))?$/x); if (defined $hr_off) { # time is "UTC <offset>" my $offset = ($hr_off * 60 + $min_off) * 60; # seconds $offset = - $offset if $sign_off eq "-"; return timegm($sec, $min, $hour, $mday, $mon-1, $year) - $offset; } else { # time is local return timelocal($sec, $min, $hour, $mday, $mon-1, $year) ; } } #================================================================================ sub usage { my $status=shift; print STDERR <<EOF; Arguments: --debug|-D --quiet|-q --progress|-p --epgdir|-d <epg output directory> --conf|-s <config file path> --chanconf|-C <channels.conf path> EOF exit $status; } #+ # command switches #- my $help; Getopt::Long::Configure ("bundling"); GetOptions ( 'debug|D+' => \$debug, 'quiet|q+' => \$quiet, 'epgdir|d=s' => \$epgdir_path, 'progress|p' => \$progress, 'conf|c=s' => \$myconf_path, 'chanconf|C=s' => \$channels_conf_path, 'maxdays|m=s' => sub {$notafter = $now + ($_[1] * 60 * 60 * 24)}, 'help|?' => \$help, ) or usage(1); usage(0) if $help; my $arg = shift or do { info "missing argument"; usage(1); }; -d $epgdir_path or do { info "invalid dir $epgdir_path ($!)"; exit(1); }; sub quote { my $string = shift; $string =~ s/"/\\"/g; return "\"" . $string . "\""; } my %xml2confchname = (); #+ # parse my conf #- { info ("parsing $myconf_path"); open my $myconf_h, "<", "$myconf_path" or die "$! opening $myconf_path\n"; while (<$myconf_h>) { s/#.*$//; # uncomment; next if /^\s*$/; # skip blank lines; my ($verb, $text) = /^\s*(\S*)\s+(.*\S)\s*$/; defined($verb) or do { info "$myconf_path:$.:syntax error"; exit(1); } ; if ($verb eq "defname") { # trailing spaces have already been suppressed my ($xmlname, $confname) = ($text =~ /^(\S+)\s+(.*)$/); die "syntax error:\n$_" unless defined $xmlname && defined $confname; $xml2confchname{lc $xmlname} = $confname; debug(1,"mapping \"$xmlname\" -> \"^$confname.*\"") } else { die "unknown $verb : $verb\n"; } } info ("done"); } my %chan_conf_name2sid = (); my %sid2suffix = (); my %uniqueid = (); #+ # parse_channel_conf #- { my $chaconf_h = new IO::File; info ("parsing $channels_conf_path"); open $chaconf_h, "<", $channels_conf_path or die "$! opening $channels_conf_path\n"; my $prefix; $chaconf_h->read ($prefix,2) == 2 or die "$! reading prefix\n"; $chaconf_h->seek(0,0); # rewind my $chname; my $sid; my $suffix; if ( $prefix eq '[{') { # hdhomerun format my $chaconf_s = $chaconf_h->getline(); while ($chaconf_s =~ /{(.*?)}/g) { # sample chaconf_s: "frequency":778000000,"service_id":513,"title":"D8" foreach (split /,/, $1) { my ($name, $value) = /^"?(.*?)"?:"?(.*?)"?$/; $chname = $value if $name eq "title"; $suffix = $value if $name eq "frequency"; $sid = $value if $name eq "service_id"; } debug(1, "SID=$sid, NAME=$chname, SUFFIX= $suffix"); $chan_conf_name2sid{$chname} = $sid; $uniqueid{$chname} = $sid . "@" . $suffix; $sid2suffix{$sid} = $suffix; } } else { while (<$chaconf_h>) { next unless /:/; s/\s*$//; # remove trailing cr nl and spacing my @fields = split(/:/); $chname=$fields[0]; $sid=$fields[-1]; $suffix=$fields[1]; $chan_conf_name2sid{$chname} = $sid; $uniqueid{$chname} = $sid . "@" . $suffix; $sid2suffix{$sid} = $suffix; debug(1, "SID=$sid, NAME=$chname, SUFFIX= $suffix"); } } info ("done"); } #+ # arg can be "http://<file>" | "file.zip" | "file.xml" #- my $xmlfile; if ($arg =~ /^http/) { my $zipfile; (undef , $zipfile) = tempfile(DIR => "/tmp", TEMPLATE => "epg-XXXXXX", SUFFIX => ".zip" , UNLINK => 1); info "fetching $arg"; die "wget error\n" if system("wget -nv -O $zipfile $arg") > 0; $arg = $zipfile; info "fetched"; } if ($arg =~ /.zip$/) { (undef , $xmlfile) = tempfile(DIR => "/tmp", TEMPLATE => "epg-XXXXXX", SUFFIX => ".xml", UNLINK => 1); info "unzipping $arg"; die "unzip error\n" if system("unzip -p $arg > $xmlfile") > 0; info "unzipped"; } else { $xmlfile = $arg; } ### Poor man XML parse info ("parsing XMLTV file"); open my $xml_h, "<", $xmlfile or die "$! opening $xmlfile\n"; my $channel_id; my $cur_chaname; # display name my $curprog; # current TV program struct (ref to hash) my %progs = (); # $progs{<channel_id>} : ref to array of "progs" my %id2name = (); while (<$xml_h>) { if (/<channel id="([^"]*?)">/) { # if (/<channel id="(.*)">/) { $channel_id=$1; next; } if (/<display-name>(.*)<\/display-name>/) { $id2name{$channel_id} = $1; next; } if (/^\s+<(title|desc|sub-title).*?>(.*)<\/\1/) { $curprog->{$1} = $2; next; } if (my ($start_s, $stop_s, $chan) = (/^ \s*<programme\s+start="(.*?)".* \s+stop="(.*?)".* \s+channel="(.*?)"/x )) { my $start=str2time($start_s); my $stop=str2time($stop_s); $cur_chaname = $id2name{$chan}; $curprog = { duration => ($stop - $start) , start_time => $start, text_name => "", }; next; } if (/^\s+<\/programme>/) { print STDERR "." if $progress; my $start_time = $curprog->{start_time}; my $duration = $curprog->{duration}; next if ($start_time + $duration < $now); # too late next if (defined($notafter) && ($start_time > $notafter)); push @{$progs{$cur_chaname}}, $curprog ; } } if ($debug) { foreach (keys %id2name) { debug (1,"XMLNAME $_ -> $id2name{$_}"); } } print STDERR "\n" if $progress; info ("parsed"); chdir $epgdir_path or die "chdir $epgdir_path, $!\n"; #+ # in: channel_name (from xml) # out: unique service ids array #- my %ignoring=(); sub cha2uid { my $xml_chaname = shift; my @uids = (); return @uids if ($ignoring{$xml_chaname}); my $squeezed_xml_chaname = $xml_chaname; $squeezed_xml_chaname =~ s/\s//g; # remove spacing #my ($xmlname, $confname) = ($text =~ /^(\S+)\s+(.*)$/); my $vs_chaname_prefix=$xml2confchname{lc($squeezed_xml_chaname)}; if (! defined($vs_chaname_prefix)) { info("mapping for channel $xml_chaname not found!"); info("add \"defname $squeezed_xml_chaname <channel.conf name>\" in config file"); info ("ignoring \"$xml_chaname\""); $ignoring{$xml_chaname}++; return @uids; } else { debug(1, "xml_chaname=$xml_chaname, squeezed_xml_chaname=$squeezed_xml_chaname, vs_chaname_prefix=$vs_chaname_prefix") } foreach my $vs_chaname (keys %chan_conf_name2sid) { if ($vs_chaname =~ /^$vs_chaname_prefix/i) { debug(2, "vs_chaname=$vs_chaname, vs_chaname_prefix=$vs_chaname_prefix, chan_conf_name2sid=$chan_conf_name2sid{$vs_chaname}"); push @uids, $uniqueid{$vs_chaname} } } debug(1,"uids for $xml_chaname: @uids"); return @uids; } foreach my $chaname (keys %progs) { my @sidlist = cha2uid($chaname); foreach my $uid ( @sidlist) { #my $unique_id= $sid . "@" . $sid2suffix{$sid}; my $unique_id=$uid; my $epgfile="epg." . $unique_id; info "creating $epgfile ($chaname)"; unlink $epgfile; open my $epg_h, ">", "$epgfile" or die "$! opening $epgfile\n"; $epg_h->print("{\n"); $epg_h->print(" \"eventdata\" : [\n"); my $eventid=1; my @proglist = sort {$a->{start_time} <=> $b->{start_time}} @{$progs{$chaname}} ; my $lastprog = $proglist[-1]; foreach my $prog (@proglist) { my $event_name = $prog->{title}; $event_name .= " - " . $prog->{"sub-title"} if exists $prog->{"sub-title"}; # remplacer les virgules par des espaces dans le titre $event_name =~ s/,/ /g; my $text_name = exists($prog->{desc}) ? $prog->{desc} : ""; my $islatest = $prog == $lastprog ; debug (2, sprintf ("Chan=%s, id=%s, event=%s",$chaname,$uid, $event_name)); $event_name .= " - " . $prog->{subtitle} if exists $prog->{subtitle}; $epg_h->print(" {\n"); $epg_h->print(" \"duration\" : ", $prog->{duration}, ",\n"); $epg_h->print(" \"event_id\" : ", $eventid++, ",\n"); $epg_h->print(" \"event_name\" : ", quote($event_name), ",\n"); $epg_h->print(" \"finalprogram\" : ", ( $islatest ? "true" : "false") , ",\n"); $epg_h->print(" \"start_time\" : ", $prog->{start_time}, ",\n"); $epg_h->print(" \"text_name\" : ", quote($text_name), "\n"); $epg_h->print(" }", ($islatest ? "" : ",") , "\n"); } $epg_h->print(" ],\n"); $epg_h->print(" \"unique_id\" : \"", $unique_id, "\"\n"); $epg_h->print("}\n"); $epg_h->close(); } } 1; # Local Variables: # mode: cperl # cperl-indent-level: 4 # End: J'espère qu'elle vous sera utile. 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Rejoindre la conversation
Vous pouvez publier maintenant et vous inscrire plus tard. Si vous avez un compte, connectez-vous maintenant pour publier avec votre compte.