diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index a610d9337460..0b25f611f652 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -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"; diff --git a/pkgs/applications/video/obs-studio/plugins/default.nix b/pkgs/applications/video/obs-studio/plugins/default.nix index 0f708f83f72d..2131744b0a54 100644 --- a/pkgs/applications/video/obs-studio/plugins/default.nix +++ b/pkgs/applications/video/obs-studio/plugins/default.nix @@ -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 { }; diff --git a/pkgs/applications/video/obs-studio/plugins/distroav/default.nix b/pkgs/applications/video/obs-studio/plugins/distroav/default.nix new file mode 100644 index 000000000000..6654cb08ac40 --- /dev/null +++ b/pkgs/applications/video/obs-studio/plugins/distroav/default.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; + }; +} diff --git a/pkgs/applications/video/obs-studio/plugins/distroav/hardcode-ndi-path.patch b/pkgs/applications/video/obs-studio/plugins/distroav/hardcode-ndi-path.patch new file mode 100644 index 000000000000..567d5c4fbcb7 --- /dev/null +++ b/pkgs/applications/video/obs-studio/plugins/distroav/hardcode-ndi-path.patch @@ -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(); diff --git a/pkgs/by-name/nd/ndi-6/package.nix b/pkgs/by-name/nd/ndi-6/package.nix new file mode 100644 index 000000000000..1e121b7e5764 --- /dev/null +++ b/pkgs/by-name/nd/ndi-6/package.nix @@ -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 ]; + }; +} diff --git a/pkgs/by-name/nd/ndi-6/update.py b/pkgs/by-name/nd/ndi-6/update.py new file mode 100755 index 000000000000..1f828dab2275 --- /dev/null +++ b/pkgs/by-name/nd/ndi-6/update.py @@ -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) diff --git a/pkgs/by-name/nd/ndi-6/version.json b/pkgs/by-name/nd/ndi-6/version.json new file mode 100644 index 000000000000..c4142f42d71f --- /dev/null +++ b/pkgs/by-name/nd/ndi-6/version.json @@ -0,0 +1 @@ +{"hash": "sha256-6iqjexwILth2muLpXWQjDVTvOuMq4jM8KBYnpPmViU8=", "version": "6.1.1"}