mirror of
git://f0xx.org/ac/ac-ms-media-transcode
synced 2026-07-29 04:38:08 +03:00
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>
69 lines
1.8 KiB
Bash
69 lines
1.8 KiB
Bash
#!/usr/bin/env bash
|
|
# Tee muxer targets: local file, named pipe, HLS dir, RTMP sinks list.
|
|
set -euo pipefail
|
|
|
|
# shellcheck disable=SC1091
|
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
|
|
|
read_sinks() {
|
|
SINKS=()
|
|
[[ -f "${SINKS_LIST}" ]] || return 0
|
|
while IFS= read -r line; do
|
|
line="${line%%#*}"
|
|
line="$(echo "${line}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
[[ -n "${line}" ]] && SINKS+=("${line}")
|
|
done < "${SINKS_LIST}"
|
|
}
|
|
|
|
pipe_tee_entry() {
|
|
local pipe="$1"
|
|
printf "[select='v:0,a':f=flv:onfail=ignore:use_fifo=1:fifo_options='fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1']%s" "${pipe}"
|
|
}
|
|
|
|
file_tee_entry() {
|
|
local path="$1"
|
|
local fmt="${RECORD_FORMAT}"
|
|
case "${fmt}" in
|
|
mkv) printf "[select='v:0,a':f=matroska:onfail=ignore]%s" "${path}" ;;
|
|
flv|*) printf "[select='v:0,a':f=flv:onfail=ignore]%s" "${path}" ;;
|
|
esac
|
|
}
|
|
|
|
hls_tee_entry() {
|
|
local dir="$1"
|
|
mkdir -p "${dir}"
|
|
printf "[select='v:0,a':f=hls:onfail=ignore:hls_time=2:hls_list_size=6:hls_flags=delete_segments+append_list]%s/index.m3u8" "${dir}"
|
|
}
|
|
|
|
rtmp_tee_entry() {
|
|
local url="$1"
|
|
printf "[select='v:0,a':f=flv:onfail=ignore]%s" "${url}"
|
|
}
|
|
|
|
# Encode stage: record + pipe (+ optional HLS). RTMP fanout is copy stage.
|
|
build_encode_tee_spec() {
|
|
local record="$1"
|
|
local pipe="$2"
|
|
local parts=()
|
|
parts+=("$(file_tee_entry "${record}")")
|
|
parts+=("$(pipe_tee_entry "${pipe}")")
|
|
if [[ -n "${HLS_OUTPUT_DIR}" ]]; then
|
|
parts+=("$(hls_tee_entry "${HLS_OUTPUT_DIR}")")
|
|
fi
|
|
local IFS='|'
|
|
echo "${parts[*]}"
|
|
}
|
|
|
|
# Fanout stage: copy from pipe to all sinks (no re-encode).
|
|
build_fanout_tee_spec() {
|
|
read_sinks
|
|
local parts=()
|
|
local s
|
|
for s in "${SINKS[@]}"; do
|
|
parts+=("$(rtmp_tee_entry "${s}")")
|
|
done
|
|
[[ ${#parts[@]} -gt 0 ]] || die "no sinks in ${SINKS_LIST}"
|
|
local IFS='|'
|
|
echo "${parts[*]}"
|
|
}
|