File size: 4,184 Bytes
2753d8f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | #!/usr/bin/env bash
# Stream playback helper — takes BEX stream JSON output and plays with mpv/ffplay
#
# Usage:
# ./play-stream.sh <stream_json>
# echo '{"manifest_url":"...", "headers":[...]}' | ./play-stream.sh
# ./play-stream.sh --from-file stream_output.json
#
# Supports:
# - HLS (.m3u8) streams
# - Direct MP4/MKV URLs
# - Custom headers (Referer, User-Agent, etc.)
# - mpv (preferred) or ffplay (fallback)
#
# The script extracts the stream URL and headers from the BEX engine's
# resolve-stream JSON output and constructs the correct player command.
set -euo pipefail
# Read JSON from stdin, argument, or file
if [ "${1:-}" = "--from-file" ] && [ -f "${2:-}" ]; then
JSON=$(cat "$2")
elif [ -n "${1:-}" ] && [ "${1:-}" != "-" ]; then
JSON="$1"
else
JSON=$(cat)
fi
if [ -z "$JSON" ]; then
echo "Error: No stream JSON provided"
echo "Usage: ./play-stream.sh '<json>' or pipe JSON to stdin"
exit 1
fi
# Parse JSON with jq (or python fallback)
if command -v jq &>/dev/null; then
STREAM_URL=$(echo "$JSON" | jq -r '.manifest_url // .videos[0].url // empty')
# Extract headers as key: value pairs
HEADERS=$(echo "$JSON" | jq -r '.headers[]? | "\(.key): \(.value)"')
FORMAT=$(echo "$JSON" | jq -r '.format // "hls"')
LABEL=$(echo "$JSON" | jq -r '.label // "Stream"')
elif command -v python3 &>/dev/null; then
STREAM_URL=$(echo "$JSON" | python3 -c "
import json, sys
d = json.load(sys.stdin)
url = d.get('manifest_url') or (d.get('videos', [{}])[0].get('url', ''))
print(url)
")
HEADERS=$(echo "$JSON" | python3 -c "
import json, sys
d = json.load(sys.stdin)
for h in d.get('headers', []):
print(f\"{h['key']}: {h['value']}\")
")
FORMAT=$(echo "$JSON" | python3 -c "
import json, sys
d = json.load(sys.stdin)
print(d.get('format', 'hls'))
")
LABEL="Stream"
else
echo "Error: requires 'jq' or 'python3' to parse JSON"
exit 1
fi
if [ -z "$STREAM_URL" ]; then
echo "Error: Could not extract stream URL from JSON"
echo "JSON received:"
echo "$JSON" | head -20
exit 1
fi
echo "=== BEX Stream Player ==="
echo "URL: $STREAM_URL"
echo "Format: $FORMAT"
echo "Label: $LABEL"
echo ""
# Build header arguments
MPV_HEADERS=""
FFPLAY_HEADERS=""
while IFS= read -r header; do
if [ -n "$header" ]; then
KEY=$(echo "$header" | cut -d: -f1 | xargs)
VALUE=$(echo "$header" | cut -d: -f2- | xargs)
MPV_HEADERS="${MPV_HEADERS}${KEY}: ${VALUE}\r\n"
FFPLAY_HEADERS="${FFPLAY_HEADERS}-headers \"${KEY}: ${VALUE}\r\n\" "
echo "Header: $KEY: $VALUE"
fi
done <<< "$HEADERS"
echo ""
# Try mpv first (best experience)
if command -v mpv &>/dev/null; then
echo "Playing with mpv..."
MPV_ARGS=(
"$STREAM_URL"
"--title=BEX: $LABEL"
"--force-media-title=$LABEL"
)
if [ -n "$MPV_HEADERS" ]; then
MPV_ARGS+=("--http-header-fields=${MPV_HEADERS}")
fi
# HLS-specific options
if [ "$FORMAT" = "hls" ] || echo "$STREAM_URL" | grep -q "m3u8"; then
MPV_ARGS+=(
"--demuxer-max-bytes=100MiB"
"--demuxer-max-back-bytes=50MiB"
"--cache=yes"
"--cache-secs=30"
)
fi
exec mpv "${MPV_ARGS[@]}"
# Fallback to ffplay
elif command -v ffplay &>/dev/null; then
echo "Playing with ffplay..."
FFPLAY_ARGS=(
-i "$STREAM_URL"
-window_title "BEX: $LABEL"
-loglevel warning
-autoexit
)
if [ -n "$MPV_HEADERS" ]; then
FFPLAY_ARGS+=(-headers "$MPV_HEADERS")
fi
exec ffplay "${FFPLAY_ARGS[@]}"
# Last resort: just print the URL for manual use
else
echo "No player found (mpv or ffplay required)"
echo ""
echo "Manual playback commands:"
echo ""
echo " mpv \"$STREAM_URL\" \\"
if [ -n "$MPV_HEADERS" ]; then
echo " --http-header-fields=\"${MPV_HEADERS}\" \\"
fi
echo " --cache=yes"
echo ""
echo " ffplay -i \"$STREAM_URL\" \\"
if [ -n "$MPV_HEADERS" ]; then
echo " -headers \"${MPV_HEADERS}\""
fi
echo ""
echo " curl -L -H 'User-Agent: Mozilla/5.0' \"$STREAM_URL\" | ffplay -"
exit 1
fi
|