Skip to content

Instantly share code, notes, and snippets.

@majenkotech
Created August 22, 2022 14:23
Show Gist options
  • Save majenkotech/d727d32b81f2e3e294357780babb58bf to your computer and use it in GitHub Desktop.
Save majenkotech/d727d32b81f2e3e294357780babb58bf to your computer and use it in GitHub Desktop.

OBS Camera Fixing Script

I got fed up with OBS always having the wrong /dev/videoX paths every time I start it. Not OBS's fault, but Linux's fault for never knowing where its webcams are connected.

So I wrote this small script to update the OBS scene configuration for me automatically.

It relies on your camera sources being named the same as your cameras (as reported by v4l2-ctl --list-devices) so it knows what device to map each scene to.

For example, if you have a camera named BRIO 4K Stream Edition you should also name the source in OBS as BRIO 4K Stream Edition for it to match between them.

This does not modify the live file, instead it reads from a backup ".tpl" copy of the file. That way if there is a hiccup while generating the live file it won't trash the whole setup. But any changes you make to your scene will not be saved unless you then copy the "live" scene file back to the template version.

#!/usr/bin/php
<?php
// Your scene file
$src = "/home/matt/.config/obs-studio/basic/scenes/Untitled.json";
// First build a list of the cameras to use. These unfortunately have to all be
// unique names, it doesn't handle multiple cameras with the same name.
$cams = `v4l2-ctl --list-devices`;
$clist = explode("\n", $cams);
$cameras = array();
$thiscam = '';
foreach ($clist as $cam) {
$cam = trim($cam);
if ($cam == '') continue;
if (substr($cam, 0, 5) == '/dev/') {
if ($thiscam != '') {
$cameras[$thiscam] = $cam;
$thiscam = '';
}
} else {
if (preg_match('/^(.*) \(/', $cam, $m)) {
$thiscam = $m[1];
}
}
}
// Now load the scene file template, which is the real file just copied and .tpl
// added to the end of the file. This is to prevent any accidents from killing
// your whole setup
$data = file_get_contents($src . ".tpl");
$scene = json_decode($data);
// Now go through each source and look for any that match a camera name. If they
// match then update the device_id to be the real camera filename
$out = array();
foreach ($scene->sources as $source) {
if (array_key_exists($source->name, $cameras)) {
$source->settings->device_id = $cameras[$source->name];
print_r($source);
}
$out[] = $source;
}
// Put the new settings into the configuration and output it to the live config file
$scene->sources = $out;
$data = json_encode($scene);
file_put_contents($src, $data);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment