Mini-Summary of my activity during the DebConf Video Team sprint
Hi Everyone
Here's a summary of what I worked on during the DebConf video team
sprint. TL;DR: I mostly poked around at OBS.
== Scripting OBS ==
Currently, we use obs-studio for the loopy loop. In the free software
world, it really is the state of the art in sequencing scenes and
compositing different elements. We could use it for more in the future,
but already for loopy loop, it would be nice to be able to script it
better and in config files that can be handled in git, rather than
building and managing everything by hand in its GUI.
In obs-studio 28+ (in testing), it now includes a websocket interface by
default. Enabling it is really trivial, here is some upstream
documentation that describes what it can do:
https://github.com/obsproject/obs-websocket/blob/master/docs/generated/protocol.md
I searched for the best available methods to talk to OBS via python, and
found the following:
* simpleobsws: async python library
https://github.com/IRLToolkit/simpleobsws
* obsws-python: sync python library
https://github.com/aatikturk/obsws-python
* obs-websocket-http: exposes http endpoints that can
be caled to controb obs
https://github.com/IRLToolkit/obs-websocket-http
simpleobsws ticked all my boxes, so I didn't delve too much into
obsws-python, simpleobsws seemed better maintained and had stable tags,
to I spent most time on that and packaged it (It's now in unstable, I'll
do a source-only upload of that after this email so that it can migrate
to testing). obs-websocket-http looks nice, but simpleobsws is really
sufficient for scripting OBS. obs-websocket-http looks like it might be
useful if we would want to expose some functions with finer grained
permissions at some point.
So, before I could get started on a script to implement loopy, I had to
figure out what a loopy configuration would look like. Since TOML is now
a first class citizen in python, I decided to give it a try. Here is the
result:
https://salsa.debian.org/debconf-video-team/loo.py/-/blob/main/examples/loopy.toml
The [loopy] section defines the basic config for loopy. sequence defines
the loop. In this example "play something from welcome, then sponsors,
then shoutouts, then schedule" and loop that over and over. Previously,
we had another script that monitors the vocto socket and would switch to
a standby slide when talks were taking place, and back to a welcome /
sponsors slide when the talked end (so that you're not abruptly in the
middle of some other clip when the talk ends). That's defined in
switch_on_idle and switch_on_return_from_talk.
In the following sections, we define groups of clips that we'd want to
play, and whether they should be played in sequence or random.
It's useful to be able to thread scenes. In the case of sponsors, we
have 3 different types of sponsor inserts. First is just a set of logos
for each level of sponsors, the second is sponsors with announcements
and the third is a video where someone reads out the announcements. In
the case of the first two, these scenes are threaded by the "next"
directive. This is useful for things like shoutouts too where they fit
together or where there are replies to existing shoutouts.
duration for each clip is optional for videos, the idea is to get the
timestamp from the video and use that for default, but it's also nice to
cut off some part at the end if it's not wanted without having to edit
the video. Other than that I think the loopy TOML format is quite easy
to understand and self-explanatory.
Here is the script that would read that config and execute it:
https://salsa.debian.org/debconf-video-team/loo.py/-/blob/main/src/loo.py
It's a proof of concept at this stage, it needs some more work to be
production ready, like moving the host/password to a config file,
reading video metadata and implement the clip threading part. As it is,
it does work and change those scenes in OBS. It doesn't build any
scenes, those have to be defined in OBS already, although in the future
we could build them too either with this script or an additional one.
== Evaluating OBS plugins ==
I checked out obs-downstream-keyer, obs-move-transition and
obs-scene-collection-manager. obs-downstream-keyer and
obs-scene-collection-manager didn't end up as useful to us as I thought
it might be, so I moved on. obs-move-transition looks very useful for
adding effects and transitions for elements in scenes that spans scenes,
but it's quite complicated, I'll have to spend some more dedicated time
on it in the future if we'd want to take advantage of it's powerful
features.
obs-advanced-scene-switcher will hopefully be replaced by loo.py in the
future, in the meantime, it initially appears broken in testing right
now since all the usual options seem missing, but if you untick "Hide
tabs which can be represented via macros", then all the usual tabs are
back again.
== Less embedded web pages ==
Currently in our loopy, we display the announcements on the lower third,
the schedule scene, as well as the time in the form of an embedded web page.
OBS has supported python scripting for a little while now. I tried out
an exising OBS script that fetches data from a url and displays it in a
scene element. This worked well for the announcements.
Next, I created a script from the obs examples to update the time in a
scene element, it still needs some work, but it works:
https://salsa.debian.org/debconf-video-team/loo.py/-/blob/main/src/time.py
For the schedule, I didn't even try, it would need a bit more work to
properly parse a schedule and represent that in OBS scene items, but
consensus at the sprint was that this would be overkill and we'll just
go ahead and keep showing the schedule from wafer in an embedded web
page for now.
So, there's still a lot left to do, but the sprint was very useful in
figuring out a lot of this. What's great about defining loopy completely
outside of OBS is, that we should be able to easily port it over to
another sequencer/compositor tool if it ever emerges.
-Jonathan
Reply to: