Skip to content

Commit 6344286

Browse files
Steveclaude
andcommitted
feat: Improve recording and codec handling
- Add H264 codec preference for HLS recording mode - Implement SDP reordering to prefer H264 when using HLS - Remove CPU-intensive transcoding for non-HLS recording: - VP8 now saves directly to WebM without re-encoding - OPUS audio saves directly to WebM without decoding to WAV - Add clear status messages showing transcoding vs direct copy - Update both main process and subprocess recording logic - Move NDI scripts to dedicated ndi/ directory These changes significantly reduce CPU usage during recording by eliminating unnecessary transcoding operations when not required. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c72e1ce commit 6344286

4 files changed

Lines changed: 493 additions & 49 deletions

File tree

ndi/install_ndi.sh

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "Universal NDI support installer for Linux systems"
5+
echo "Supports Ubuntu, Debian, CentOS, RHEL, Fedora, openSUSE, Arch, and more"
6+
7+
NDI_VERSION="6"
8+
NDI_INSTALLER="Install_NDI_SDK_v${NDI_VERSION}_Linux.tar.gz"
9+
NDI_URL="https://downloads.ndi.tv/SDK/NDI_SDK_Linux/${NDI_INSTALLER}"
10+
TMP_DIR=$(mktemp -d)
11+
12+
# Detect architecture
13+
ARCH=$(uname -m)
14+
case $ARCH in
15+
x86_64)
16+
LIB_ARCH="x86_64-linux-gnu"
17+
GST_LIB_DIR="/usr/lib/x86_64-linux-gnu/gstreamer-1.0"
18+
;;
19+
aarch64|arm64)
20+
LIB_ARCH="aarch64-linux-gnu"
21+
GST_LIB_DIR="/usr/lib/aarch64-linux-gnu/gstreamer-1.0"
22+
;;
23+
armv7l|armhf)
24+
LIB_ARCH="arm-linux-gnueabihf"
25+
GST_LIB_DIR="/usr/lib/arm-linux-gnueabihf/gstreamer-1.0"
26+
;;
27+
*)
28+
echo "Warning: Unsupported architecture $ARCH, defaulting to x86_64"
29+
LIB_ARCH="x86_64-linux-gnu"
30+
GST_LIB_DIR="/usr/lib/x86_64-linux-gnu/gstreamer-1.0"
31+
;;
32+
esac
33+
34+
# Detect distribution and package manager
35+
detect_distro() {
36+
if [ -f /etc/os-release ]; then
37+
. /etc/os-release
38+
DISTRO=$ID
39+
VERSION_ID=${VERSION_ID:-""}
40+
elif [ -f /etc/redhat-release ]; then
41+
DISTRO="rhel"
42+
elif [ -f /etc/debian_version ]; then
43+
DISTRO="debian"
44+
else
45+
DISTRO="unknown"
46+
fi
47+
echo "Detected distribution: $DISTRO"
48+
}
49+
50+
# Install packages based on distribution
51+
install_dependencies() {
52+
echo "Installing build dependencies..."
53+
54+
case $DISTRO in
55+
ubuntu|debian)
56+
sudo apt-get update
57+
sudo apt-get install -y build-essential cmake curl git pkg-config \
58+
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
59+
;;
60+
fedora)
61+
sudo dnf install -y gcc gcc-c++ cmake curl git pkgconfig \
62+
gstreamer1-devel gstreamer1-plugins-base-devel
63+
GST_LIB_DIR="/usr/lib64/gstreamer-1.0"
64+
;;
65+
centos|rhel)
66+
# Enable EPEL for additional packages
67+
if ! rpm -q epel-release &>/dev/null; then
68+
sudo yum install -y epel-release || sudo dnf install -y epel-release
69+
fi
70+
sudo yum install -y gcc gcc-c++ cmake curl git pkgconfig \
71+
gstreamer1-devel gstreamer1-plugins-base-devel || \
72+
sudo dnf install -y gcc gcc-c++ cmake curl git pkgconfig \
73+
gstreamer1-devel gstreamer1-plugins-base-devel
74+
GST_LIB_DIR="/usr/lib64/gstreamer-1.0"
75+
;;
76+
opensuse*|sles)
77+
sudo zypper install -y gcc gcc-c++ cmake curl git pkg-config \
78+
gstreamer-devel gstreamer-plugins-base-devel
79+
GST_LIB_DIR="/usr/lib64/gstreamer-1.0"
80+
;;
81+
arch|manjaro)
82+
sudo pacman -Sy --noconfirm base-devel cmake curl git pkgconf \
83+
gstreamer gst-plugins-base
84+
GST_LIB_DIR="/usr/lib/gstreamer-1.0"
85+
;;
86+
alpine)
87+
sudo apk update
88+
sudo apk add build-base cmake curl git pkgconfig \
89+
gstreamer-dev gst-plugins-base-dev
90+
GST_LIB_DIR="/usr/lib/gstreamer-1.0"
91+
;;
92+
*)
93+
echo "Warning: Unknown distribution. Attempting generic installation..."
94+
echo "Please ensure you have: gcc, cmake, curl, git, pkg-config, gstreamer development headers"
95+
read -p "Continue anyway? [y/N] " -n 1 -r
96+
echo
97+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
98+
exit 1
99+
fi
100+
;;
101+
esac
102+
}
103+
104+
# Check and install Rust/Cargo
105+
install_rust() {
106+
echo "Checking for Rust installation..."
107+
108+
if command -v rustc &> /dev/null && command -v cargo &> /dev/null; then
109+
echo "Rust and Cargo are already installed:"
110+
rustc --version
111+
cargo --version
112+
113+
# Check if Rust is reasonably recent (1.70+)
114+
RUST_VERSION=$(rustc --version | cut -d' ' -f2 | cut -d'.' -f1-2)
115+
if [ "$(printf '%s\n' "1.70" "$RUST_VERSION" | sort -V | head -n1)" = "1.70" ]; then
116+
echo "Rust version is sufficient."
117+
return 0
118+
else
119+
echo "Rust version is too old, updating..."
120+
fi
121+
else
122+
echo "Rust/Cargo not found. Installing..."
123+
fi
124+
125+
# Install or update Rust using rustup
126+
if command -v rustup &> /dev/null; then
127+
echo "Updating Rust via rustup..."
128+
rustup update stable
129+
else
130+
echo "Installing Rust via rustup..."
131+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
132+
133+
# Source the cargo environment
134+
if [ -f "$HOME/.cargo/env" ]; then
135+
. "$HOME/.cargo/env"
136+
fi
137+
fi
138+
139+
# Verify installation
140+
if command -v rustc &> /dev/null && command -v cargo &> /dev/null; then
141+
echo "Rust installation successful:"
142+
rustc --version
143+
cargo --version
144+
else
145+
echo "Error: Rust installation failed"
146+
exit 1
147+
fi
148+
}
149+
150+
# Create fallback GStreamer plugin directory if it doesn't exist
151+
ensure_gstreamer_dir() {
152+
if [ ! -d "$GST_LIB_DIR" ]; then
153+
echo "GStreamer plugin directory not found at $GST_LIB_DIR"
154+
# Try common alternatives
155+
ALTERNATIVE_DIRS=(
156+
"/usr/lib/gstreamer-1.0"
157+
"/usr/lib64/gstreamer-1.0"
158+
"/usr/local/lib/gstreamer-1.0"
159+
"/usr/lib/$LIB_ARCH/gstreamer-1.0"
160+
)
161+
162+
for dir in "${ALTERNATIVE_DIRS[@]}"; do
163+
if [ -d "$dir" ]; then
164+
echo "Using alternative GStreamer directory: $dir"
165+
GST_LIB_DIR="$dir"
166+
return 0
167+
fi
168+
done
169+
170+
echo "Creating GStreamer plugin directory: $GST_LIB_DIR"
171+
sudo mkdir -p "$GST_LIB_DIR"
172+
fi
173+
}
174+
175+
# Main installation process
176+
main() {
177+
echo "Installing NDI SDK version ${NDI_VERSION}"
178+
179+
# Detect system
180+
detect_distro
181+
182+
# Install dependencies
183+
install_dependencies
184+
185+
# Install Rust if needed
186+
install_rust
187+
188+
# Download and install NDI SDK
189+
cd "$TMP_DIR"
190+
echo "Downloading NDI SDK..."
191+
curl -LO "$NDI_URL"
192+
193+
echo "Extracting NDI SDK..."
194+
tar -xzf "$NDI_INSTALLER"
195+
196+
echo "Running NDI installer..."
197+
yes | PAGER="cat" sh "./Install_NDI_SDK_v${NDI_VERSION}_Linux.sh"
198+
199+
echo "Installing NDI libraries..."
200+
if [ -d "NDI SDK for Linux/lib/$LIB_ARCH" ]; then
201+
sudo cp -P "NDI SDK for Linux/lib/$LIB_ARCH/"* /usr/local/lib/
202+
else
203+
echo "Warning: Architecture-specific NDI libraries not found, trying x86_64..."
204+
sudo cp -P "NDI SDK for Linux/lib/x86_64-linux-gnu/"* /usr/local/lib/
205+
fi
206+
sudo ldconfig
207+
208+
echo "Creating compatibility symlink..."
209+
sudo ln -sf /usr/local/lib/libndi.so.${NDI_VERSION} /usr/local/lib/libndi.so.5
210+
211+
echo "Cleaning up NDI installation..."
212+
cd - > /dev/null
213+
rm -rf "$TMP_DIR"
214+
215+
echo "Building GStreamer NDI Plugin..."
216+
217+
# Ensure GStreamer directory exists
218+
ensure_gstreamer_dir
219+
220+
# Clone and build the plugin
221+
PLUGIN_DIR="gst-plugin-ndi"
222+
if [ -d "$PLUGIN_DIR" ]; then
223+
echo "Updating existing plugin repository..."
224+
cd "$PLUGIN_DIR"
225+
git pull
226+
else
227+
echo "Cloning plugin repository..."
228+
git clone https://github.com/steveseguin/gst-plugin-ndi.git
229+
cd "$PLUGIN_DIR"
230+
fi
231+
232+
cargo build --release
233+
234+
echo "Installing GStreamer NDI plugin..."
235+
sudo install target/release/libgstndi.so "$GST_LIB_DIR/"
236+
sudo ldconfig
237+
238+
echo "Testing GStreamer NDI plugin..."
239+
if gst-inspect-1.0 ndi &>/dev/null; then
240+
echo "✓ GStreamer NDI plugin installed successfully!"
241+
gst-inspect-1.0 ndi | head -5
242+
else
243+
echo "⚠ Warning: GStreamer NDI plugin test failed. Manual verification may be needed."
244+
fi
245+
246+
cd ..
247+
248+
echo ""
249+
echo "🎉 NDI SDK installation complete!"
250+
echo ""
251+
echo "Installed components:"
252+
echo " ✓ NDI SDK v${NDI_VERSION}"
253+
echo " ✓ Rust $(rustc --version | cut -d' ' -f2)"
254+
echo " ✓ GStreamer NDI plugin"
255+
echo ""
256+
echo "You may need to restart your terminal or run: source ~/.cargo/env"
257+
}
258+
259+
# Run main function
260+
main

0 commit comments

Comments
 (0)