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 \
|
--mount=type=cache,target=/tmp/build/.cache \
|
||||||
ulimit -n 1024 && makepkg -sr --noconfirm
|
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
|
# FFMPEG-NDI
|
||||||
|
|
||||||
|
@ -267,7 +313,7 @@ RUN chmod -v +x *.sh
|
||||||
FROM scratch as packages
|
FROM scratch as packages
|
||||||
|
|
||||||
COPY --from=ndi-sdk /usr/src/ndi-sdk/*.pkg.* /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/
|
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=yay /usr/src/yay/*.pkg.* /tmp/
|
||||||
COPY --from=ndi-sdk /usr/src/ndi-sdk/*.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 \
|
RUN \
|
||||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||||
--mount=type=cache,target=/tmp/build/.cache \
|
--mount=type=cache,target=/tmp/build/.cache \
|
||||||
|
@ -293,7 +339,7 @@ RUN \
|
||||||
RUN \
|
RUN \
|
||||||
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
--mount=type=cache,target=/var/cache/pacman/pkg,sharing=locked \
|
||||||
--mount=type=cache,target=/tmp/build/.cache \
|
--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/
|
COPY --from=fakesilence /usr/local/bin/fakesilence /usr/local/bin/
|
||||||
|
|
||||||
|
|
|
@ -1,57 +1,58 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
target_url="${1:-icecast://source:source@127.0.0.1:61120/main}"
|
#target_url="${1:-icecast://source:source@127.0.0.1:61120/main}"
|
||||||
ffmpeg_pids=()
|
: "${TARGET_IP:=127.0.0.1}"
|
||||||
|
: "${TARGET_PORT:=61120}"
|
||||||
|
: "${TARGET_MOUNT:=/main}"
|
||||||
|
: "${TARGET_USERNAME:=source}"
|
||||||
|
: "${TARGET_PASSWORD:=source}"
|
||||||
|
: "${NDI_FEEDER_EXTRA_IP:=}"
|
||||||
|
|
||||||
call_ffmpeg() {
|
gstreamer_pids=()
|
||||||
command ffmpeg -hide_banner "$@"
|
|
||||||
|
call_gstreamer() {
|
||||||
|
command gst-launch-1.0 "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
daemon_ffmpeg() {
|
daemon_gstreamer() {
|
||||||
call_ffmpeg "$@" &
|
call_gstreamer "$@" &
|
||||||
ffmpeg_pids+=($!)
|
gstreamer_pids+=($!)
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown_ffmpeg() {
|
shutdown_gstreamer() {
|
||||||
if is_ffmpeg_running; then
|
if is_gstreamer_running; then
|
||||||
kill "$ffmpeg_pid" || true
|
kill "$gstreamer_pid" || true
|
||||||
for t in $(seq 0 10); do
|
for t in $(seq 0 10); do
|
||||||
if ! kill -0 "$ffmpeg_pid"; then
|
if ! kill -0 "$gstreamer_pid"; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
if kill -0 "$ffmpeg_pid"; then
|
if kill -0 "$gstreamer_pid"; then
|
||||||
kill -9 "$ffmpeg_pid" || true
|
kill -9 "$gstreamer_pid" || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
ffmpeg_pid=
|
gstreamer_pid=
|
||||||
}
|
}
|
||||||
|
|
||||||
is_ffmpeg_running() {
|
is_gstreamer_running() {
|
||||||
[ -n "$ffmpeg_pid" ] && kill -0 "$ffmpeg_pid"
|
[ -n "$gstreamer_pid" ] && kill -0 "$gstreamer_pid"
|
||||||
}
|
}
|
||||||
|
|
||||||
on_exit() {
|
on_exit() {
|
||||||
shutdown_ffmpeg
|
shutdown_gstreamer
|
||||||
}
|
}
|
||||||
trap on_exit EXIT
|
trap on_exit EXIT
|
||||||
|
|
||||||
offline=0
|
offline=0
|
||||||
|
|
||||||
while true; do
|
url_address=()
|
||||||
found_audio_source=""
|
if [ -n "$NDI_FEEDER_EXTRA_IP" ]; then
|
||||||
|
url_address=("url-address=$NDI_FEEDER_EXTRA_IP:5961")
|
||||||
|
fi
|
||||||
|
|
||||||
while read -r line; do
|
while true; do
|
||||||
declare -a "found_source=($(sed -e 's/"/\\"/g' -e "s/'/\"/g" -e 's/[][`~!@#$%^&*():;<>.,?/\|{}=+-]/\\&/g' <<<"$line"))"
|
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))"
|
||||||
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)
|
|
||||||
|
|
||||||
if [ -z "$found_audio_source" ]; then
|
if [ -z "$found_audio_source" ]; then
|
||||||
offline=$((offline + 1))
|
offline=$((offline + 1))
|
||||||
|
@ -59,21 +60,16 @@ while true; do
|
||||||
offline=0
|
offline=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! is_ffmpeg_running && [ -n "$found_audio_source" ]; then
|
if ! is_gstreamer_running && [ -n "$found_audio_source" ]; then
|
||||||
echo "starting ffmpeg with audio source: $found_audio_source" >&2
|
echo "starting gstreamer with audio source: $found_audio_source" >&2
|
||||||
|
|
||||||
call_ffmpeg -loglevel warning \
|
call_gstreamer ndisrc ndi-name="$found_audio_source" "${url_address[@]}" ! ndisrcdemux name=demux \
|
||||||
-analyzeduration 1 -f libndi_newtek -extra_ips 192.168.188.21 -i "$found_audio_source" \
|
demux.audio ! queue ! audioconvert ! audio/x-raw, channels=2, rate=48000, format=S16LE ! filesink location=/dev/stdout |
|
||||||
-map a -c:a pcm_s16le -ar 48000 -ac 2 -f s16le - |
|
|
||||||
fakesilence --samplerate 48000 --channels 2 --silence-threshold 125ms |
|
fakesilence --samplerate 48000 --channels 2 --silence-threshold 125ms |
|
||||||
daemon_ffmpeg -loglevel warning \
|
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"
|
||||||
-ar 48000 -channels 2 -f s16le -i - \
|
elif is_gstreamer_running && [ -z "$found_audio_source" ] && [ "$offline" -gt 0 ]; then
|
||||||
-map a -c:a flac -f ogg -content_type application/ogg "${target_url}"
|
echo "shutting down gstreamer since no source has been found" >&2
|
||||||
|
shutdown_gstreamer # it won't shut down by itself unfortunately
|
||||||
# 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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sleep 1
|
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