New release
authorKristian Kræmmer Nielsen <jkkn@jkkn.dk>
Mon, 3 Apr 2017 11:58:32 +0000 (13:58 +0200)
committerKristian Kræmmer Nielsen <jkkn@jkkn.dk>
Mon, 3 Apr 2017 11:58:32 +0000 (13:58 +0200)
Moved record config to seperate file
Tuned timeouts
Picking better stream bandwidth for recording
Fix resync on lost segments

monitor-dai.sh
record-config.sh [new file with mode: 0644]

index c89c46788c977f16485b5befae9afdf948829551..6f552960cb328160372e06b8ddcf16af02646483 100755 (executable)
@@ -26,7 +26,7 @@
 #   monitor-dai.sh <url-to-hls-stream-including-tokens> <optional-record-dir> <delay>
 #
 
-BASIC_CURL_PARAMS="--connect-timeout 10 --location --max-time 60 -Ss"
+BASIC_CURL_PARAMS="--connect-timeout 15 --location -Ss"
 SCRIPT_NAME=$(basename "$0")
 
 DATE_BSD="date -r "
@@ -41,8 +41,7 @@ fi
 # Used as default 10 seconds pause before retrying
 TARGET_DURATION=10
 
-# No adblocks to record
-RECORD_AD_BLOCKS=3
+source "$(dirname $0)/record-config.sh" || fatal "Missing record-config.sh"
 
 # Very limited function to resolve relative url
 function resolveRelativeURL() {
@@ -80,15 +79,22 @@ function fatal() {
 # Extract first stream from HLS Master-Playlist
 function resolveFirstStream() {
    local hls="$1"
+   local bandwidth=-1
    TMPFILE=$(mktemp) || fatal "Can not write tmp-file"
-   url=$(curl $BASIC_CURL_PARAMS -o "$TMPFILE" "$hls" -w "%{url_effective}")
+   url=$(curl $BASIC_CURL_PARAMS --max-time 20 -o "$TMPFILE" "$hls" -w "%{url_effective}")
    if [ $? -eq 0 ]; then
       while IFS="" read line; do
-        # First none comment is first element in playlist => we will use that stream
-        re="^[^#].*$"
+        # Select proper bandwidth
+        re="^#EXT-X-STREAM-INF[:,]BANDWIDTH=([0-9]+)(,|$)"
         if [[ "$line" =~ $re ]]; then
-            echo $(resolveRelativeURL "$line" "$url")
-            break
+            bandwidth="${BASH_REMATCH[1]}"
+        # First none comment is first element in playlist => we will use that stream
+        elif [[ "$bandwidth" -ne -1 && "$bandwidth" -lt "$RECORD_MAX_BANDWIDTH" ]]; then
+            re="^[^#].*$"
+            if [[ "$line" =~ $re ]]; then
+                echo $(resolveRelativeURL "$line" "$url")
+                break
+            fi
         fi
       done <"$TMPFILE"
    else
@@ -117,7 +123,7 @@ function monitorStream() {
     local syncMode=-1 # (-1=get first, x=saw last at, 0=synched) In syncmode we try to request every second until we see a change to get a more precise time sync
     local stream_time="" # unknown
 
-    echo >&2 "$pretty_time: INFO: Started monitoring using: $stream"
+    echo >&2 "INFO: Started monitoring using: $stream"
     
     while true; do
         starttime=$(date +%s)
@@ -125,10 +131,11 @@ function monitorStream() {
 
         # Set time to real time first request
         if [ -z "$stream_time" ]; then
+            syncMode=-1
             if [ -n "$streamDelay" ]; then
                 stream_time=$(($starttime - $streamDelay))
                 pretty_time=$($DATE${stream_time%.*} +"%Y-%m-%d %H:%M:%S")
-                echo >&2 "NOTICE: Using time-offset of -${streamDelay}s. Stream time is $pretty_time, real time is $(date ${realtime} +"%Y-%m-%d %H:%M:%S")"
+                echo >&2 "NOTICE: Using time-offset of -${streamDelay}s. Stream time is $pretty_time, real time is $($DATE${starttime} +"%Y-%m-%d %H:%M:%S")"
             else
                 stream_time="$starttime"
                 pretty_time=$($DATE${stream_time%.*} +"%Y-%m-%d %H:%M:%S")
@@ -137,7 +144,7 @@ function monitorStream() {
         fi
 
         TMPFILE=$(mktemp) || fatal "Can not write tmp-file"
-        curl $BASIC_CURL_PARAMS -o "$TMPFILE" "$stream"
+        curl $BASIC_CURL_PARAMS --max-time 25 -o "$TMPFILE" "$stream"
         if [ $? -eq 0 ]; then
            while IFS="" read line; do
 
@@ -160,7 +167,7 @@ function monitorStream() {
                     if [[ $curSeq -ne -1 ]]; then # we know media sequence
                         if [[ $curSeq -ge $nextSeq ]]; then # later sequence than we need
                             if [[ $doRecord -eq 1 ]]; then
-                                saveStreamBit "$stream" "$tags" "$stream_time" "$recordFolder"
+                                saveStreamBit "$stream" "$tags" "$stream_time" "$recordFolder" &
                             fi
                             lastUsedSegment="$tags"
                             lastUsedStreamTime="$stream_time"
@@ -170,8 +177,15 @@ function monitorStream() {
                             pretty_time=$($DATE${stream_time%.*} +"%Y-%m-%d %H:%M:%S")
                             if [[ $curSeq -ne $nextSeq ]]; then
                                 echo >&2 "$pretty_time: WARN: Lost segments ($curSeq > $nextSeq)."
-                                stream_time=
+                                stream_time=""
                                 syncMode=-1
+                                curSeq=-1
+                                doRecord=0
+                                doStopRecord=0
+                                nextSeq=-1
+                                tags=""
+                                mode="UNKNOWN"
+                                break
                             fi
                             #echo >&2 "$pretty_time: Current mode length: $curLength"
                             nextSeq=$(($curSeq + 1))
@@ -229,21 +243,21 @@ function monitorStream() {
                             echo >&2 "$pretty_time: INFO: Seeing CUE-OUT (Ad block start) of duration: $value"
                             if [ "$mode" == "ADBLOCK" ]; then
                                 echo >&2 "$pretty_time: ERROR: Already in ad block - extra cue-out after $curLength"
-                            #else
-                            #    echo >&2 "$pretty_time: INFO: Ad-block started after $curLength seconds"
-                            fi
-                            mode="ADBLOCK"
-                            expectedAdLength=$value
-                            curLength=0
-                            if [ "$RECORD_AD_BLOCKS" -gt 0 ]; then
-                                if [ -z "$lastUsedSegment" ]; then
-                                    echo >&2 "$pretty_time: INFO: Skipping recording since we did not see start of it."
-                                else
-                                    RECORD_AD_BLOCKS=$(($RECORD_AD_BLOCKS - 1))
-                                    echo >&2 "$pretty_time: INFO: Recording this adblock ($RECORD_AD_BLOCKS left)."
-                                    saveStreamBit "$stream" "$lastUsedSegment" "$lastUsedStreamTime" "$recordFolder"
-                                    doRecord=1
-                                    doStopRecord=0
+                            else
+                                #echo >&2 "$pretty_time: INFO: Ad-block started after $curLength seconds"
+                                mode="ADBLOCK"
+                                expectedAdLength=$value
+                                curLength=0
+                                if [ "$RECORD_AD_BLOCKS" -gt 0 ]; then
+                                    if [ -z "$lastUsedSegment" ]; then
+                                        echo >&2 "$pretty_time: INFO: Skipping recording since we did not see start of it."
+                                    else
+                                        RECORD_AD_BLOCKS=$(($RECORD_AD_BLOCKS - 1))
+                                        echo >&2 "$pretty_time: INFO: Recording this adblock ($RECORD_AD_BLOCKS left)."
+                                        saveStreamBit "$stream" "$lastUsedSegment" "$lastUsedStreamTime" "$recordFolder" &
+                                        doRecord=1
+                                        doStopRecord=0
+                                    fi
                                 fi
                             fi
                         elif [ "$tag" == "EXT-X-CUE-IN" ]; then
@@ -253,15 +267,15 @@ function monitorStream() {
                                 if [ "$expectedAdLength" != "$curLength" ]; then
                                     echo >&2 "$pretty_time: WARN: Block was not the length expected ($curLength <> $expectedAdLength)"
                                 fi
+                                if [ "$doRecord" == "1" ]; then
+                                    echo >&2 "$pretty_time: INFO: Stopping recording."
+                                    doStopRecord=1
+                                fi  
+                                curLength=0
                             elif [ "$mode" == "LIVE" ]; then
                                 echo >&2 "$pretty_time: ERROR: Extra CUE-IN outside Ad-block after $curLength"
                             fi
                             mode="LIVE"
-                            curLength=0
-                            if [ "$doRecord" == "1" ]; then
-                                echo >&2 "$pretty_time: INFO: Stopping recording."
-                                doStopRecord=1
-                            fi  
                         fi
                     fi
                 fi                 
@@ -332,13 +346,13 @@ function saveStreamBit() {
             # Fetch key if needed
             if [[ -n "$keyURI" ]]; then
                 keyURI=$(resolveRelativeURL "$keyURI" "$streamURI")
-                key=$(curl $BASIC_CURL_PARAMS "$keyURI" | hexdump -v -e '/1 "%02X"')
+                key=$(curl $BASIC_CURL_PARAMS --max-time 480 "$keyURI" | hexdump -v -e '/1 "%02X"')
                 # Decrypt on the fly
-                curl $BASIC_CURL_PARAMS "$uri" | \
+                curl $BASIC_CURL_PARAMS --max-time 480 "$uri" | \
                 openssl aes-128-cbc -d -K "$key" -iv "$keyIV" -nosalt -out "$output"
             else
                 # Fetch stream to file
-                curl $BASIC_CURL_PARAMS -o "$output" "$uri"
+                curl $BASIC_CURL_PARAMS --max-time 480 -o "$output" "$uri"
             fi
         else
             re="^#EXT-X-KEY:METHOD=(AES-128|NONE)(,URI=\"([^\"]*)\",IV=0x([0-9A-F]+))?"
diff --git a/record-config.sh b/record-config.sh
new file mode 100644 (file)
index 0000000..779a67b
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+# ==========================================
+#   Configuration file for DAI monitor
+# ==========================================
+
+# Should we record a number of ad blocks?
+RECORD_AD_BLOCKS=3
+
+# Max bandwidth to select
+RECORD_MAX_BANDWIDTH=600000
+