Skip to content
Trouffman edited this page Nov 12, 2025 · 88 revisions

Development

NDI License Requirements Summary

Per

Licence Summary (not legal advice) :

  • Provide a link to NDI.video in
    • in DistroAV app
    • on DistroAV web site
    • in DistroAV documentation
  • Use "NDI®" along with the statement “NDI® is a registered trademark of Vizrt NDI AB” located on the same page near the mark where it is first used, or at the bottom of the page in footnotes. You are required to use the registered trademark designation only on the first use of the word NDI within a single document.
  • Your application’s About Box and any other locations where trademark attribution is provided should also specifically indicate that “NDI® is a registered trademark of Vizrt NDI AB”.
  • Provide a user link to the NDI-provided download of this application at NDI Redist. At runtime, the location of the NDI runtime DLLs can be determined from the environment variable NDI_RUNTIME_DIR_V6.

Other References:

Licence usage for the DistroAV

Following discussion/emails in Sept. 2025 between DistroAV maintainer @trouffman and NDI/Vizrt leaders, the following has been confirmed for the purpose of the DistroAV project.

The discussion with NDI confirmed that, for the DistroAV project, we should use the NDI name & Registration Mark on the about screen, then we are not required to use it in the rest of the software/interface. This does not remove the need on other medium (website/documentation).

Any questions about this should be addressed to the official DistroAV email/contact on distroav.org.

Code Style(s)

General Naming Conventions

  • Methods: camelCase
  • Variables: snake_case

Third-Party Library Conventions

Follow the naming conventions of third-party libraries when interfacing with them or mimicking their functionality.
For example, if you are writing a method that behaves like an OBS or Qt method, use that library's naming conventions.

This can sometimes be ambiguous; the spirit of the convention matters more than the [literal] letter of it.

Specific Libraries (in general)

  • NDI:

    • This code is C that uses snake_case.
  • OBS (libobs/obs-module/obs-frontend-api/etc):
    OBS Naming Convention

    • This code is approximately 55% C using snake_case and 35% C++ using camelCase and PascalCase.
  • Qt (Core/Widgets/Network/etc):

    • This code is C++ that uses camelCase for methods and PascalCase for class names.
  • stdlib:

    • This code is C++ that uses snake_case.
  • libcurl:

    • This code is C that uses snake_case.
  • Other Libraries:

    • Follow the specific library's naming convention.

Note

The current code standard is somewhat scattered.
A future pull request (PR) should be made to address and standardize this.

Building

OBS build requirement

As a good starting point, make sure you have everything the OBS project require to build / dev Read the OBS project Wiki for your environment.

Windows

Build from the source code

In PowerShell Core 7+ terminal, in a folder that you want to clone to:

git clone https://github.com/DistroAV/DistroAV.git
cd DistroAV
First build
.github/scripts/Build-Windows.ps1
.github/scripts/Package-Windows.ps1 -BuildInstaller

Or combine them:

.github/scripts/Build-Windows.ps1 && .github/scripts/Package-Windows.ps1 -BuildInstaller

Tip(s)

Build and run the versioned installer:

.github/scripts/Build-Windows.ps1 && .github/scripts/Package-Windows.ps1 -BuildInstaller && release\distroav-<version>-windows-x64-Installer.exe

In an Admin PowerShell, build and directly copy to OBS:

.github\scripts\Build-Windows.ps1 && xcopy /s /y /c .\release\RelWithDebInfo\* "$env:ProgramFiles\obs-studio\"

Troubleshooting

See Help .github/scripts/Build-Windows.ps1 for more details.

MacOS

In terminal:

git clone https://github.com/DistroAV/DistroAV.git
cd DistroAV
export CI=
export GITHUB_EVENT_NAME=
.github/scripts/build-macos
...
.github/scripts/package-macos
...
cp -r release/RelWithDebInfo/distroav.plugin ~/Library/Application\ Support/obs-studio/plugins/
...

See build-macos --help for more details.

Combine all 3:

.github/scripts/build-macos && .github/scripts/package-macos && cp -r release/RelWithDebInfo/distroav.plugin ~/Library/Application\ Support/obs-studio/plugins/

