mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
linux-v4l2: Use flatpak-spawn when inside a Flatpak sandbox
It is not possible to run host system executables like modinfo, pkexec, and modprobe inside a Flatpak sandbox. However, Flatpak provides a way to run command on the host system: the flatpak-spawn executable. flatpak-spawn is a tiny helper that, when executed with the '--host' parameter, talks to the org.freedesktop.Flatpak D-Bus interface to run and retrieve the return value of the executable. This provides OBS Studio a way to escape this sandbox limitation without opening large holes in the sandbox. Make v4l2's implementation of VirtualCam run system commands using flatpak-spawn when inside a Flatpak sandbox. The detection of the sandbox is done by checking the existence of the /.flatpak-info file, which is created by Flatpak itself, and only exists inside the sandbox. If OBS Studio is not running inside a Flatpak sandbox, run the exact same command it used to run before this commit. Add the permission to talk to the org.freedesktop.Flatpak D-Bus interface to the Flatpak manifest, so we can run flatpak-spawn with the '--host' parameter. Notice that the same constraints apply with and without Flatpak: the host system needs to have the v4l2loopback kernel module available for the v4l2 implementation of VirtualCam to work.
This commit is contained in:
parent
44ee91188f
commit
7a87777225
@ -14,6 +14,7 @@
|
||||
"--filesystem=xdg-run/pipewire-0",
|
||||
"--filesystem=host",
|
||||
"--talk-name=org.kde.StatusNotifierWatcher",
|
||||
"--talk-name=org.freedesktop.Flatpak",
|
||||
"--talk-name=org.freedesktop.ScreenSaver",
|
||||
"--talk-name=org.freedesktop.PowerManagement.Inhibit",
|
||||
"--talk-name=org.freedesktop.Notifications",
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <obs-module.h>
|
||||
#include <util/dstr.h>
|
||||
#include <util/platform.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -26,6 +27,35 @@ static void virtualcam_destroy(void *data)
|
||||
bfree(data);
|
||||
}
|
||||
|
||||
static bool is_flatpak_sandbox(void)
|
||||
{
|
||||
static bool flatpak_info_exists = false;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
flatpak_info_exists = access("/.flatpak-info", F_OK) == 0;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return flatpak_info_exists;
|
||||
}
|
||||
|
||||
static int run_command(const char *command)
|
||||
{
|
||||
struct dstr str;
|
||||
int result;
|
||||
|
||||
dstr_init_copy(&str, "PATH=\"$PATH:/sbin\" ");
|
||||
|
||||
if (is_flatpak_sandbox())
|
||||
dstr_cat(&str, "flatpak-spawn --host ");
|
||||
|
||||
dstr_cat(&str, command);
|
||||
result = system(str.array);
|
||||
dstr_free(&str);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool loopback_module_loaded()
|
||||
{
|
||||
bool loaded = false;
|
||||
@ -56,8 +86,7 @@ bool loopback_module_available()
|
||||
return true;
|
||||
}
|
||||
|
||||
if (system("PATH=\"$PATH:/sbin\" modinfo v4l2loopback >/dev/null 2>&1") ==
|
||||
0) {
|
||||
if (run_command("modinfo v4l2loopback >/dev/null 2>&1") == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -66,8 +95,8 @@ bool loopback_module_available()
|
||||
|
||||
static int loopback_module_load()
|
||||
{
|
||||
return system(
|
||||
"PATH=\"$PATH:/sbin\" pkexec modprobe v4l2loopback exclusive_caps=1 card_label='OBS Virtual Camera' && sleep 0.5");
|
||||
return run_command(
|
||||
"pkexec modprobe v4l2loopback exclusive_caps=1 card_label='OBS Virtual Camera' && sleep 0.5");
|
||||
}
|
||||
|
||||
static void *virtualcam_create(obs_data_t *settings, obs_output_t *output)
|
||||
|
Loading…
Reference in New Issue
Block a user