Quote
Ich habe dem vdr-plugin-iptv noch eine Chance gegeben und die letzten Tage etwas mit dem Script iptvstream.sh getestet.
Allerdings muss ich aber gleich sagen, es gab da keinerlei Erfolge, d.h. kein Bild und kein Ton.
In order to be able to record and watch, VDR wants SID, NID and TID values that match with the values in the UDP Transport stream.
I decided to generate these based on a 'checksum' taken from the tvg-id, like "ARD.de"
CHKSUM=$(echo "$tvg_name" | cksum | cut -c 1-9 | sed 's/ //g')
E.g.:
echo "ARD.de" | cksum | cut -c 1-9 | sed 's/ //g'
219542664
Next I generate the channels.conf values as follows:
SID_FILTER="1"
PID_FILTER="1"
NID="65281"
PIDS="100:200:0" # vpid, apid, tpid
# determine unique sid and tid based on CHKSUM
FLOAT=$(perl -E "say $CHKSUM/65536*10000000")
TID=$(echo $FLOAT | cut -f 1 -d "." | cut -c 1-4)
SID=$(echo $FLOAT | cut -f 2 -d ".")
# Create channels.conf line
echo "${tvg_name};IPTV:${CHKSUM}:S=${SID_FILTER}|P=${PID_FILTER}|F=EXT|U=iptvstream.sh|A=${CHKSUM}:I:0:${PIDS}:0:${SID}:&{NID}:${TID}:0" >> channels_iptv.conf
Display More
I also keep (a list of) urls based on the 'CHKSUM' separated by '€' (with some supporting fields that describe the stream)
cat urls.conf
1€ARD.de€http://192.168.1.3:5000/api/zde/live/ard.m3u8€219542664€1920€0
iptvstream.sh script reads the "CHKSUM" as it got passed from the iptv plugin from the channels.conf
The original SID, and TID are generated on-the fly at the time you switch to channel
It also reads the URL from urls.conf
iptvstream snippet: (not meant to start working out of the box, more to give an idea)
#!/bin/bash
if [ $# -ne 2 ]; then
logger -s -t "iptvstream.sh" "Pass two arguments: chksum and iptv udp listening port"
exit 1
fi
# Where to find vlc or ffmpeg
FFMPEG="ffmpeg"
# Set streaming network buffers
BUFFER="?buffer_size=16777216"
FLUSH_PACKETS="-flush_packets -1" # 1: flush immediately, reduce latency, 0: increases throughput, -1: automatic
# CORRECT_TS_OVERFLOW="-correct_ts_overflow 1" # Correct single timestamp overflows if set to 1. Default is 1
CORRECT_TS_OVERFLOW=""
# DISCARD_CORRUPT_PACKAGES="-fflags +discardcorrupt"
DISCARD_CORRUPT_PACKAGES=""
PROBESIZE="2000000" # bytes, 5MB default
ANALYZEDURATION="2000000" # ms, 5 sec. default
NID="65281"
STREAM_FORMAT="-f hls -http_persistent 0 -re"
# define urls file
URL_FILE="/etc/vdr/plugins/iptv/urls.conf"
LOG_DIR="/var/log/vdr"
## start functions:
start_ffmpeg () {
$FFMPEG -y -hide_banner -user_agent "Mozilla/5.0" -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 1 $CORRECT_TS_OVERFLOW \
$DISCARD_CORRUPT_PACKAGES -probesize $PROBESIZE -analyzeduration $ANALYZEDURATION $STREAM_FORMAT -i "${URL}${BUFFER}" \
-codec:v $VCODEC $VCODEC_OPTIONS -codec:a $ACODEC $ACODEC_OPTIONS -streamid 0:$VPID -streamid 1:$APID $FLUSH_PACKETS \
-f mpegts -mpegts_transport_stream_id $TID -mpegts_pmt_start_pid 4096 -mpegts_service_id $SID \
-mpegts_original_network_id $NID udp://$HOST:$PORT?pkt_size=1316\&buffer_size=65536\&overrun_nonfatal=1 &> "$1" &
}
start_ffmpeg_hwaccel () {
$FFMPEG -y -hide_banner -user_agent "Mozilla/5.0" -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 1 $CORRECT_TS_OVERFLOW \
-hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi \
$DISCARD_CORRUPT_PACKAGES -probesize $PROBESIZE -analyzeduration $ANALYZEDURATION $STREAM_FORMAT -i "${URL}${BUFFER}" \
-c:v $VCODEC -b:v 1M -maxrate 2M -c:a $ACODEC -ac 2 -streamid 0:$VPID -streamid 1:$APID $FLUSH_PACKETS \
-f mpegts -mpegts_transport_stream_id $TID -mpegts_pmt_start_pid 4096 -mpegts_service_id $SID \
-mpegts_original_network_id $NID udp://$HOST:$PORT?pkt_size=1316\&buffer_size=65536\&overrun_nonfatal=1 &> "$1" &
}
## End functions
## Main part
URL_LINE=$(cat $URL_FILE | grep €${1} | sed -n 1p) # grab the first line in case multiple url's exist pointing to the same channel
if [ "$URL_LINE" = "" ]; then
logger -s -t "iptvstream.sh" "URL with param: $1 could not be found, please check"
exit 1
fi
CHKSUM=${1}
URL=$(echo "$URL_LINE" | awk 'BEGIN{FS="€"} {print $3}')
CHANNEL=$(echo "$URL_LINE" | awk 'BEGIN{FS="€"} {print $2}')
CHAN_NEL=$(echo $CHANNEL | sed 's/ /_/g')
echo "$URL $CHKSUM" > /tmp/url.txt
LOG="$LOG_DIR/${CHAN_NEL}-ffmpeg.log"
# Retrieve sid and tid based on CHKSUM
FLOAT=`perl -E "say $CHKSUM/65536*10000000"`
TID=`echo $FLOAT | cut -f 1 -d "." | cut -c 1-4`
SID=`echo $FLOAT | cut -f 2 -d "."`
# Port to send stream to
let PORT=$2
# Host to send iptv stream to
HOST=`hostname`
# use fixed pids, only change the sid and tid to identify the channel
let VPID=100
let APID=200
let SPID=0
# Keep list of exceptions in grep -E to start re-coding in order to get stable video and sound
echo "$URL_LINE" | grep -qiE "dummy"
if [ $? -eq 0 ]; then # start ffmpeg recoding
VCODEC="hevc_vaapi" # h264_vaapi
VCODEC_OPTIONS="-b:v 2500k -preset veryfast -tune zerolatency"
ACODEC="libfdk_aac"
ACODEC_OPTIONS=""
start_ffmpeg_hwaccel "$LOG"
else
VCODEC="copy"
VCODEC_OPTIONS=""
ACODEC="copy"
ACODEC_OPTIONS=""
PROBESIZE="18000000" # overrule default
ANALYZEDURATION="18000000" # overrule default
start_ffmpeg "$LOG"
fi
PID=${!}
trap 'kill -SIGKILL ${PID} 2>/dev/null; exit' HUP INT TERM KILL
# Waiting for the given PID to terminate
wait ${PID}
Display More