mirror of
git://f0xx.org/ac/ac-ms-media-transcode
synced 2026-07-29 05:19:30 +03:00
Add lab restream pipeline with pirate_drift logo and lib/env.sh.
Encode-once/fanout scripts, HLS output, and single overloadable env source. Commits assets/pirate_drift.png as default watermark for cluster runs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
118
lib/source.sh
Normal file
118
lib/source.sh
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
# Resolve pipeline input from CLI arg, sources.list index, or env SOURCE_URL.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
||||
|
||||
SOURCE_URL=""
|
||||
SOURCE_FMT=""
|
||||
SOURCE_VIDEO_STREAM="v:0"
|
||||
SOURCE_AUDIO_STREAM="a:0"
|
||||
AUDIO_INPUT_ARGS=()
|
||||
USE_YTDLP=0
|
||||
|
||||
is_page_url() {
|
||||
local url="$1"
|
||||
[[ "$url" =~ ^https?:// ]] || return 1
|
||||
[[ "$url" =~ \.(m3u8|mpd|mp4|mkv|mov|ts|flv)(\?|$) ]] && return 1
|
||||
[[ -f "$url" ]] && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
resolve_source() {
|
||||
local arg="${1:-}"
|
||||
SOURCE_URL="${SOURCE_URL:-}"
|
||||
SOURCE_FMT=""
|
||||
|
||||
if [[ -n "${SOURCE_URL}" ]]; then
|
||||
:
|
||||
elif [[ -n "${arg}" && -f "${arg}" && "${arg}" != *".list" ]]; then
|
||||
SOURCE_URL="${arg}"
|
||||
elif [[ -n "${arg}" && "${arg}" =~ ^https?:// ]]; then
|
||||
SOURCE_URL="${arg}"
|
||||
elif [[ -n "${arg}" && "${arg}" =~ ^[0-9]+$ ]]; then
|
||||
if [[ ! -f "${SOURCES_LIST}" ]]; then
|
||||
die "sources list missing: ${SOURCES_LIST} (copy sources.example.list)"
|
||||
fi
|
||||
local line
|
||||
line="$(sed -n "${arg}p" "${SOURCES_LIST}" | sed 's/#.*//' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||
[[ -n "${line}" ]] || die "no source on line ${arg} of ${SOURCES_LIST}"
|
||||
SOURCE_URL="$(awk '{print $1}' <<<"${line}")"
|
||||
SOURCE_FMT="$(awk '{print $2}' <<<"${line}")"
|
||||
elif [[ -f "${SOURCES_LIST}" ]]; then
|
||||
local line
|
||||
line="$(grep -v '^[[:space:]]*#' "${SOURCES_LIST}" | grep -v '^[[:space:]]*$' | head -1)"
|
||||
SOURCE_URL="$(awk '{print $1}' <<<"${line}")"
|
||||
SOURCE_FMT="$(awk '{print $2}' <<<"${line}")"
|
||||
else
|
||||
die "usage: pass URL, file path, or 1-based index into ${SOURCES_LIST}"
|
||||
fi
|
||||
|
||||
[[ -n "${SOURCE_URL}" ]] || die "empty source URL"
|
||||
|
||||
if [[ -n "${AUDIO_SOURCE:-}" ]]; then
|
||||
read_rate_flag
|
||||
AUDIO_INPUT_ARGS=("${RE_FLAG[@]}" -thread_queue_size "${THREAD_QUEUE_SIZE}" -i "${AUDIO_SOURCE}")
|
||||
SOURCE_AUDIO_STREAM="a:0"
|
||||
fi
|
||||
|
||||
if [[ "${YTDLP_ENABLED}" == "1" ]] && is_page_url "${SOURCE_URL}"; then
|
||||
USE_YTDLP=1
|
||||
fi
|
||||
|
||||
echo "${SOURCE_URL}" > "${ROOT}/.current_source"
|
||||
log "source: ${SOURCE_URL} (ytdlp=${USE_YTDLP})"
|
||||
}
|
||||
|
||||
ytdlp_auth_args() {
|
||||
local auth="${ROOT}/config/yt-dlp.auth.env"
|
||||
if [[ -f "${auth}" ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "${auth}"
|
||||
fi
|
||||
local args=()
|
||||
[[ -n "${YTDLP_USERNAME:-}" ]] && args+=(--username "${YTDLP_USERNAME}")
|
||||
[[ -n "${YTDLP_PASSWORD:-}" ]] && args+=(--password "${YTDLP_PASSWORD}")
|
||||
[[ -n "${YTDLP_NETRC:-}" ]] && args+=(--netrc)
|
||||
[[ -n "${YTDLP_EXTRA_ARGS:-}" ]] && args+=(${YTDLP_EXTRA_ARGS})
|
||||
printf '%s\n' "${args[@]}"
|
||||
}
|
||||
|
||||
build_ytdlp_pipeline() {
|
||||
local fmt_args=()
|
||||
[[ -n "${SOURCE_FMT}" ]] && fmt_args=(-f "${SOURCE_FMT}")
|
||||
mapfile -t auth < <(ytdlp_auth_args)
|
||||
|
||||
printf '%s\0' "${YTDLP_BIN}" \
|
||||
-o - --no-part --no-live-from-start --no-write-subs --no-embed-subs \
|
||||
--remux-video mkv --merge-output-format mkv --no-audio-multistreams \
|
||||
--geo-bypass --ignore-errors --hls-use-mpegts \
|
||||
"${auth[@]}" \
|
||||
"${fmt_args[@]}" \
|
||||
"${SOURCE_URL}"
|
||||
}
|
||||
|
||||
# Returns ffmpeg input argv: either direct -i URL or pipe from yt-dlp.
|
||||
build_primary_input() {
|
||||
read_rate_flag
|
||||
if [[ "${USE_YTDLP}" == "1" ]]; then
|
||||
require_cmd "${YTDLP_BIN}"
|
||||
printf '%s\0' pipe
|
||||
printf '%s\0' -thread_queue_size "${THREAD_QUEUE_SIZE}" -i pipe:0
|
||||
return
|
||||
fi
|
||||
|
||||
local url="${SOURCE_URL}"
|
||||
if [[ "${url}" == *.jpg || "${url}" == *.jpeg || "${url}" == *.png ]]; then
|
||||
printf '%s\0' direct
|
||||
printf '%s\0' "${RE_FLAG[@]}" -thread_queue_size "${THREAD_QUEUE_SIZE}" \
|
||||
-loop 1 -i "${url}" -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000
|
||||
return
|
||||
fi
|
||||
|
||||
printf '%s\0' direct
|
||||
printf '%s\0' "${RE_FLAG[@]}" -thread_queue_size "${THREAD_QUEUE_SIZE}" \
|
||||
-reconnect_on_network_error 1 -reconnect_streamed 1 -reconnect_delay_max 5 \
|
||||
-i "${url}"
|
||||
}
|
||||
Reference in New Issue
Block a user