External Plugin Support for the OBS Studio Snap

After the recent update of the OBS Studio snap to upgrade the base snap to core24 and to remove bundled third party plugins, we have been working on bringing external plugin support. External plugins are now supported through a generic plug called obs-plugins.

Already available plugins

The following OBS Studio plugins have already been snapped and are available for testing:

Intel OpenVINO AI plugins

The openvino-plugins-obs-studio snap packages the Intel OpenVINO AI plugins for OBS Studio, which are available here. You can access the snap source code at the following link:
https://github.com/canonical/openvino-plugins-obs-studio-snap

Advanced Masks

The advanced-masks-obs-studio snap packages the Advanced Masks plugins by FiniteSingularity, which are available here. The snap packaging definition can be found here:
https://github.com/vandah/advanced-masks-obs-studio-snap

How to install a plugin

Install the new version of the OBS Studio snap

If you don’t have OBS Studio snap installed, use:

sudo snap install obs-studio

Add a plugin

To add a new plugin, install any compatible plugin snap and connect the obs-plugins connection.

sudo snap install obs-openvino-plugins
sudo snap connect obs-studio:obs-plugins obs-openvino-plugins:obs-plugins

How to create a new plugin snap

To utilize a plugin that is not already included with the OBS Studio snap, you can create a new snap and establish a connection between it and the OBS Studio snap.

OBS Studio plugins are implemented as shared libraries, which the OBS Studio application automatically loads from specific standard locations. When creating your new plugin snap, the plugin must be compiled, and all associated files must be placed within a directory that shares the name of your snap (this is accessible as $CRAFT_PROJECT_NAME in snapcraft.yaml).

This main directory can contain up to three specialized subdirectories that OBS Studio will recognize and process:

  • plugins: This is where the compiled plugins (the shared libraries) should be placed. Do not create further subdirectories within plugins.
  • data: This directory holds plugin-specific data. It should contain one subdirectory for the data of each individual plugin.
  • lib: This directory allows you to supply any additional dependencies required by your plugins.

It is possible for a single snap to deliver multiple plugins, as illustrated in the provided example.

${CRAFT_PROJECT_NAME}/
β”œβ”€β”€ data/ # data folders of plugins
β”‚   β”œβ”€β”€ plugin-A/
β”‚   β”‚   └── settings.json
β”‚   └── plugin-B/
β”‚       └── images/
β”‚           └── icon.png
β”œβ”€β”€ lib/ # additional shared libraries needed by the plugins
β”‚   └── libexternal-dependency.so
└── plugins/ # compiled plugins (shared libraries)
    β”œβ”€β”€ libplugin-A.so
    └── libplugin-B.so

The entire directory is shared via the content interface, as illustrated in the snippet below. The inclusion of the source: keyword in the slot definition is essential for correctly loading the plugins.

slots:
  obs-plugins:
    interface: content
    source:
      read:
        - /${CRAFT_PROJECT_NAME}

Additionally, you must include a snap hook that sets the snapname variable for the obs-plugins slot using the plugin snap’s name. This is crucial for correct behavior when the plugin snap is connected or disconnected. You can achieve this by adding the prepare-hook part to your existing parts definition, using the snippet provided below.

parts:
  prepare-hook:
    plugin: nil
    override-build: |
      mkdir -p ${CRAFT_PART_INSTALL}/snap/hooks/
      echo -e '#!/bin/bash\nsnapctl set :obs-plugins snapname='"${CRAFT_PROJECT_NAME}" > ${CRAFT_PART_INSTALL}/snap/hooks/prepare-slot-obs-plugins
5 Likes