NDI6 SDK + DistroAV obs-studio plugin (#368924)
This commit is contained in:
@@ -9308,6 +9308,12 @@
|
||||
githubId = 1447245;
|
||||
name = "Robin Gloster";
|
||||
};
|
||||
globule655 = {
|
||||
email = "globule655@gmail.com";
|
||||
github = "globule655";
|
||||
githubId = 47015416;
|
||||
name = "globule655";
|
||||
};
|
||||
gm6k = {
|
||||
email = "nix@quidecco.pl";
|
||||
name = "Isidor Zeuner";
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
droidcam-obs = callPackage ./droidcam-obs { };
|
||||
|
||||
distroav = qt6Packages.callPackage ./distroav { };
|
||||
|
||||
input-overlay = qt6Packages.callPackage ./input-overlay.nix { };
|
||||
|
||||
looking-glass-obs = callPackage ./looking-glass-obs.nix { };
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
obs-studio,
|
||||
cmake,
|
||||
qtbase,
|
||||
ndi-6,
|
||||
curl,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "distroav";
|
||||
version = "6.0.0";
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
qtbase
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
obs-studio
|
||||
qtbase
|
||||
ndi-6
|
||||
curl
|
||||
];
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "DistroAV";
|
||||
repo = "DistroAV";
|
||||
tag = version;
|
||||
hash = "sha256-pr/5XCLo5fzergIQrYFC9o9K+KuP4leDk5/oRe5ct9Q=";
|
||||
};
|
||||
|
||||
# Modify plugin-main.cpp file to fix ndi libs path
|
||||
patches = [ ./hardcode-ndi-path.patch ];
|
||||
|
||||
postPatch = ''
|
||||
# Add path (variable added in hardcode-ndi-path.patch
|
||||
substituteInPlace src/plugin-main.cpp --replace-fail "@NDI@" "${ndi-6}"
|
||||
|
||||
# Replace bundled NDI SDK with the upstream version
|
||||
# (This fixes soname issues)
|
||||
rm -rf lib/ndi
|
||||
ln -s ${ndi-6}/include lib/ndi
|
||||
'';
|
||||
|
||||
cmakeFlags = [ "-DENABLE_QT=ON" ];
|
||||
|
||||
env.NIX_CFLAGS_COMPILE = "-Wno-deprecated-declarations";
|
||||
|
||||
dontWrapQtApps = true;
|
||||
|
||||
meta = {
|
||||
description = "Network A/V plugin for OBS Studio (formerly obs-ndi)";
|
||||
homepage = "https://github.com/DistroAV/DistroAV";
|
||||
license = with lib.licenses; [ gpl2 ];
|
||||
maintainers = with lib.maintainers; [ globule655 ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
diff --git a/src/plugin-main.cpp b/src/plugin-main.cpp
|
||||
index 0d94add..617af73 100644
|
||||
--- a/src/plugin-main.cpp
|
||||
+++ b/src/plugin-main.cpp
|
||||
@@ -369,14 +369,7 @@ const NDIlib_v5 *load_ndilib()
|
||||
if (!temp_path.isEmpty()) {
|
||||
locations << temp_path;
|
||||
}
|
||||
-#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
- // Linux, MacOS
|
||||
- // https://github.com/DistroAV/DistroAV/blob/master/lib/ndi/NDI%20SDK%20Documentation.pdf
|
||||
- // "6.1 LOCATING THE LIBRARY
|
||||
- // ... the redistributable on MacOS is installed within `/usr/local/lib` ..."
|
||||
- locations << "/usr/lib";
|
||||
- locations << "/usr/local/lib";
|
||||
-#endif
|
||||
+ locations << "@NDI@/lib";
|
||||
auto lib_path = QString();
|
||||
@@ -0,0 +1,86 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchurl,
|
||||
avahi,
|
||||
obs-studio-plugins,
|
||||
}:
|
||||
|
||||
let
|
||||
versionJSON = lib.importJSON ./version.json;
|
||||
ndiPlatform =
|
||||
if stdenv.hostPlatform.isAarch64 then
|
||||
"aarch64-rpi4-linux-gnueabi"
|
||||
else if stdenv.hostPlatform.isAarch32 then
|
||||
"arm-rpi2-linux-gnueabihf"
|
||||
else if stdenv.hostPlatform.isx86_64 then
|
||||
"x86_64-linux-gnu"
|
||||
else
|
||||
throw "unsupported platform for NDI SDK";
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ndi-6";
|
||||
version = versionJSON.version;
|
||||
majorVersion = lib.versions.major version;
|
||||
installerName = "Install_NDI_SDK_v${majorVersion}_Linux";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://downloads.ndi.tv/SDK/NDI_SDK_Linux/${installerName}.tar.gz";
|
||||
hash = versionJSON.hash;
|
||||
};
|
||||
|
||||
buildInputs = [ avahi ];
|
||||
|
||||
unpackPhase = ''
|
||||
unpackFile $src
|
||||
echo y | ./${installerName}.sh
|
||||
sourceRoot="NDI SDK for Linux";
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
mv bin/${ndiPlatform} $out/bin
|
||||
for i in $out/bin/*; do
|
||||
if [ -L "$i" ]; then continue; fi
|
||||
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$i"
|
||||
done
|
||||
patchelf --set-rpath "${avahi}/lib:${stdenv.cc.libc}/lib" $out/bin/ndi-record
|
||||
patchelf --set-rpath "${avahi}/lib:${stdenv.cc.libc}/lib" $out/bin/ndi-free-audio
|
||||
mv lib/${ndiPlatform} $out/lib
|
||||
for i in $out/lib/*; do
|
||||
if [ -L "$i" ]; then continue; fi
|
||||
patchelf --set-rpath "${avahi}/lib:${stdenv.cc.libc}/lib" "$i"
|
||||
done
|
||||
rm $out/bin/libndi.so.${majorVersion}
|
||||
ln -s $out/lib/libndi.so.${version} $out/bin/libndi.so.${majorVersion}
|
||||
# Fake ndi version 5 for compatibility with DistroAV (obs plugin using NDI)
|
||||
ln -s $out/lib/libndi.so.${version} $out/bin/libndi.so.5
|
||||
mv include examples $out/
|
||||
mkdir -p $out/share/doc/ndi-6
|
||||
mv licenses $out/share/doc/ndi-6/licenses
|
||||
mv documentation/* $out/share/doc/ndi-6/
|
||||
'';
|
||||
|
||||
# Stripping breaks ndi-record.
|
||||
dontStrip = true;
|
||||
|
||||
passthru.tests = {
|
||||
inherit (obs-studio-plugins) distroav;
|
||||
};
|
||||
|
||||
passthru.updateScript = ./update.py;
|
||||
|
||||
meta = {
|
||||
homepage = "https://ndi.video/ndi-sdk/";
|
||||
description = "NDI Software Developer Kit";
|
||||
platforms = [
|
||||
"x86_64-linux"
|
||||
"i686-linux"
|
||||
"aarch64-linux"
|
||||
"armv7l-linux"
|
||||
];
|
||||
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
|
||||
license = lib.licenses.unfree;
|
||||
maintainers = with lib.maintainers; [ globule655 ];
|
||||
};
|
||||
}
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i python -p "python3.withPackages (ps: with ps; [ ps.absl-py ps.requests ])"
|
||||
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import os.path
|
||||
import tarfile
|
||||
|
||||
import requests
|
||||
from absl import app, flags
|
||||
|
||||
BASE_NAME = "Install_NDI_SDK_v6_Linux"
|
||||
NDI_SDK_URL = f"https://downloads.ndi.tv/SDK/NDI_SDK_Linux/{BASE_NAME}.tar.gz"
|
||||
NDI_EXEC = f"{BASE_NAME}.sh"
|
||||
|
||||
NDI_ARCHIVE_MAGIC = b"__NDI_ARCHIVE_BEGIN__\n"
|
||||
|
||||
FLAG_out = flags.DEFINE_string("out", None, "Path to read/write version.json from/to.")
|
||||
|
||||
|
||||
def find_version_json() -> str:
|
||||
if FLAG_out.value:
|
||||
return FLAG_out.value
|
||||
try_paths = ["pkgs/by-name/nd/ndi-6/version.json", "version.json"]
|
||||
for path in try_paths:
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
raise Exception(
|
||||
"Couldn't figure out where to write version.json; try specifying --out"
|
||||
)
|
||||
|
||||
|
||||
def fetch_tarball() -> bytes:
|
||||
r = requests.get(NDI_SDK_URL)
|
||||
r.raise_for_status()
|
||||
return r.content
|
||||
|
||||
|
||||
def read_version(tarball: bytes) -> str:
|
||||
# Find the inner script.
|
||||
outer_tarfile = tarfile.open(fileobj=io.BytesIO(tarball), mode="r:gz")
|
||||
eula_script = outer_tarfile.extractfile(NDI_EXEC).read()
|
||||
|
||||
# Now find the archive embedded within the script.
|
||||
archive_start = eula_script.find(NDI_ARCHIVE_MAGIC) + len(NDI_ARCHIVE_MAGIC)
|
||||
inner_tarfile = tarfile.open(
|
||||
fileobj=io.BytesIO(eula_script[archive_start:]), mode="r:gz"
|
||||
)
|
||||
|
||||
# Now find Version.txt...
|
||||
version_txt = (
|
||||
inner_tarfile.extractfile("NDI SDK for Linux/Version.txt")
|
||||
.read()
|
||||
.decode("utf-8")
|
||||
)
|
||||
_, _, version = version_txt.strip().partition(" v")
|
||||
return version
|
||||
|
||||
|
||||
def main(argv):
|
||||
tarball = fetch_tarball()
|
||||
|
||||
sha256 = hashlib.sha256(tarball).hexdigest()
|
||||
version = {
|
||||
"hash": f"sha256:{sha256}",
|
||||
"version": read_version(tarball),
|
||||
}
|
||||
|
||||
out_path = find_version_json()
|
||||
with open(out_path, "w") as f:
|
||||
json.dump(version, f)
|
||||
f.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(main)
|
||||
@@ -0,0 +1 @@
|
||||
{"hash": "sha256-6iqjexwILth2muLpXWQjDVTvOuMq4jM8KBYnpPmViU8=", "version": "6.1.1"}
|
||||
Reference in New Issue
Block a user