If you get a No CMAKE_C_COMPILER could be found error:

  1. Launch XCode
    -or-
  2. Run sudo xcode-select --reset

If you get a requires CI environment error:

  1. Get the list of possible preset: cmake --list-presets
  2. Configure the preset for cmake to use: cmake --preset macos

more info on obs build doc

Known Issues

MacOS SDK Version too low or not detected correctly. Context : cmake 4.0.0+ and OBS source before commit 8f1bcc179869ee864ab0dee70dc3ccdf6bec9e11 throw an error during the "Configure OBS sources" step. Reason : changes in behavior in cmake 4+ for SDK detection. Fix : Update the compilerconfig.cmake file in the .deps/obs-studio-xx.x.x folder witht he same changes as the branch linked above. Validity : obs-deps 2025-03-06 (latest when adding this note) still have the issue.) TODO: Remove this note when new deps are released and used.

Linux

NOTE: Only Debian and Ubuntu are officially supported

In terminal (Debian):

git clone https://github.com/DistroAV/DistroAV.git
cd DistroAV
.github/scripts/build-ubuntu
...
.github/scripts/package-ubuntu --package

Subsequent builds can be sped up by using build-ubuntu --skip-deps.
See build-ubuntu --help for more details.

Install:

sudo dpkg -i release/distroav-[version]-[architecture]-linux-gnu.deb

Manual copy

