Voctomix
- name:
- Voctomix
- project-owner:
- Mazdermind
- git-url:
- https://github.com/voc/voctomix
- project-status:
- running
Voctomix ist ein Softwaremischer der es uns erlaubt auf Konferenzen HD-Recording und -Streaming anbieten zu können. Voctomix wird aktuell von mazdermind fürs VOC entwickelt und ist gst-switch's kleine Schwester. Sie lebt im Git unter git@c3voc.de:voctomix und read-only auf Github.
- Voctomix Lecture at FROSCON12 by Mazdermind
Resources
Documentation
Subprojects
related projects
Installation on VOC hardware
The installation on VOC machines (encoder cubes and mixer notebooks) is managed through Ansible. The Ansible deployment creates the following things on the encoder-cubes:
- Source of last release in
/opt/voctomix/release
- Config file for voctocore in
/opt/voctomix/voctocore-config.ini
- Scripts to source/sink/playout video- content into/out of the voctocore in
/opt/voctomix/scripts
- Systemd units in
/etc/systemd/system/*.service
- A system status script in
/usr/bin/voctomix-status
Ansible always resets the setup to a default configuration, where all SDI-ports are used as camera INs, no playout is active and all supporting scripts are enabled. Ansible generated the following Systemd units for Voctomix:
Systemd-Unit | Description |
---|---|
music-source.service | Source Music from /opt/voc/share/pause-music/ into the pause loop |
pause-source.service | Source pause loop from /opt/voc/share/pause.ts |
program-to-[NAME]-playout.service | Such a unit is generated for each Decklink output device present at the time of the ansible-run. Playout video- and audio from the program output (=what is being recorded; before the stream-blanker) to the Decklink output |
program-to-framebuffer-playout.service | Playout video from the program output (=what is being recorded; before the stream-blanker) to the HDMI/DVI/VGA output on the mainboard |
recording-sink.service | Record the program output to segmented .ts-files in /video |
streaming-hd-sink.service | Encode and stream the stream-blanker output to rtmp://127.0.0.1:1935/stream/s{{ room_number }}_native_hd |
streaming-sd-sink.service | Encode and stream the stream-blanker output to rtmp://127.0.0.1:1935/stream/s{{ room_number }}_native_sd |
stream-to-[NAME]-playout.service | Such a unit is generated for each Decklink-Output-Device present at the time of the ansible-run. Playout video and audio from the stream output (=what is being streamed; after the stream-blanker) to the Decklink output |
stream-to-framebuffer-playout.service | Playout video from the stream output (=what is being streamed; after the stream-blanker) to the HDMI/DVI/VGA output on the mainboard |
voctocore.service | The Voctocore |
All supporting units are WantedBy=voctocore.service
as well as the request Requires=voctocore.service
and After=voctocore.service
. This means:
- The supporting units only start up when the core has successfully started up first
- When enabled, the supporting units automatically start up when the core is up
- The supporting units go down when the core goes down
Practical tips
In practice this means, that to restart the whole chain, you can do:
sudo systemctl restart voctocore.service
Stop recording at night and schedule re-start in the morning:
for i in 1 2 3 4 5 6 41 42; do echo "10.73.${i}.3"; ssh 10.73.${i}.3 'sudo systemctl stop recording-sink.service'; done for i in 1 2 3 4 5 6 41 42; do echo "10.73.${i}.3"; ssh 10.73.${i}.3 'echo "sudo systemctl restart voctocore.service" | at 09:00'; done
Similar to stop or start everything you can use
sudo systemctl stop voctocore.service
and
sudo systemctl start voctocore.service
To see which units are actually started, you can call
voctomix-status
To Reconfigure a Decklink-Duo Port as Playout, in order for it to survive a restart/reboot, you can do:
sudo systemctl disable decklink-source-decklink-sdi-2.service sudo systemctl stop decklink-source-decklink-sdi-2.service sudo systemctl enable stream-to-decklink-sdi-2-playout.service sudo systemctl start stream-to-decklink-sdi-2-playout.service
If you leave out the enable/disable the change will be temporary and restarting the voctocore unit or the encoder cube will reset the change.
Similar to enable playout to the Framebuffer, you can do:
sudo systemctl start stream-to-framebuffer-playout.service sudo systemctl enable stream-to-framebuffer-playout.service
Leaving out the enable/disable the change will also here be temporary.
Playout to the framebuffer can always be interrupted by funny tty0 printouts at any time :) Also think about whether you want to playout the program output (before the stream-blanker) or the streaming output (after the stream-blanker).
Debugging
To see the output of the various units, you can use a command like this:
journalctl -au decklink-source-decklink-sdi-2.service
Alternative version:
journalctl -a -f -u grabber-source.service
Control Commands
Some useful control commands when you only have a shell (see also example-scripts/control-server: For more details see https://github.com/voc/voctomix/blob/voctopanel/voctocore/lib/commands.py
echo set_audio cam1 | nc -q0 localhost 9999 echo set_audio cam2 | nc -q0 localhost 9999 echo set_composite_mode fullscreen | nc -q0 localhost 9999 echo set_composite_mode picture_in_picture | nc -q0 localhost 9999 echo set_composite_mode side_by_side_equal | nc -q0 localhost 9999 echo set_composite_mode side_by_side_preview | nc -q0 localhost 9999 echo set_stream_blank pause | nc -q0 localhost 9999 echo set_stream_live | nc -q0 localhost 9999 echo set_video_a cam1 | nc -q0 localhost 9999 echo set_video_a cam2 | nc -q0 localhost 9999 echo set_video_a grabber | nc -q0 localhost 9999 echo set_video_b cam1 | nc -q0 localhost 9999 echo set_video_b cam2 | nc -q0 localhost 9999 echo set_video_b grabber | nc -q0 localhost 9999
here you can see the commands together with replays from the core
=> set_video_a cam1 <= video_status cam1 cam2 => set_composite_mode fullscreen <= composite_mode fullscreen <= video_status cam1 cam2 => set_composite_mode side_by_side_equal <= composite_mode side_by_side_equal <= video_status cam1 cam2 => get_config <= server_config {"stream-blanker": {"sources": "pause,nostream", "enabled": "true"}, "DEFAULT": {}, "side-by-side-equal": {}, "fullscreen": {}, "side-by-side-preview": {}, "mix": {"sources": "cam1,cam2,grabber", "videocaps": "video/x-raw,format=I420,width=1920,height=1080,framerate=25/1,pixel-aspect-ratio=1/1", "audiocaps": "audio/x-raw,format=S16LE,channels=2,layout=interleaved,rate=48000"}, "previews": {"deinterlace": "false", "enabled": "false"}, "output-buffers": {"mix_out": "10000"}, "picture-in-picture": {}} => get_video <= video_status cam1 cam2 => get_composite_mode <= composite_mode side_by_side_equal