Files
cvmmap-streamer/scripts/live_srs_forward_smoke.sh
T

234 lines
6.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
BUILD_DIR="${BUILD_DIR:-$ROOT_DIR/build}"
STREAMER_BIN="${STREAMER_BIN:-$BUILD_DIR/cvmmap_streamer}"
SRS_ROOT="${SRS_ROOT:-$HOME/Code/srs}"
SRS_BIN="${SRS_BIN:-$SRS_ROOT/trunk/objs/srs}"
SRS_CONF="${SRS_CONF:-$SRS_ROOT/trunk/conf/srs.conf}"
FFPROBE_BIN="${FFPROBE_BIN:-ffprobe}"
FFMPEG_BIN="${FFMPEG_BIN:-ffmpeg}"
CURL_BIN="${CURL_BIN:-curl}"
INPUT_URI="${INPUT_URI:-}"
STREAM_NAME="${STREAM_NAME:-}"
CODEC="${CODEC:-h264}"
ENCODER_BACKEND="${ENCODER_BACKEND:-ffmpeg}"
ENCODER_DEVICE="${ENCODER_DEVICE:-nvidia}"
RTMP_TRANSPORT="${RTMP_TRANSPORT:-libavformat}"
RTMP_MODE="${RTMP_MODE:-enhanced}"
INGEST_MAX_FRAMES="${INGEST_MAX_FRAMES:-120}"
PROBE_TIMEOUT_S="${PROBE_TIMEOUT_S:-20}"
DECODE_FRAMES="${DECODE_FRAMES:-15}"
SRS_MAX_CONNECTIONS="${SRS_MAX_CONNECTIONS:-64}"
RUN_DIR="${RUN_DIR:-$BUILD_DIR/live_srs_forward_smoke_$(date +%Y%m%d_%H%M%S)}"
mkdir -p "$RUN_DIR"
SRS_LOG="$RUN_DIR/srs.log"
STREAMER_LOG="$RUN_DIR/streamer.log"
HTTP_PROBE_LOG="$RUN_DIR/ffprobe_httpflv.log"
DECODE_LOG="$RUN_DIR/ffmpeg_decode_httpflv.log"
API_LOG="$RUN_DIR/srs_api_streams.json"
SRS_TEMP_CONF="$RUN_DIR/srs.conf"
RTMP_URL="rtmp://127.0.0.1/live/${STREAM_NAME}"
HTTP_FLV_URL="http://127.0.0.1:8080/live/${STREAM_NAME}.flv"
SRS_PID=""
STREAMER_PID=""
STARTED_SRS=0
require_bin() {
local path="$1"
local label="$2"
if ! command -v "$path" >/dev/null 2>&1 && [[ ! -x "$path" ]]; then
echo "$label not found: $path" >&2
exit 1
fi
}
usage() {
cat <<'EOF'
Usage:
live_srs_forward_smoke.sh <input-uri> [stream-name]
Environment overrides:
INPUT_URI cvmmap source URI, if positional argument is omitted
STREAM_NAME RTMP/HTTP-FLV stream name, default derived from INPUT_URI
CODEC h264|h265
ENCODER_BACKEND ffmpeg|gstreamer_legacy
ENCODER_DEVICE auto|nvidia|software
RTMP_TRANSPORT libavformat|ffmpeg_process|legacy_custom
RTMP_MODE enhanced|domestic
INGEST_MAX_FRAMES bounded frame count for the smoke
DECODE_FRAMES frames to decode from HTTP-FLV after probe
SRS_ROOT local SRS checkout, default ~/Code/srs
EOF
}
derive_stream_name() {
local uri="$1"
local body="${uri#cvmmap://}"
local instance="${body%%@*}"
instance="${instance%%\?*}"
instance="${instance%%/*}"
if [[ -z "$instance" || "$instance" == "$uri" ]]; then
instance="stream"
fi
instance="${instance//[^a-zA-Z0-9_-]/_}"
printf '%s_live' "$instance"
}
wait_for_http() {
local url="$1"
local attempts="$2"
for _ in $(seq 1 "$attempts"); do
if "${CURL_BIN}" -fsS "$url" >/dev/null 2>&1; then
return 0
fi
sleep 0.25
done
return 1
}
wait_for_http_flv() {
local attempts="$1"
for _ in $(seq 1 "$attempts"); do
if "${FFPROBE_BIN}" \
-v error \
-select_streams v:0 \
-show_entries stream=index,codec_name,width,height,avg_frame_rate \
-of default=noprint_wrappers=1 \
"$HTTP_FLV_URL" >"$HTTP_PROBE_LOG" 2>&1; then
return 0
fi
if [[ -n "$STREAMER_PID" ]] && ! kill -0 "$STREAMER_PID" >/dev/null 2>&1; then
return 1
fi
sleep 0.25
done
return 1
}
print_failure_context() {
echo "--- artifacts ---" >&2
echo "RUN_DIR=$RUN_DIR" >&2
echo "--- streamer log tail ---" >&2
tail -n 120 "$STREAMER_LOG" >&2 || true
echo "--- srs log tail ---" >&2
tail -n 120 "$SRS_LOG" >&2 || true
}
cleanup() {
if [[ -n "$STREAMER_PID" ]] && kill -0 "$STREAMER_PID" >/dev/null 2>&1; then
kill "$STREAMER_PID" >/dev/null 2>&1 || true
wait "$STREAMER_PID" >/dev/null 2>&1 || true
fi
if [[ "$STARTED_SRS" -eq 1 ]] && [[ -n "$SRS_PID" ]] && kill -0 "$SRS_PID" >/dev/null 2>&1; then
kill "$SRS_PID" >/dev/null 2>&1 || true
wait "$SRS_PID" >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT
require_bin "$STREAMER_BIN" "streamer binary"
require_bin "$SRS_BIN" "SRS binary"
require_bin "$FFPROBE_BIN" "ffprobe"
require_bin "$FFMPEG_BIN" "ffmpeg"
require_bin "$CURL_BIN" "curl"
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
usage
exit 0
fi
if [[ -n "${1:-}" ]]; then
INPUT_URI="$1"
fi
if [[ -n "${2:-}" ]]; then
STREAM_NAME="$2"
fi
if [[ -z "$INPUT_URI" ]]; then
echo "input URI is required" >&2
usage >&2
exit 1
fi
if [[ -z "$STREAM_NAME" ]]; then
STREAM_NAME="$(derive_stream_name "$INPUT_URI")"
fi
RTMP_URL="rtmp://127.0.0.1/live/${STREAM_NAME}"
HTTP_FLV_URL="http://127.0.0.1:8080/live/${STREAM_NAME}.flv"
if [[ ! -f "$SRS_CONF" ]]; then
echo "SRS config not found: $SRS_CONF" >&2
exit 1
fi
if wait_for_http "http://127.0.0.1:1985/api/v1/versions" 4; then
echo "Reusing running SRS on 127.0.0.1:1935"
else
sed \
-e 's/^daemon[[:space:]]\+on;/daemon off;/' \
-e "s/^max_connections[[:space:]]\\+[0-9]\\+;/max_connections ${SRS_MAX_CONNECTIONS};/" \
"$SRS_CONF" >"$SRS_TEMP_CONF"
(
cd "$SRS_ROOT/trunk"
"$SRS_BIN" -c "$SRS_TEMP_CONF" >"$SRS_LOG" 2>&1 &
echo $! >"$RUN_DIR/srs.pid"
)
SRS_PID="$(cat "$RUN_DIR/srs.pid")"
STARTED_SRS=1
if ! wait_for_http "http://127.0.0.1:1985/api/v1/versions" 40; then
echo "SRS failed to become ready on 127.0.0.1:1985" >&2
print_failure_context
exit 1
fi
fi
"$STREAMER_BIN" \
--run-mode pipeline \
--input-uri "$INPUT_URI" \
--codec "$CODEC" \
--encoder-backend "$ENCODER_BACKEND" \
--encoder-device "$ENCODER_DEVICE" \
--rtmp \
--rtmp-url "$RTMP_URL" \
--rtmp-transport "$RTMP_TRANSPORT" \
--rtmp-mode "$RTMP_MODE" \
--ingest-max-frames "$INGEST_MAX_FRAMES" \
>"$STREAMER_LOG" 2>&1 &
STREAMER_PID=$!
if ! wait_for_http_flv $((PROBE_TIMEOUT_S * 4)); then
echo "HTTP-FLV stream never became probeable: $HTTP_FLV_URL" >&2
print_failure_context
exit 1
fi
if ! "$FFMPEG_BIN" -v error -i "$HTTP_FLV_URL" -an -frames:v "$DECODE_FRAMES" -f null - >"$DECODE_LOG" 2>&1; then
echo "warning: HTTP-FLV decode sample failed, see $DECODE_LOG" >&2
fi
"$CURL_BIN" -fsSL "http://127.0.0.1:1985/api/v1/streams/" >"$API_LOG" 2>/dev/null || true
wait "$STREAMER_PID"
STREAMER_RC=$?
STREAMER_PID=""
echo "RUN_DIR=$RUN_DIR"
echo "STREAMER_RC=$STREAMER_RC"
echo "INPUT_URI=$INPUT_URI"
echo "RTMP_URL=$RTMP_URL"
echo "HTTP_FLV_URL=$HTTP_FLV_URL"
echo "--- http-flv ffprobe ---"
cat "$HTTP_PROBE_LOG"
echo "--- http-flv decode log ---"
cat "$DECODE_LOG"
echo "--- srs api streams ---"
cat "$API_LOG" 2>/dev/null || true
echo "--- streamer log tail ---"
tail -n 80 "$STREAMER_LOG"