Debian
sudo cp -r release/RelWithDebInfo/lib/x86_64-linux-gnu/obs-plugins/* /usr/local/lib/x86_64-linux-gnu/obs-plugins/
...
sudo cp -r release/RelWithDebInfo/share/obs/obs-plugins/* /usr/local/share/obs/obs-plugins/
...
sudo ldconfig
Ubuntu
sudo cp -r release/RelWithDebInfo/lib/x86_64-linux-gnu/obs-plugins/* /usr/lib/x86_64-linux-gnu/obs-plugins/
...
sudo cp -r release/RelWithDebInfo/share/obs/obs-plugins/* /usr/share/obs/obs-plugins/
...
sudo ldconfig

Raspbian

# install prerequisites
apt install -y zsh libobs-dev libgles2-mesa-dev

# clone and cd into the repo, all following instructions will be given relative to DistroAV/
git clone https://github.com/DistroAV/DistroAV.git
cd DistroAV

# I had to comment out line 38 that adds the ppa in DistroAV/.github/scripts/utils.zsh/setup_linux
# 38   # sudo add-apt-repository --yes ppa:obsproject/obs-studio
# if you don't comment out this line, you may run into the error described in https://github.com/DistroAV/DistroAV/issues/987

# install the plugin locally
cp release/RelWithDebInfo/lib/aarch64-linux-gnu/obs-plugins/distroav.so /usr/lib/aarch64-linux-gnu/obs-plugins/distroav.so
cp -r release/RelWithDebInfo/share/obs/obs-plugins/distroav /usr/share/obs/obs-plugins/

# bundle the plugin to install on other Pis
# This will create an `distroav-<version>-aarch64-linux-gnu.tar.xz` package,
# e.g.: distroav-6.0.0-aarch64-linux-gnu.tar.xz
.github/scripts/package-linux

# Install on another Pi
tar vxf distroav-<version>-aarch64-linux-gnu.tar.xz -C distroav
cp distroav/lib/aarch64-linux-gnu/obs-plugins/distroav.so /usr/lib/aarch64-linux-gnu/obs-plugins/distroav.so
cp -r distroav/share/obs/obs-plugins/distroav /usr/share/obs/obs-plugins/

Formatting

Install Pre-requisities (Linux / MacOS)

Requires [obsproject/tools/]clang-format@17, cmakelang, and zsh installed.

Requires brew installed; From https://brew.sh/ ...

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

...then follow the instructions printed out at the end of install.

From .github\actions\run-clang-format\action.yaml ...

brew install --quiet obsproject/tools/clang-format@17

...then follow the instructions printed out at the end of install.

Gersemi package shoul dbe the one from the OBS proejct and not the public/global one if running on your machine.

brew install --quiet obsproject/tools/gersemi

Linux/MacOS

Open a terminal:

./tools/Format.sh

-or-

./build-aux/run-clang-format
./build-aux/run-gersemi

Windows (WSL)

Visual Studio Code

  1. Install the Visual Studio Code clang extension
  2. Right click in/on a file and Format Document. Mac: Option-Shift-F

Manually (safe)

...
clang-format-17 -i src/distroav-filter.cpp
clang-format-17 -i src/distroav-source.cpp
clang-format-17 -i src/plugin-main.cpp
...

Scripted (risky)

This is very hacky and can freak out Windows git clients!

  1. Open a WSL Ubuntu terminal to DistroAV
  2. Install zsh (needed to run run-clang-format/run-cmake-format)
brew install zsh

...then follow the instructions printed out at the end of install.

  1. Restore the unix symlinks (this freaks out Windows GitKraken)
pushd build-aux
rm run-clang-format
rm run-cmake-format
git restore run-clang-format
git restore run-cmake-format
popd

A script that automates this is:
(I am tempted to check this into the repo)

#!/usr/bin/env zsh

if [[ $# -eq 0 ]]; then
    echo "Usage: $0 <on|off>"
    exit 1
fi

links=("run-clang-format" "run-cmake-format")

script_dir=$(dirname "$(realpath "$0")")

echo "Before:"
ls -la ${script_dir}

if [[ $1 == "on" ]]; then
    echo "Restoring unix links"
    for link in ${links[@]}; do
        rm "${script_dir}/$link"
        git restore "${script_dir}/$link"
    done
elif [[ $1 == "off" ]]; then
    echo "Removing unix links"
    for link in ${links[@]}; do
        rm -f "${script_dir}/$link"
    done
    echo "You will need to manually restore them from the Windows side"
fi

echo "After:"
ls -la ${script_dir}

Usage: ./build-aux/wsl.zsh on or ./build-aux/wsl.zsh off

  1. Replace Windows CRLF with Unix CR
brew install dos2unix
dos2unix  build-aux/.run-format.zsh
  1. Finally, run the scripts:
./tools/Format.sh

-or-

./build-aux/run-clang-format

Supress Formatting/Code Errors/Warnings

I keep forgetting how to do this, so adding a note here.
On rare/sparing/appropriate basis, suppress Lint errors with:

#if defined(__linux__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfoo"
#endif
    ...foo code...
#if defined(__linux__)
#pragma GCC diagnostic pop
#endif

Replace __linux__ w/ __GNUC__ or WIN32 type of macros as appropriate.

String Translations

For every translation, if you are not a native or expert speaker in the destination language, check translation with two services (ie.: google translate and an LLM). Always check a reverse translation to avoid "lost in translation" challenges. Take the newly translated term, and verify it make sense when back in your language. Best to check on two systems as well.

Updating obs-plugintemplate

This plugin is based off of https://github.com/obsproject/obs-plugintemplate, and has occasionally contributes back to it.

If obs-plugintemplate is template is updated, then this plugin should also be updated.

This plugin is not a pure fork of https://github.com/obsproject/obs-plugintemplate, so it cannot be merged/rebased.
It needs to be applied manually, and may not be easy to cherry-pick.

A snapshot of the latest merged obs-plugintemplate code is tracked at:

To update this plugin's obs-plugintemplate code:

  1. Clone this plugin's code
  2. Add remote to https://github.com/obsproject/obs-plugintemplate/tree/master
  3. Push https://github.com/obsproject/obs-plugintemplate/tree/master to https://github.com/DistroAV/DistroAV/tree/obsplugin-template/master
  4. Create a feature branch off of https://github.com/DistroAV/DistroAV/tree/master
  5. Cherry-pick new changes from https://github.com/DistroAV/DistroAV/tree/obsplugin-template/master to https://github.com/DistroAV/DistroAV/tree/master
    Incorporate MOST of obs-plugintemplate's changes into this plugin.
    DO NOT OVERWRITE THIS PLUGIN'S PLUGIN SPECIFIC CHANGES IN THESE FILES!
    Examples:
    • buildspec.json
    • CMakeLists.txt
    • ...
  6. Create a PR of the changes and have reviewed.

Updating OBS Dependencies

Almost all of the time, all of the necessary OBS dependencies get updated when updating the obs-plugintemplate. Sometimes the obs-plugintemplate is not updated quickly enough, this is how to manually do it.

To update this plugin's OBS dependencies, modify buildspec.json :

  1. Download obs-studio release version source for macos .tar.gz & windows-x64 .zip. Example for https://github.com/obsproject/obs-studio/releases/tag/29.1.3 https://github.com/obsproject/obs-studio/archive/refs/tags/29.1.3.tar.gz https://github.com/obsproject/obs-studio/archive/refs/tags/29.1.3.zip
  2. sha256sum the macos .tar.gz & windows-x64 .zip
  3. Update the obs-studio version and hashes below
  4. Browse the obs-studio code buildspec.json at that version commit and copy the prebuilt and qt6 versions and hashes to below Example https://github.com/obsproject/obs-studio/blob/c58e511/buildspec.json

Updating NDI Dependencies

Occasionally a new version of the NDI SDK is released.

To update this plugin's NDI dependencies:

  1. Update all the files in /lib/ndi with the sdk files

Testing

Standard Acceptance Test

For each platform [Linux, MacOS, Windows]:

  • Install the plugin
  • Launch OBS
  • Verify the plugin loaded
  • Use the plugin
    • NDI Output Settings
      • Main On
      • Preview On
    • NDI Source
      • Add Filter NDI Audio Output
      • Loopback the local OBS Output
      • Loopback the local OBS NDI Audio Output
      • ...
  • Close OBS
  • View the logs
    • Linux:
      • Normal: ~/.config/obs-studio
      • Flatpak: ~/.var/app/com.obsproject.Studio/config/obs-studio
    • MacOS: ~/Library/Application Support/obs-studio
    • Windows: %APPDATA%\obs-studio\logs
  • Verify the log ended with Number of memory leaks: 0.
    NOTE: For some reason in Windows OBS says 0 but on MacOS it says 4.
    I uninstalled DistroAV and OBS still says 4, so I am ignoring this... for now.
  • Uninstall the plugin

Update Testing

Several command-line args can be used to help locally test the Update functionality.
To do this you need access to the firebase repo and then to run the firebase functions with:

firebase emulators:start --only firestore,functions,hosting:dev

Then pass the following arguments when launching OBS with DistroAV installed:

/Applications/OBS.app/Contents/MacOS/OBS --distroav-debug --distroav-update-local --distroav-update-force --distroav-update-last-check-ignore

The arguments are documented in https://github.com/DistroAV/DistroAV/blob/master/src/config.cpp

  • --distroav-debug
  • --distroav-verbose
  • --distroav-log[=error|warning|info|debug|verbose]
  • --distroav-update-force[=0|1]
  • --distroav-update-last-check-ignore
  • --distroav-update-local[=5002]
  • --distroav-detect-obsndi-force[=off|on]

Pre-Release

Seeking Testers

This plugin is based off of https://github.com/obsproject/obs-plugintemplate that supports CI packaging installers if the PR is labeled with Seeking Testers:
https://github.com/obsproject/obs-plugintemplate/blob/e385ac1863b8c658e7f6cc564f04040c9057c9f0/.github/workflows/build-project.yaml#L32C1-L36

Use this feature when wanting testing/feedback on a branch build.

Release Candidate

WIP... Use this feature when wanting testing/feedback on a build imminent for release.

Release

  1. Follow Pre-Release processes.
  2. Update ./buildspec.json "version" to the new version number
    (ex: "4.14.0").
  3. Commit and push these changes to a branch to be merged to master.
  4. Merge to master when ready.
  5. Verify build passed for Linux, MacOS, Windows
  6. Create tag for new version (ex: 4.14.0) and push tag to DistroAV origin. (git tag x.x.x then git push origin tag x.x.x) DO NOT START DRAFTING A RELEASE YET; GitHub will auto-draft a release note after the tagged build completes successfully.
  7. Verify tagged build passed for Linux, MacOS, Windows.
    This is especially important because historically the MacOS build sometimes fails for Apple Developer reasons.
    If this happens, contact @Trouffman or @paulpv.
  8. GitHub should auto-draft a release, but leave it alone for now.
  9. DO NOT PUBLISH THE DRAFT RELEASE JUST YET!
  10. VERY IMPORTANT OR NO ONE WILL BE ABLE TO SUCCESSFULLY CHECK FOR THE NEXT UPDATE
    Add Linux/MacOS/Windows release hashes to Firestore:
    1. Clone https://github.com/DistroAV/firebase
    2. Follow the directions in the header of:
      https://github.com/DistroAV/firebase/blob/main/admin/admin.py
      Example:
      % ./admin/admin.py hashes 6.0.0 --real --live
      This should automatically add the tag's release binary hashes to live production Firestore.
    3. On at least one, preferably all, platform(s):
      1. Download and install the tagged build.
        (A clean compile of the current code will not work!)
      2. Run firebase emulators:start --only firestore,functions,hosting:dev
      3. Run OBS with --distroav-update-local --distroav-update-force
      4. Verify that the tagged build sees the latest/current release (NOT the new tagged build) as an update.
        (It is semi-reasonable to assume that if one computed correctly, then they all would have computed correctly, but human copy-paste/etc errors could still cause unexpected failures.
        It is best to test all platforms!)
    4. Check the update server logs are seeing 200 responses with no errors or unexpected warnings.
  11. Edit and Publish the auto-drafted release; use previous release title/content as a guide.
  12. DO NOT ANNOUNCE THE RELEASE JUST YET!
  13. Wait up to 15 minutes for the DistroAV update server to timeout its GitHub response cache.
    You can speed this up by re-pushing functions with:
    firebase deploy --only firestore,functions,hosting:prod
  14. Test that an install of the previous release detects the update during both launch and manual (look at the logs).
  15. You are now free to announce the release!
  16. Follow Post-Release processes.

NOTE: Per https://github.com/DistroAV/DistroAV/issues/724 this plugin also generates a flatpak via
https://github.com/flathub/flathub/pull/4701 ...
TODO: Confirm this is working after DistroAV rebrand

Post-Release

OBS Project

Update OBS Plugin Listing: https://distroav.org/forum (>3M downloads)

  1. Open https://distroav.org/download
    Should auto-redirect to something like https://github.com/DistroAV/DistroAV/releases/tag/6.0.0
  2. Open https://obsproject.com/forum/resources/distroav-network-audio-video-in-obs-studio-using-ndi-technology.528/post-update
  3. Check "Release a new version"
  4. New version number:: Copy & paste the version # of the GitHub release
  5. External download URL:: Copy & paste the url of the GitHub release
  6. Update title:: Copy & paste the title of the GitHub release
  7. Update message:: Copy & paste the HTML description of the GitHub release NOTE that after posting this it still requires moderator approval. :/

Windows

The Windows installer is not [yet?] signed.
This can result in errors while downloading and running.
To mitigate this:

  1. Manually try a download

    1. If Chrome's "Google Safe Browsing" says "Suspicious download blocked":



    2. Other browsers? ...
  2. If Windows Defender detects/warns/deletes the file as suspicious:

  3. If the file launches but says it is suspicious: ...

MacOS

Similar to Windows, MacOS also complains about the installer.
distroav-macos-security-issue
For developers only
You can force run by clicking "control" to open.
...


NOTE: Non-Rewrite vs Rewrite Branch Translations

In 2022 @tt2468 did a fantastic job implementing a near total rewrite on the https://github.com/DistroAV/DistroAV/tree/rewrite branch.

The following is just my personal opinion:

I (@paulpv) do love that code, but I personally do think that code may have gone a bridge too far for what I think most DistroAV users really wanted.

I think most users just wanted the same old DistroAV that worked on the (at the time) latest OBS v28

@tt2468's changes are great, but they took the plugin in a different direction.

That direction was not bad, but I don't think most DistroAV users were ready for it at that time.

I would still love to cherry-pick from that excellent code where possible in bits and pieces over time.

The names of several files changed in the branches, so this table helps [me] to remember what files are similar.

master [non-rewrite] branch vs/to<->from rewrite branch:

=non-rewrite= =rewrite= =note=
preview-output? aux-output
config config
? input-utils
obs-ndi-source input
plugin-main obs-ndi
output-manager
obs-ndi-output output
main-output ?
obs-ndi-filter ?

Clone this wiki locally