summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS8
-rw-r--r--HISTORY28
-rwxr-xr-xstreamdev-server/externremux.sh267
3 files changed, 302 insertions, 1 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 5ccccc6..5f8ef8d 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -37,6 +37,7 @@ Rolf Ahrenberg
for improving LIMIKUUTIO and PARENTALRATING patch detection
for suggesting to include the charset in HTTP replies
for requesting replacement of asprintf calls
+ for suggesting to change the URL path from EXTERN to EXT
Rantanen Teemu
for providing vdr-incompletesections.diff
@@ -146,3 +147,10 @@ lhanisch
Eric Valette
for adding support for EnhancedAC3
+
+carel
+ for reporting "plugin doesn't honor APIVERSION" error in new Makefile
+ for helping to find a way to cleanly shutdown externremux with mencoder
+
+wolfi.m
+ for reporting a typo in externermux quality parameter value
diff --git a/HISTORY b/HISTORY
index 252a171..95fb1c7 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,32 @@
VDR Plugin 'streamdev' Revision History
---------------------------------------
-
+
+2010-07-20: Version 0.5.0a
+
+- set externremux.sh executable in distribution archive
+- externremux quality value should be wlan54, not wlan45
+
+2010-07-19: Version 0.5.0
+
+- using SIGINT in externremux to kill mencoder works better than SIGTERM;
+ especially x264 still needs a SIGKILL sometimes
+- added --remove-destination to cp commands installing plugins
+- fixed "plugin doesn't honor APIVERSION" (reported by carel@vdrportal)
+- updated Italian translation (thanks to Diego Pierotto)
+- config option "client may suspend" hidden if not applicable
+- updated and enhanced README
+- separated language resources of client and server
+- restructured build process
+- added support for HTTP method HEAD
+- rewrite of externremux.sh, including support for various URL parameters,
+ logging and improved shutdown
+- start externremux script in a separate process group
+- changed HTTP URL path for externremux from EXTERN to EXT (suggested by
+ Rolf Ahrenberg)
+- HTTP headers now have to be emitted by externremux script
+- pass channel related information and URL parameters to externremux script
+ through environment
+- implement CGI like interface for externremux script
- dropped "Synchronize EPG" feature. Please use epgsync-plugin instead
(available from http://vdr.schmirler.de)
- proper tsplay-0.2 patch detection. tsplay-0.1 is no longer recognized
diff --git a/streamdev-server/externremux.sh b/streamdev-server/externremux.sh
new file mode 100755
index 0000000..21cc60d
--- /dev/null
+++ b/streamdev-server/externremux.sh
@@ -0,0 +1,267 @@
+#!/bin/bash
+#
+# externremux.sh - sample remux script using mencoder for remuxing.
+#
+# Install this script as VDRCONFDIR/plugins/streamdev-server/externremux.sh
+#
+# The parameter QUALITY selects the default remux parameters. Adjust
+# to your needs and point your web browser to http://servername:3000/ext/
+# To select different remux parameters on the fly, insert a semicolon
+# followed by the name and value of the requested parameter, e.g:
+# e.g. http://servername:3000/ext;QUALITY=WLAN11;VBR=512/
+# The following parameters are recognized:
+#
+# PROG actual remux program
+# VC video codec
+# VBR video bitrate (kbit)
+# VOPTS custom video options
+# WIDTH scale video to width
+# AC audio codec
+# ABR audio bitrate (kbit)
+# AOPTS custom audio options
+#
+
+##########################################################################
+
+### GENERAL CONFIG START
+###
+# Pick one of DSL1000/DSL2000/DSL3000/DSL6000/DSL16000/LAN10/WLAN11/WLAN54
+QUALITY='DSL1000'
+# Program used for logging (logging disabled if empty)
+LOGGER=logger
+# Path and name of FIFO
+FIFO=/tmp/externremux-${RANDOM:-$$}
+# Default remux program (cat/mencoder/ogg)
+PROG=mencoder
+# Use mono if $ABR is lower than this value
+ABR_MONO=64
+###
+### GENERAL CONFIG END
+
+### MENCODER CONFIG START
+###
+# mencoder binary
+MENCODER=mencoder
+# Default video codec (e.g. lavc/x264/copy)
+MENCODER_VC=lavc
+# Default audio codec (e.g. lavc/mp3lame/faac/copy)
+MENCODER_AC=mp3lame
+# Default video codec if lavc is used (-ovc lavc -lavcopts vcodec=)
+MENCODER_LAVC_VC=mpeg4
+# Default audio codec if lavc is used (-oac lavc -lavcopts acodec=)
+MENCODER_LAVC_AC=mp2
+###
+### MENCODER CONFIG END
+
+### OGG CONFIG START
+###
+# ffmpeg2theora binary
+OGG=ffmpeg2theora
+# speedlevel - lower value gives better quality but is slower (0..2)
+OGG_SPEED=1
+# videoquality - higher value gives better quality but is slower (0..10)
+OGG_VQUALITY=0
+# audioquality - higher value gives better quality but is slower (0..10)
+OGG_AQUALITY=0
+###
+### OGG CONFIG END
+
+##########################################################################
+
+function hasOpt { echo "$1" | grep -q "\b${2}\b"; }
+
+function isNumeric() { echo "$@" | grep -q '^[0-9]\{1,\}$'; }
+
+function remux_cat
+{
+ startReply
+ exec 3<&0
+ cat 0<&3 >"$FIFO" &
+}
+
+function remux_mencoder
+{
+ # lavc may be used for video and audio
+ LAVCOPTS=()
+
+ # Assemble video options
+ VC=${REMUX_PARAM_VC:-$MENCODER_VC}
+ VOPTS=${REMUX_PARAM_VOPTS}
+ WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH}
+ case "$VC" in
+ lavc)
+ LAVCOPTS=(
+ ${VOPTS}
+ $(hasOpt "$VOPTS" vcodec || echo "vcodec=$MENCODER_LAVC_VC")
+ ${VBR:+vbitrate=$VBR}
+ )
+ [ ${#LAVCOPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -lavcopts "${LAVCOPTS[*]}")
+ ;;
+ x264)
+ X264OPTS=(
+ ${VOPTS}
+ $(hasOpt "$VOPTS" threads || echo "threads=auto")
+ ${VBR:+bitrate=$ABR}
+ )
+ [ ${#X264OPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -x264encopts "${X264OPTS[*]}")
+ ;;
+ copy)
+ VOPTS=
+ ;;
+ *)
+ error "Unknown video codec '$VC'"
+ ;;
+ esac
+
+ # Assemble audio options
+ AC=${REMUX_PARAM_AC:-$MENCODER_AC}
+ AOPTS=${REMUX_PARAM_AOPTS}
+ case "$AC" in
+ lavc)
+ LAVCOPTS=(
+ ${LAVCOPTS[*]}
+ ${AOPTS}
+ $(hasOpt "$AOPTS" acodec || echo "acodec=$MENCODER_LAVC_AC")
+ ${ABR:+abitrate=$ABR}
+ )
+
+ [ ${#LAVCOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -lavcopts "${LAVCOPTS[*]}")
+ # lavc used for video and audio decoding - wipe out VOPTS as video options became part of AOPTS
+ [ "$VC" = lavc ] && VOPTS=
+ ;;
+ mp3lame)
+ LAMEOPTS=(
+ ${AOPTS}
+ $(isNumeric "${ABR}" && [ "${ABR}" -lt "$ABR_MONO" ] && ! hasOpt "${AOPTS}" mode ] && echo 'mode=3')
+ ${ABR:+preset=$ABR}
+ )
+ [ ${#LAMEOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -lameopts "${LAMEOPTS[*]}")
+ ;;
+ faac)
+ FAACOPTS=(
+ ${AOPTS}
+ ${ABR:+br=$ABR}
+ )
+ [ ${#FAACOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -faacopts "${FAACOPTS[*]}")
+ ;;
+ copy)
+ AOPTS=
+ ;;
+ *)
+ error "Unknown audio codec '$AC'"
+ ;;
+ esac
+
+
+ startReply
+ exec 3<&0
+ echo "$MENCODER" \
+ -ovc $VC $VOPTS \
+ -oac $AC $AOPTS \
+ ${WIDTH:+-vf scale -zoom -xy $WIDTH} \
+ -o "$FIFO" -- - >&2
+ "$MENCODER" \
+ -ovc $VC $VOPTS \
+ -oac $AC $AOPTS \
+ ${WIDTH:+-vf scale -zoom -xy $WIDTH} \
+ -o "$FIFO" -- - 0<&3 >/dev/null &
+}
+
+function remux_ogg
+{
+ VOPTS=${REMUX_PARAM_VOPTS//[:=]/ }
+ AOPTS=${REMUX_PARAM_AOPTS//[:=]/ }
+ WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH}
+
+ OGGOPTS=(
+ ${VOPTS}
+ ${VBR:+--videobitrate $VBR}
+ $(hasOpt "${VOPTS}" videoquality || echo "--videoquality $OGG_VQUALITY")
+ $(hasOpt "${VOPTS}" speedlevel || echo "--speedlevel $OGG_SPEED")
+ ${AOPTS}
+ ${ABR:+--audiobitrate $ABR}
+ $(isNumeric "${ABR}" && [ "${ABR}" -lt "$ABR_MONO" ] && ! hasOpt "${AOPTS}" channels ] && echo '--channels 1')
+ $(hasOpt "${AOPTS}" audioquality || echo "--audioquality $OGG_AQUALITY")
+ $(hasOpt "${AOPTS}" audiostream || echo '--audiostream 1')
+ )
+
+ startReply
+ exec 3<&0
+ echo "$OGG" --format ts \
+ ${OGGOPTS[*]} \
+ ${WIDTH:+--width $WIDTH --height $(($WIDTH * 3 / 4 / 8 * 8))} \
+ --title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \
+ --output "$FIFO" -- - 0<&3 >&2
+ "$OGG" --format ts \
+ ${OGGOPTS[*]} \
+ ${WIDTH:+--width $WIDTH --height $(($WIDTH * 3 / 4 / 8 * 8))} \
+ --title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \
+ --output "$FIFO" -- - 0<&3 >/dev/null &
+}
+
+function error
+{
+ if [ "$SERVER_PROTOCOL" = HTTP ]; then
+ echo -ne "Content-type: text/plain\r\n"
+ echo -ne '\r\n'
+ echo "$*"
+ fi
+
+ echo "$*" >&2
+ exit 1
+}
+
+function startReply
+{
+ if [ "$SERVER_PROTOCOL" = HTTP ]; then
+ # send content-type and custom headers
+ echo -ne "Content-type: ${CONTENTTYPE}\r\n"
+ for header in "${HEADER[@]}"; do echo -ne "$header\r\n"; done
+ echo -ne '\r\n'
+
+ # abort after headers
+ [ "$REQUEST_METHOD" = HEAD ] && exit 0
+ fi
+
+ # create FIFO and read from it in the background
+ mkfifo "$FIFO"
+ trap "trap '' EXIT HUP INT TERM ABRT PIPE CHLD; kill -INT 0; sleep 1; fuser -k '$FIFO'; rm '$FIFO'" EXIT HUP INT TERM ABRT PIPE CHLD
+ cat "$FIFO" <&- &
+}
+
+HEADER=()
+
+[ "$LOGGER" ] && exec 2> >($LOGGER -t "vdr: [$$] ${0##*/}" 2>&-)
+
+# set default content-types
+case "$REMUX_VPID" in
+ ''|0|1) CONTENTTYPE='audio/mpeg';;
+ *) CONTENTTYPE='video/mpeg';;
+esac
+
+QUALITY=${REMUX_PARAM_QUALITY:-$QUALITY}
+case "$QUALITY" in
+ DSL1000|dsl1000) VBR=96; ABR=16; WIDTH=160;;
+ DSL2000|dsl2000) VBR=128; ABR=16; WIDTH=160;;
+ DSL3000|dsl3000) VBR=256; ABR=16; WIDTH=320;;
+ DSL6000|dsl6000) VBR=378; ABR=32; WIDTH=320;;
+ DSL16000|dsl16000) VBR=512; ABR=32; WIDTH=480;;
+ WLAN11|wlan11) VBR=768; ABR=64; WIDTH=640;;
+ WLAN54|wlan54) VBR=2048; ABR=128; WIDTH=;;
+ LAN10|lan10) VBR=4096; ABR=; WIDTH=;;
+ *) error "Unknown quality '$QUALITY'";;
+esac
+ABR=${REMUX_PARAM_ABR:-$ABR}
+VBR=${REMUX_PARAM_VBR:-$VBR}
+WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH}
+PROG=${REMUX_PARAM_PROG:-$PROG}
+
+case "$PROG" in
+ cat) remux_cat;;
+ mencoder) remux_mencoder;;
+ ogg) remux_ogg;;
+ *) error "Unknown remuxer '$PROG'";;
+esac
+
+set -o monitor
+wait