% Voctomix setup ## Ситуация За OpenFest имахме две кутии от тези от [FOSDEM](https://lusis.eu/blog/curious-about-fosdem-video-cases), които в общи линии ни даваха възможност да включим почти произволен източник на видео в тях и да го изкараме от мрежата. Те вървят в комплект от две - едната се използва, за да се включи в нея лектора, другата - за камерата. С тези две кутии и малко софтуерно видео миксиране може да се направи много лесно добър setup за видео запис на една зала. Схемата на setup-а може да се види в [github](https://github.com/OpenFest/openfest/blob/master/2016/schemes/studio-music.pdf), като лесно може да се види, че е доста по-прост от другите, които използваме. Негов вариант мислим да използваме за FOSDEM 2017 (което може да се наблюдава в [repo-тата в github](https://github.com/FOSDEM/video/) - issue-та, wiki и всякакви работи). ## VoctoMix Липсващият компонент в цялата работа беше софтуерен миксер, който да ползваме. Пробвахме различни - първо един ffmpeg с малко patch-ове (чупи се твърде лесно), после OBS (който leak-ва памет като гламав и не е особено стабилен), и накрая се спряхме на [voctomix](https://github.com/voc/voctomix/), който е разработка на CCC и в общи линии е прекрасен хакерски инструмент, който работи по следния начин: * Има входове на TCP портове за следните неща: * Видео потоци (камери, лекторски лаптоп) * Поддържащи потоци (фон, какво да се пуска докато не сме live и т.н.) * Команди за разни действия (смяна на картина и т.н.) * Изходи, пак по TCP, за * Видео поток * Аудио поток * Копие на всеки входящ stream * preview на потоците и изходящата картина Софтуерът в общи линии просто switch-ва между няколко неща (някоя картина на fullscreen, picture-in-picture в някакви варианти и т.н.) и вади поток, който може да се използва. Има отделно приложение (voctogui) което се закача към него и се използва като конзола - може да показва preview на потоците и да подава команди към основния процес (voctocore). ## Как го използвахме ### Излъчване от кутиите Като за начало, изкарването на поток от кутиите става с ffmpeg/avconv, по UDP, по multicast. UDP, понеже е по-издръжливо на някакви random прекъсвания и няма да създаде десинхронизация, multicast, за да може да се гледа от повече от едно място (например за проверка какво точно излиза). Командата изглежда по следния начин: ~~~~~~sh # these are needed, because the default socket size is too small. echo 81921024 > /proc/sys/net/core/wmem_max echo 81921024 > /proc/sys/net/core/wmem_default echo 81921024 > /proc/sys/net/core/rmem_max echo 81921024 > /proc/sys/net/core/rmem_default /usr/local/bin/bmd-streamer -f /usr/lib/firmware -k 1000 -S hdmi -F 0 | \ ffmpeg -i - -c copy -f mpegts 'udp://227.0.0.1:9000&overrun_nonfatal=1&buffer_size=81921024&fifo_size=178481' ~~~~~~ Интересното тук са параметрите на UDP stream-а - гигантски буфери (които и по-горе се казват на kernel-а), така че каквото и да се случва, да не се бави писането в буфера. Като цяло не е проблем да се губят пакети, но е доста лошо да се получава забавяне в целия stream, понеже води до десинхронизация. (да се губят пакети също е лошо, и за целта работя по нещо, което да вкарва forward error correction в тоя поток, един добър човек е написал patch за ffmpeg, реализиращ pro-mpeg, който има точно такава функционалност, надявам се да успеем да го ползваме на FOSDEM) ### Приемане във voctomix Самият voctocore приема потоците точно във видът, в който е конфигуриран (в нашия случай 1280x720, 30fps, audio в pcm_s16le на 44100hz), в MKV контейнер. За целта скриптовете, които го подават изглеждат ето така: ~~~~~~sh #/bin/sh confdir="`dirname "$0"`/../" . $confdir/default-config.sh if [ -f $confdir/config.sh ]; then . $confdir/config.sh fi ffmpeg -y -nostdin \ -i 'udp://227.0.0.1:9000&overrun_nonfatal=1&buffer_size=81921024&fifo_size=178481' \ -ac 2 \ -filter_complex " [0:v] scale=$WIDTH:$HEIGHT,fps=$FRAMERATE,setdar=16/9,setsar=1 [v] ; [0:a] aresample=$AUDIORATE [a] " \ -map "[v]" -map "[a]" \ -pix_fmt yuv420p \ -c:v rawvideo \ -c:a pcm_s16le \ -f matroska \ tcp://localhost:10000 ~~~~~~ Това в общи линии казва "вземи udp stream-а, scale-ни го до колкото искаме, сгъни пикселите и аспекта да са точно каквито ни трябват, и го прати като mkv на порт 10000". Сгъването на пикселите и аспекта (setsar, setdar) се налага основно когато не може да се промени изхода на камерата и идва в нещо странно като 1920x1088, което води до малко по-различна форма на пикселите. За да работи цялото нещо, имаме два такива скрипта (по един за box), както и един подобен, който просто loop-ва едно PNG, което играе ролята на фон. В оригиналните скриптове хората са използвали видео за фон на picture-in-picture, но това е по-объркващо за гледащите и не го ползваме. ### Излъчване и запис при voctomix Излъчването и записът са в общи линии много подобни скриптове, като ще покажа само този, който праща до restreamer-а: ~~~~~~sh #/bin/sh ffmpeg -y -nostdin \ -i tcp://localhost:15000 \ -threads:0 0 \ -aspect 16:9 \ -c:v libx264 \ -maxrate:v:0 2000k -bufsize:v:0 8192k \ -pix_fmt:0 yuv420p -profile:v:0 main -b:v 512k \ -preset:v:0 ultrafast \ \ -ac 1 -c:a libfdk_aac -b:a 96k -ar 44100 \ -map 0:v \ -map 0:a -filter:a:0 pan=mono:c0=FL \ -ac:a:2 2 \ \ -y -f flv rtmp://10.23.0.1:1935/st/STREAM ~~~~~~ (скриптът е примерен, понеже доработвах след това нещата) Като цяло, просто се взимат raw данните от порт 15000, encode-ват се до H.264 и се пращат до сървъра. По същият начин може да се обръщат във WEBM и засилват, но той иска много повече процесорно време и не сме стигнали до там, че да го ползваме. ### Екстри за voctomix Нещо, което не включихме на OpenFest, но ще има на FOSDEM е една дребна доработка, която позволява с много малко ресурси хора отдалечено да контролират voctomix-а. По принцип voctogui не е лек процес и има много сериозни мрежови изисквания, ако не се стартира локално (от порядъка на 1Gbps само за него), но позволява всякакви ужасяващи неща с малко дописване. С един прост скрипт, [който прави screenshot веднъж в секунда](https://github.com/krokodilerian/fostest/blob/master/voctomix-ffmpeg-scripts/imgmaker.sh), и [съвсем прост друг, който подава команди](https://github.com/krokodilerian/fostest/tree/master/voctomix-web-interface) ще имаме начин определени хора да имат контрол върху излъчването. Също така нещо, което ползвахме донякъде на OpenFest за monitoring на stream-а е един друг [скрипт с mpv](https://github.com/krokodilerian/fostest/blob/master/mon.sh), който взима списък URL-та и някакви имена към тях и ги пуска в отделни подредени един до друг прозорци на екрана, като за всеки overlay-ва един bar с нивото на звука, така че да може да се вижда дали е ок (понеже не е практически възможно да се слушат няколко зали едновременно). Проблемът му е, че се иска бая процесорно време, за да се декодират повечето потоци и един T420 с i7 процесор се озорваше с 6те потока от феста. Как изглеждаше екрана може да видите [тук](https://vasil.ludost.net/pics/20161106mon.jpg). ## Опериране Работата с voctomix не е сложна, но за момента пълна с неща, които имат да се свършат. Ето как изглежда (засега, работим по автоматизация) процесът на стартиране: * voctocore * voctogui * скриптове за приемане от камери (cam1.sh, grab.sh) * скрипт за генериране на фон * скрипт за stream-ване * запис (record.sh) След което от voctogui при нужда се сменят различните картини. Като цяло е доста по-просто за разбиране от по-големите setup-и с конвертори и т.н., но и с по-малко функционалности. ## Доколко добре работи? Работи прекрасно, въпреки че се опитваме да открием един бъг с забавяне на audio-то, който се появява в някакъв момент. Започвам да си мисля, че има някакъв проблем със самия лаптоп, с който правим миксирането. ## Какво още можем да искаме? Хрумнаха ни няколко екстри, които да добавим, така че да стигнем функционалността на хардуерния setup: * Начин да излъчваме екрана за проектора от при нас. Това ще иска някаква доработка, за да смъкнем латентността на цялото нещо под 100ms, понеже иначе ще е доста забележимо (представете си как лектора прави нещо и проекторът се променя след 5 секунди). Единият от вариантите, който ни хрумна е проекторът да е вързан на едно pi и то директно да може да избира кой multicast да гледа (някоя камера, лаптопа на лектора или нещо трето). * Overlay надписи по време на лекцията - трябва да видим какво има да се пипне още, мисля, че има някаква такава функционалност (или може да ги сложим във фона). * По-добра синхронизация на различните потоци - ако работим с няколко камери, може да се окаже проблем, че едната върви с няколко кадъра след другата и трябва да си поиграем със забавяне. Като цяло, аз съм много щастлив от voctomix и ако успея да убедя екипа, догодина можем много повече да ползваме него, отколкото чисто хардуерния setup (просто ще ни трябват мощни машини, за да се справят с encode-ването, че засега успяваме да работим само на 720p, без да подпалим лаптопа).