1
0
Fork 0

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
Icedream 2025-04-20 16:19:43 +02:00
parent d2df62e51c
commit 57dbec3aac
Signed by: icedream
GPG Key ID: 468BBEEBB9EC6AEA
3 changed files with 125 additions and 45 deletions

View File

@ -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/

View File

@ -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

View File

@ -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