Replace ffmpeg-ndi with gst-plugin-ndi for ndi-feeder.
We can no longer reliably compile ffmpeg with the NDI reversal patch. While gst-plugin-ndi isn't particularly well maintained anymore either, it works for now and will probably become a main-stay in my setup. The alternative is doing NDI via OBS and that's just silly and not easily automatable.main
parent
d2df62e51c
commit
57dbec3aac
|
@ -205,6 +205,52 @@ RUN \
|
|||
--mount=type=cache,target=/tmp/build/.cache \
|
||||
ulimit -n 1024 && makepkg -sr --noconfirm
|
||||
|
||||
###
|
||||
# GST-PLUGIN-NDI-GIT
|
||||
|
||||
FROM base-devel-yay AS gst-plugin-ndi-git
|
||||
|
||||
WORKDIR /usr/src/gst-plugin-ndi-git
|
||||
|
||||
USER root
|
||||
# COPY --from=ndi-sdk-embedded /usr/src/ndi-sdk-embedded/*.pkg.* /tmp/
|
||||
COPY --from=ndi-sdk /usr/src/ndi-sdk/*.pkg.* /tmp/
|
||||
RUN \
|
||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/build/.cache \
|
||||
yay --noconfirm -U /tmp/*.pkg.* && rm /tmp/*.pkg.*
|
||||
|
||||
USER build
|
||||
RUN git clone https://aur.archlinux.org/gst-plugin-ndi-git.git .
|
||||
COPY patches/gst-plugin-ndi-git/*.patch /var/tmp
|
||||
RUN set -e && for patch in /var/tmp/*.patch; do patch -Np1 -i "$patch"; done
|
||||
RUN \
|
||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/build/.cache \
|
||||
(\
|
||||
. ./PKGBUILD &&\
|
||||
if [ "${#depends[@]}" -eq 0 ]; then exit; fi &&\
|
||||
packages=$(yay -T "${depends[@]}" 2>/dev/null|| true) &&\
|
||||
if [ -z "$packages" ]; then exit; fi &&\
|
||||
yay -S --noconfirm --asdeps --provides --needed $packages &&\
|
||||
find ~/.cache/yay/ -mindepth 2 -maxdepth 2 -name \*.pkg.\* -exec mv {} . \;\
|
||||
)
|
||||
# RUN (. ./PKGBUILD && yay -S --noconfirm --asdeps --provides --needed $(yay -T "${optdepends[@]}") && (mv -v ~/.cache/yay/*/*.pkg.* . || true))
|
||||
RUN \
|
||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/build/.cache \
|
||||
(\
|
||||
. ./PKGBUILD &&\
|
||||
if [ "${#makedepends[@]}" -eq 0 ]; then exit; fi &&\
|
||||
packages=$(yay -T "${makedepends[@]}" 2>/dev/null|| true) &&\
|
||||
if [ -z "$packages" ]; then exit; fi &&\
|
||||
yay -S --noconfirm --asdeps --provides --needed $packages \
|
||||
)
|
||||
RUN \
|
||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/build/.cache \
|
||||
ulimit -n 1024 && makepkg -sr --noconfirm --nocheck
|
||||
|
||||
###
|
||||
# FFMPEG-NDI
|
||||
|
||||
|
@ -267,7 +313,7 @@ RUN chmod -v +x *.sh
|
|||
FROM scratch as packages
|
||||
|
||||
COPY --from=ndi-sdk /usr/src/ndi-sdk/*.pkg.* /packages/
|
||||
COPY --from=ffmpeg-ndi /usr/src/ffmpeg-ndi/*.pkg.* /packages/
|
||||
COPY --from=gst-plugin-ndi-git /usr/src/gst-plugin-ndi-git/*.pkg.* /packages/
|
||||
COPY --from=fakesilence /usr/local/bin/fakesilence /target/usr/local/bin/
|
||||
|
||||
###
|
||||
|
@ -284,7 +330,7 @@ USER root
|
|||
|
||||
#COPY --from=yay /usr/src/yay/*.pkg.* /tmp/
|
||||
COPY --from=ndi-sdk /usr/src/ndi-sdk/*.pkg.* /tmp/
|
||||
COPY --from=ffmpeg-ndi /usr/src/ffmpeg-ndi/*.pkg.* /tmp/
|
||||
COPY --from=gst-plugin-ndi-git /usr/src/gst-plugin-ndi-git/*.pkg.* /tmp/
|
||||
RUN \
|
||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/build/.cache \
|
||||
|
@ -293,7 +339,7 @@ RUN \
|
|||
RUN \
|
||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/build/.cache \
|
||||
rm -f /var/cache/pacman/pkg/cache.lck; pacman -S --noconfirm --needed sudo realtime-privileges
|
||||
rm -f /var/cache/pacman/pkg/cache.lck; pacman -S --noconfirm --needed sudo realtime-privileges gst-plugins-base gst-plugins-good
|
||||
|
||||
COPY --from=fakesilence /usr/local/bin/fakesilence /usr/local/bin/
|
||||
|
||||
|
|
|
@ -1,57 +1,58 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
target_url="${1:-icecast://source:source@127.0.0.1:61120/main}"
|
||||
ffmpeg_pids=()
|
||||
#target_url="${1:-icecast://source:source@127.0.0.1:61120/main}"
|
||||
: "${TARGET_IP:=127.0.0.1}"
|
||||
: "${TARGET_PORT:=61120}"
|
||||
: "${TARGET_MOUNT:=/main}"
|
||||
: "${TARGET_USERNAME:=source}"
|
||||
: "${TARGET_PASSWORD:=source}"
|
||||
: "${NDI_FEEDER_EXTRA_IP:=}"
|
||||
|
||||
call_ffmpeg() {
|
||||
command ffmpeg -hide_banner "$@"
|
||||
gstreamer_pids=()
|
||||
|
||||
call_gstreamer() {
|
||||
command gst-launch-1.0 "$@"
|
||||
}
|
||||
|
||||
daemon_ffmpeg() {
|
||||
call_ffmpeg "$@" &
|
||||
ffmpeg_pids+=($!)
|
||||
daemon_gstreamer() {
|
||||
call_gstreamer "$@" &
|
||||
gstreamer_pids+=($!)
|
||||
}
|
||||
|
||||
shutdown_ffmpeg() {
|
||||
if is_ffmpeg_running; then
|
||||
kill "$ffmpeg_pid" || true
|
||||
shutdown_gstreamer() {
|
||||
if is_gstreamer_running; then
|
||||
kill "$gstreamer_pid" || true
|
||||
for t in $(seq 0 10); do
|
||||
if ! kill -0 "$ffmpeg_pid"; then
|
||||
if ! kill -0 "$gstreamer_pid"; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if kill -0 "$ffmpeg_pid"; then
|
||||
kill -9 "$ffmpeg_pid" || true
|
||||
if kill -0 "$gstreamer_pid"; then
|
||||
kill -9 "$gstreamer_pid" || true
|
||||
fi
|
||||
fi
|
||||
ffmpeg_pid=
|
||||
gstreamer_pid=
|
||||
}
|
||||
|
||||
is_ffmpeg_running() {
|
||||
[ -n "$ffmpeg_pid" ] && kill -0 "$ffmpeg_pid"
|
||||
is_gstreamer_running() {
|
||||
[ -n "$gstreamer_pid" ] && kill -0 "$gstreamer_pid"
|
||||
}
|
||||
|
||||
on_exit() {
|
||||
shutdown_ffmpeg
|
||||
shutdown_gstreamer
|
||||
}
|
||||
trap on_exit EXIT
|
||||
|
||||
offline=0
|
||||
|
||||
while true; do
|
||||
found_audio_source=""
|
||||
url_address=()
|
||||
if [ -n "$NDI_FEEDER_EXTRA_IP" ]; then
|
||||
url_address=("url-address=$NDI_FEEDER_EXTRA_IP:5961")
|
||||
fi
|
||||
|
||||
while read -r line; do
|
||||
declare -a "found_source=($(sed -e 's/"/\\"/g' -e "s/'/\"/g" -e 's/[][`~!@#$%^&*():;<>.,?/\|{}=+-]/\\&/g' <<<"$line"))"
|
||||
found_source[0]=$(sed -e 's/\\\([`~!@#$%^&*():;<>.,?/\|{}=+-]\)/\1/g' <<<"${found_source[0]}")
|
||||
found_source[1]=$(sed -e 's/\\\([`~!@#$%^&*():;<>.,?/\|{}=+-]\)/\1/g' <<<"${found_source[1]}")
|
||||
case "${found_source[0]}" in
|
||||
*\(ID*\ Main\ Audio\))
|
||||
found_audio_source="${found_source[0]}"
|
||||
;;
|
||||
esac
|
||||
done < <(call_ffmpeg -loglevel info -extra_ips 192.168.188.21,192.168.188.76 -find_sources true -f libndi_newtek -i "dummy" 2>&1 | grep -Po "'(.+)'\s+'(.+)" | tee)
|
||||
while true; do
|
||||
found_audio_source="$(grep --line-buffered -m 1 --color=none -Po 'ndi-name = \K.+\(ID.* Main Audio.*\)$' < <(gst-device-monitor-1.0 -f Source/Network:application/x-ndi))"
|
||||
|
||||
if [ -z "$found_audio_source" ]; then
|
||||
offline=$((offline + 1))
|
||||
|
@ -59,21 +60,16 @@ while true; do
|
|||
offline=0
|
||||
fi
|
||||
|
||||
if ! is_ffmpeg_running && [ -n "$found_audio_source" ]; then
|
||||
echo "starting ffmpeg with audio source: $found_audio_source" >&2
|
||||
if ! is_gstreamer_running && [ -n "$found_audio_source" ]; then
|
||||
echo "starting gstreamer with audio source: $found_audio_source" >&2
|
||||
|
||||
call_ffmpeg -loglevel warning \
|
||||
-analyzeduration 1 -f libndi_newtek -extra_ips 192.168.188.21 -i "$found_audio_source" \
|
||||
-map a -c:a pcm_s16le -ar 48000 -ac 2 -f s16le - |
|
||||
call_gstreamer ndisrc ndi-name="$found_audio_source" "${url_address[@]}" ! ndisrcdemux name=demux \
|
||||
demux.audio ! queue ! audioconvert ! audio/x-raw, channels=2, rate=48000, format=S16LE ! filesink location=/dev/stdout |
|
||||
fakesilence --samplerate 48000 --channels 2 --silence-threshold 125ms |
|
||||
daemon_ffmpeg -loglevel warning \
|
||||
-ar 48000 -channels 2 -f s16le -i - \
|
||||
-map a -c:a flac -f ogg -content_type application/ogg "${target_url}"
|
||||
|
||||
# HACK - can't use the standard mpegts here, but liquidsoap will happily accept anything ffmpeg can parse (by default)… so let's just use nut here even though it feels super duper wrong
|
||||
elif is_ffmpeg_running && [ -z "$found_audio_source" ] && [ "$offline" -gt 0 ]; then
|
||||
echo "shutting down ffmpeg since no source has been found" >&2
|
||||
shutdown_ffmpeg # it won't shut down by itself unfortunately
|
||||
daemon_gstreamer filesrc location=/dev/stdin ! rawaudioparse use-sink-caps=false format=pcm pcm-format=s16le sample-rate=48000 num-channels=2 ! queue ! audioconvert ! audioresample ! flacenc ! oggmux ! shout2send mount="$TARGET_MOUNT" port="$TARGET_PORT" username="$TARGET_USERNAME" password="$TARGET_PASSWORD" ip="$TARGET_IP"
|
||||
elif is_gstreamer_running && [ -z "$found_audio_source" ] && [ "$offline" -gt 0 ]; then
|
||||
echo "shutting down gstreamer since no source has been found" >&2
|
||||
shutdown_gstreamer # it won't shut down by itself unfortunately
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
From 4906403902c507ed70389f88ce4371b7055ac0b9 Mon Sep 17 00:00:00 2001
|
||||
From: Carl Kittelberger <icedream@icedream.pw>
|
||||
Date: Sun, 20 Apr 2025 00:15:30 +0200
|
||||
Subject: [PATCH] Add gst-plugins-base-libs to depends
|
||||
|
||||
---
|
||||
.SRCINFO | 1 +
|
||||
PKGBUILD | 2 +-
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/.SRCINFO b/.SRCINFO
|
||||
index 0aa79d5..b0ba5d4 100644
|
||||
--- a/.SRCINFO
|
||||
+++ b/.SRCINFO
|
||||
@@ -10,6 +10,7 @@ pkgbase = gst-plugin-ndi-git
|
||||
makedepends = git
|
||||
makedepends = rust
|
||||
depends = gstreamer
|
||||
+ depends = gst-plugins-base-libs
|
||||
depends = libndi
|
||||
provides = gst-plugin-ndi
|
||||
conflicts = gst-plugin-ndi
|
||||
diff --git a/PKGBUILD b/PKGBUILD
|
||||
index 3a0bfce..d2dee08 100644
|
||||
--- a/PKGBUILD
|
||||
+++ b/PKGBUILD
|
||||
@@ -7,7 +7,7 @@ pkgdesc="GStreamer plugin for NDI"
|
||||
arch=("x86_64")
|
||||
url="https://github.com/teltek/gst-plugin-ndi"
|
||||
license=('LGPL')
|
||||
-depends=('gstreamer' 'libndi')
|
||||
+depends=('gstreamer' 'gst-plugins-base-libs' 'libndi')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
makedepends=('git' 'rust')
|
||||
--
|
||||
2.49.0
|
||||
|
Loading…
Reference in New Issue