Kartina.tv mit IPTV
Inhaltsverzeichnis |
Beschreibung
kartina.tv ist ein kommerzieller IPTV-Anbieter, der etwas über 100 russischsprachige Kanäle inkl. einigen HD- und Radiokanälen anbietet. Der Anbieter offeriert über seine Webseite mehrere unterschiedlich teure Set-Top-Boxen, die vermutlich auch nichts anderes machen als was ich hier beschreibe. Aber wer kauft schon eine Set-Top-Box, wenn er einen VDR hat.
Der automatisierte Zugriff auf das Webinterface erfolgt per REST-API (Representational State Transfer). Die Herausforderung beim Zugriff auf die einzelnen Streams liegt darin, dass die Stream-URLs dynamisch gebildet werden und nur für sehr kurze Zeit gültig sind. Eine statische Konfiguration funktioniert daher nicht; man muss bei jedem Umschaltvorgang einen neuen dynamischen URL holen.
Grundsätzlich funktioniert der Zugriff prima mit dem Iptv-plugin mithilfe des EXT-Protokolls und vlc als externem Player. Folgende Beispielkonfiguration habe ich mit vdr-1.7.15 erstellt. Es gibt im Moment noch einige Instabilitäten (was den WAF-Faktor erheblich senkt); Hinweise und Verbesserungen werden dankend angenommen :-) (Hinweis: Diese Anleitung ist Work in Progress und nicht für "Produktiv" Umgebungen geeignet!)
Software
Der Extensions-Patch ist für iptv / kartina nicht nötig, aber ich brauche ein paar Funktionen in meinem VDR:
CUTTIME = 1 DDEPGENTRY = 1 HARDLINKCUTTER = 1 JUMPPLAY = 1 LIEMIEXT = 1 PINPLUGIN = 1 PLUGINMISSING = 1 TIMERINFO = 1
Patchen wie üblich, vdr und Module neu übersetzen.
Für die Wiedergabe nutze ich aktuell xineliboutput-1.0.90-cvs und vdr-sxfe auf einem NVidia-ION-basierten Player (SD und HD).
Funktionen
- 1x pro Tag wird die channel-Liste neu geholt. Vor jedem (Neu-) Start von VDR wird damit eine neue channels.conf gebaut (TODO). (Ich würde mir an der Stelle eine INCLUDE-Funktion in channels.conf wünschen, oder noch besser eine Verlagerung in eine sqlite-DB -- eine statische channels.conf ist einfach nicht mehr zeitgemäß).
- Beim Unschalten auf einen kartina-Kanal wird ein aktueller dynamischer Stream-URL geholt und dann vlc gestartet (basierend auf iptvstream.sh aus dem Iptv-plugin)
- 1x pro Tag werden die EPG-Daten für alle Kanäle geholt, ins epg.data-Format gewandelt und in den VDR geladen (TODO).
Konfiguration
Alle Konfigurationsdateien und Skripte liegen in /etc/vdr/plugins/iptv/kartina.tv/ .
Zunächst benötigen wir eine zentrale Datei, die die Zugangsdaten hält. Sie wird von den anderen Skripten benutzt (hier: nur Demo-Zugang):
Einmal am Tag wird die aktuelle Kanalliste geholt und in einen channels.conf-Abschnitt konvertiert. Das Skript sollte wegen Dateizugriffsrechten unter der gleichen UID laufen wie VDR selbst (root oder vdr):
#!/bin/bash # Your logon Data DIR=$(dirname $0) . $DIR/kartina-login.sh # Channels.conf CHANNELS=$DIR/kartinatv-channels.conf API=http://iptv.kartina.tv/api/xml # Login echo Login to iptv.kartina.tv LOGIN=$(wget -O - -q --save-cookies k.x --keep-session-cookies "$API/login?login=$USER&pass=$PASS") PACKET_NAME="$(echo "$LOGIN" | grep packet_name | sed 's!\(.*<packet_name>\)\(.*\)\(</packet_name>.*\)!\2!g' )" if [ -z "$PACKET_NAME" ]; then echo "login failed" echo "$LOGIN" exit 1 fi echo 'Playlist for Paket:' $PACKET_NAME # get Channel List CHANNEL_LIST=$(wget -O - -q --load-cookies k.x --keep-session-cookies "$API/channel_list") echo "$CHANNEL_LIST" > channel_list.xml # very poor man's XML parser echo "$CHANNEL_LIST" | sed 's/<id>/\n/g;' | grep 'stream' | \ sed 's!\([0-9]*\)</id><name>\(.*\)</name>.*<is_video>\(.\)</is_video>.*!\1 \3 \2!g' | \ while read ID VIDEO NAME; do # wenn Radiokanal: VPID = 0 if [ $VIDEO -eq 0 ] ; then VPID=0 else VPID=$(( $ID + 1 )) fi APID=$(( $ID + 2 )) SPID=$(( $ID + 3 )) echo "$NAME;IPTV:$ID:S=0|P=0|F=EXT|U=iptvstream.sh|A=$ID:I:0:$VPID:$APID:0:0:$ID:0:0:0" >> "$CHANNELS.unsorted" # jetzt epg für Channel holen # nur ein Tag? Oder gleich für mehrere? rm -f "epg/$ID-*" DAY1=$(date +"%d%m%y") DAY2=$(date +"%d%m%y" --date="tomorrow") DAY3=$(date +"%d%m%y" --date="tomorrow + 1 day") for DAY in $DAY1 $DAY2 $DAY3 ; do wget -O "$DIR/epg/$ID-$DAY.xml" -q --load-cookies k.x --keep-session-cookies "$API/epg?cid=$ID&day=$DAY" # epgparse.pl < $DIR/epg/$ID-$DAY.xml > $DIR/epg/$ID-$DAY.epg.data done done # write channels.conf fragment sort < "$CHANNELS.unsorted" > "$CHANNELS" rm "$CHANNELS.unsorted" # log out LOGOUT=$(wget -O - -q --load-cookies k.x --keep-session-cookies "$API/logout") chown -R vdr.vdr $DIR
Die erzeugte channels.conf sieht dann so aus (iptv-0.4.2 Format):
МТV Россия;IPTV:39:S=0|P=0|F=EXT|U=iptvstream.sh|A=39:I:0:40:41:0:0:39:0:0:0 РенТВ;IPTV:7:S=0|P=0|F=EXT|U=iptvstream.sh|A=7:I:0:8:9:0:0:7:0:0:0 Россия 24;IPTV:6:S=0|P=0|F=EXT|U=iptvstream.sh|A=6:I:0:7:8:0:0:6:0:0:0 ТНТ;IPTV:8:S=0|P=0|F=EXT|U=iptvstream.sh|A=8:I:0:9:10:0:0:8:0:0:0
/etc/vdr/plugins/iptv/iptvstream.sh ist ein symbolischer Link auf /etc/vdr/plugins/iptv//kartina.tv/kartina-iptvstream.sh:
#!/bin/bash # # iptvstream.sh can be used by the VDR iptv plugin to transcode external # sources # # (C) 2007 Rolf Ahrenberg, Antti Seppälä # # iptvstream.sh is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This package is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this package; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, # MA 02110-1301, USA. # adapted for kartina.tv hm@seneca.muc.de exec 1>>/tmp/t.out exec 2>>/tmp/t.out set -x if [ $# -ne 2 ]; then logger "$0: error: Invalid parameter count '$#' $*" exit 1 fi # Channels.conf parameter ID=${1} # Iptv plugin listens this port PORT=${2} # Default settings for stream transcoding VCODEC=mp2v VBITRATE=2400 ACODEC=mpga ABITRATE=320 ########################################################################## # retrieve current URL for this channel ID ########################################################################## # Your logon Data DIR="$(dirname $0)/kartina.tv" cd $DIR . kartina-login.sh # For VLC set "false", for other players set "true" FIXSTANDARD=false API=http://iptv.kartina.tv/api/xml # Login LOGIN=$(wget -O - -q --save-cookies k.x --keep-session-cookies "$API/login?login=$USER&pass=$PASS") # protect_code unconditional? # URLRAW=$(wget -O - -q --load-cookies k.x --keep-session-cookies "$API/get_url?cid=$ID&protect_code=$PROT_CODE") URLRAW=$(wget -O - -q --load-cookies k.x --keep-session-cookies "$API/get_url?cid=$ID") URL="$(echo "$URLRAW" | grep url | sed 's!\(.*<url>\)\(.*\)\(</url>.*\)!\2!g')" URL="$(echo "$URL" | sed 's/ /%20/g')" if [ "$FIXSTANDARD" = "true" ]; then URL="$(echo "$URL" | sed 's!http/ts!http!g')" fi # log out LOGOUT=$(wget -O - -q --load-cookies k.x --keep-session-cookies "$API/logout") if [ -z "${URL}" ]; then logger "$0: error: URL not defined!" exit 1 fi # Create transcoding options TRANSCODE_OPTS="vcodec=${VCODEC},acodec=${ACODEC},vb=${VBITRATE},ab=${ABITRATE}" if [ -n "${WIDTH}" -a -n "${HEIGHT}" ] ; then TRANSCODE_OPTS="${TRANSCODE_OPTS},width=${WIDTH},height=${HEIGHT}" fi # Create unique pids for the stream VPID=$(( $ID + 1 )) APID=$(( $ID + 2 )) SPID=$(( $ID + 3 )) # kill old vlc processes killall vlc # Execute vlc and feed stream into iptv port exec vlc "${URL}" \ --sout "#transcode{${TRANSCODE_OPTS}}:standard{access=udp,mux=ts{pid-video=${VPID},pid-audio=${APID},pid-spu=${SPID}},dst=127.0.0.1:${PORT}}" \ --intf dummy \ --config $DIR/vlcrc
Bugs / What's missing / TODO
- Im Moment fehlt noch der Zugriff auf das Archiv von kartina.tv (HOWTO willkommen).
- Ton geht nicht bei allen (Demo-) Kanälen. Problem mit APID? HELP!
- Umschaltzeiten sind sehr lang, das liegt mit daran, dass man immer die dyn. URLs holen muss
- EPG-Auswertung
- channels.conf autom. neu bauen
- Bild ruckt alle paar Sekunden, das mag aber daran liegen, dass mein 6 MBit/s DSL zu langsam ist.