= Voctomix
---- dataentry project ----
name : Voctomix
project-owner : Mazdermind
git-url_url : https://github.com/voc/voctomix
project-description :
project-members :
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 [[people:Mazdermind]] fürs VOC entwickelt und ist [[https://github.com/timvideos/gst-switch|gst-switch]]'s kleine Schwester. Sie lebt im [[intern:git|Git]] unter git@c3voc.de:voctomix und read-only [[https://github.com/voc/voctomix|auf Github]].
* [[https://media.ccc.de/v/froscon2016-1696-voctomix|Voctomix Lecture at FROSCON12]] by Mazdermind
* [[http://slides.com/mazdermind/froscon12-voctomix|slides]]
== Resources
**Documentation**
* [[https://github.com/voc/voctomix/blob/master/README.md|Installation]]
* [[https://github.com/voc/voctomix/blob/master/README_DOCKER.md|"Installation" mit Docker]]
* [[https://github.com/voc/voctomix/blob/master/voctocore/README.md|Voctocore, Protokoll und Ports]]
* [[https://github.com/voc/voctomix/blob/master/voctogui/README.md|Voctogui]]
* [[software:voctomix-hardware-examples]]
**Subprojects**
* [[projects:tallycom]]
* [[voctomix:voctopanel]]
* [[voctomix:voctomidi]]
** related projects**
* [[https://github.com/crossan007/PiCamFleetMapper | PiCamFleetMapper]]
* [[https://github.com/CarlFK/voctomix-outcasts | vocotmix-outcasts]]
== 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 [[https://github.com/voc/voctomix/tree/master/example-scripts/control-server|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