Когда мы пишем статьи о своем сервере в комментариях очень часто находится читатель, который говорит: "И зачем такой огород городить? Все это одной FFmpeg командой делается!"  Вот, например, тот же скриншаринг. Всего одной FFmpeg командой можно записать происходящее на экране в файл. А дальше? Если например нужно транслировать скриншаринг на сайт? Будем записывать в файлы, загружать их на Web-сервер и запускать на сайте? Для какого-то статичного контента может быть и подойдет, но вот для "живой" трансляции вряд ли.  Вот на этом этапе и становится недостаточно только "одной команды" (хотя, забегая вперед, скажу, что одной командой мы все же обошлись), нужно еще какое-то промежуточное звено, которое позволит превратить скриншаринг захваченный FFmpeg-ом в WebRTC трансляцию.  Задача очень простая — нужно транслировать происходящее на экране компьютера на сайт, где поток будет воспроизводиться по технологии WebRTC. Захватить нужно как видео, так и звук.  Рассмотрим два варианта решения с помощью FFmpeg, под Linux и под Windows. Здесь я решил сделать небольшое признание. При написании этой статьи мне впервые пришлось столкнуться с работой FFmpeg.  Пришлось изучать мануалы и достаточно долго гуглить. В итоге, я нагуглил сочетание ключей программы FFmpeg для скриншаринга со звуком, на основании документации добавил ключи для передачи скриншаринга в поток на WCS сервере, успешно протестировал публикацию через FFMpeg и воспроизведение по WebRTC в среде Windows и Linux и начал писать эту статью-инструкцию.  На этапе тестирования команда для FFmpeg скриншаринга показалась мне достаточно хаотичной. Поэтому, работая над текстом статьи я решил ее "причесать" — собрал все что относится к захвату и кодированию видео в начале команды, потом собрал ключи для захвата и кодирования звука и завершил команду ключами для передачи данных на сервер и формирования потока.  Внимание! НЕ используйте эту команду!  Перед публикацией статьи в блоге я проверил получившуюся команду и, к своему разочарованию, получил полное отсутствие в потоке и аудио, и видео составляющих.  Пришлось вернуться к мануалам и Google.  Я вновь и вновь проверял ключи, с которыми запускается FFmpeg.  Я даже нашел альтернативный способ захвата системного звука для Windows (о чем  обязательно расскажу далее). Я тестировал с разными драйверами в Windows и разными версиями рабочих столов в Ubuntu, но все мои действия приводили к одному: На WCS сервере формировался пустой поток.  В одном из мануалов мне попалась фраза, которая прочно засела в моей голове: "Не смешивайте ключи для аудио и видео!". Вот я старательно и раскладывал ключи по полочкам. Сначала связанное с аудио, потом связанное с видео, потом передача в поток.  В какой-то момент, я запустил исходную команду, которая на первый взгляд выглядела хаотичным набором ключей. И, о чудо! В плеере был поток скриншаринга со звуком. Тогда я внимательно присмотрелся к ключам, и, наконец-то, понял свою ошибку.  Нельзя смешивать ключи для аудио и видео и ключи для разных действий!  Опытным путем мне удалось выяснить, что структура команды должна быть такой:  К сожалению, FFmpeg не поддерживает каких-либо служебных ключей для разделения секций команды, поэтому неопытному пользователю бывает сложно сориентироваться. Далее по тексту, в описаниях ключей я уточню, какие ключи к какому действию относятся.  Рассмотрим запуск скриншаринга в поток с помощью FFmpeg.  В командной строке Windows запустите на выполнение следующую  команду: где: //захват видео составляющей скриншаринга -f gdigrab — драйвер захвата экрана Windows; -rtbufsize 100M — буфер под видео. Трансляция с экрана должна идти быстро и гладко, чтобы не было пропусков кадров. Поэтому лучше сначала записывать видео в оперативную память, а затем FFmpeg сам передаст его в поток. -framerate 30 — частота кадров при захвате экрана; -probesize 10M — количество кадров необходимое FFmpeg для идентификации потока; -draw_mouse 1 — захватывать движения мыши; -i desktop — говорим FFmpeg записывать весь экран; //кодирование видео составляющей скриншаринга -c:v libx264 — сжимать будем в формат MP4 кодеком x264; -r 30 — кодек запишет видео с частотой 30 кадров в секунду; -preset ultrafast — говорим кодеку, чтобы долго не раздумывал и кодировал видеопоток, как можно быстрее (при записи экрана это актуально); -tune zerolatency — опция кодека x264 для ускорения кодирования; -crf 25 — качество записываемого видео (большее значение — хуже видео, меньшее — лучше); -pix_fmt yuv420p — цветовой формат результирующего видео; //формирование потока и передача его WCS  -f flv rtmp://demo.flashphoner.com:1935/live/rtmp_stream — запись в поток с именем "rtmp_stream" и передача его на сервер demo.flashphoner.com. Итак. Захватываем экран в поток и ловим его на стороне WCS. (Здесь и далее я использую плеер из примера "Media Devices", потому что он позволяет на скриншоте показать наличие или отсутствие аудио потока.) Получаем поток скриншаринга. Правда без звука. На скриншоте видно, что в разделе "Audio stats" все по нулям.  Теперь предлагаю разобраться с захватом звука.  Первым шагом нужно определить доступные устройства для захвата звука. Все там же, в консоли Windows, выполняем команду:  Получаем примерно такую картину:  В результате выполнения команды выводится список устройств, которые могут записывать или выводить звук. Это будут колонки, микрофоны и веб-камеры. В этом списке найдите имя аудиоустройства, то есть ваших динамиков, с которых вы хотите записывать звук. На скриншоте аудиоустройство, с которого я собираюсь захватывать звук, называется "Stereo Mix (Realtek (R) Audio)".  Stereo Mix – одно из устройств записи звука.  Это виртуальное (программное) устройство, которое позволяет смешивать источники звука, воспроизводимые внутри операционной системы и получаемые с микрофона.  Чтобы захватить звук в исходную команду для скриншаринга нужно добавить ключи: где: //захват аудио составляющей скриншаринга -f dshow — драйвер захвата звука Windows; -i audio= — параметр "audio" в этом случае ставим равным альтернативному имени нашего "Stereo Mix (Realtek (R) Audio)"; //захват видео составляющей скриншаринга //кодирование аудио составляющей скриншаринга -acodec aac — сжимать аудио будем кодеком aac; //кодирование видео составляющей скриншаринга //формирование потока и передача его WCS  Запускаем:  И наслаждаемся: Существует еще альтернативный метод. Он будет полезен, если у вас на компьютере нет устройства "Stereo Mix" или драйвер вашей звуковой карты его, по каким-то причинам, не поддерживает.  Для реализации альтернативного метода нам понадобится небольшая утилита "VB-Audio Virtual Cable" (На момент написания этой статьи распространяется бесплатно).  VB-CABLE — это виртуальное аудиоустройство, работающее как виртуальный аудиокабель. Весь звук, поступающий на вход CABLE, просто пересылается на выход CABLE. Скачиваем программу VB-CABLE и устанавливаем. Установка не представляет собой ничего примечательного.  Запускаем установочный файл от имени администратора:  И нажимаем кнопку "Install Driver" После установки нужно переключить устройство по умолчанию для воспроизведения и записи аудио на установленный виртуальный кабель.  Теперь, звуки, воспроизводимые в программах, будут перенаправляться на виртуальное устройство Cable Output, которое будет работать как обычный микрофон и, соответственно, позволит захватить воспроизводимое аудио. Однако, при этом есть один недостаток: во время этого вы не будете слышать то, что записываете (т.е. звук вместо динамиков или наушников будет направляться на виртуальное устройство записи).  Теперь снова определяем доступные устройства для захвата аудио  Видим, что в списке устройств появилось устройство  "CABLE Output (VB-Audio Virtual Cable)" Запускаем захват скриншаринга с использованием этого устройства. Обращаемся к нему так же по альтернативному имени: В этом примере мы запускаем скриншаринг на ОС Ubuntu Desktop 20.04 LTS.  Начнем с определения доступных для захвата аудиоустройств. Выполните в консоли следующую команду:  Вывод будет примерно таким как на скриншоте.  Для дальнейшей работы нас интересует устройство, которое в Ubuntu называется "Monitor of Built-in Audio Analog Stereo". Это виртуальное устройство, которое, как и его кузен "Windows Stereo Mix",  позволяет смешивать системные звуки и звуковой поток, получаемый  с микрофона. Для дальнейшей работы нам понадобится значение индекса этого устройства.  Запускаем скриншаринг в поток с помощью FFmpeg: где: //захват аудио составляющей скриншаринга -f pulse — драйвер захвата звука Linux; -ac 2 — режим аудио "стерео" (-ac 1 — режим аудио "моно"); -i 0 — указываем индекс устройства для захвата аудио. Как мы ранее выяснили, для "Monitor of Built-in Audio Analog Stereo" это "0" ; //захват видео составляющей скриншаринга -f x11grab — опция необходима, если вы захватываете экран Linux; -rtbufsize 100M — буфер под видео;  -s 1200x720  — размеры захватываемой на экране области. В px; -framerate 30 — частота кадров при захвате экрана; -probesize 10M — количество кадров необходимое FFmpeg для идентификации потока; -draw_mouse 1 — захват движений мышки; -i :0.0 — координаты "первой точки" захватываемой области экрана; //кодирование аудио составляющей скриншаринга -acodec aac — сжимать аудио будем кодеком aac; //кодирование видео составляющей скриншаринга -c:v libx264 — сжимать видео будем в формат MP4 кодеком x264; -r 30 — кодек запишет видео с частотой 30 кадров в секунду; -preset ultrafast — кодировать поток как можно быстрее (при записи экрана это актуально); -tune zerolatency — опция кодека x264 для ускорения кодирования; -crf 25 — качество записываемого видео (большее значение — хуже видео, меньшее — лучше); -pix_fmt yuv420p — цветовой формат результирующего видео; //формирование потока и передача его WCS  -f flv rtmp://demo.flashphoner.com:1935/live/rtmp_stream —  запись в поток с именем "rtmp_stream" и передача его на сервер demo.flashphoner.com. Проверяем.  Запускаем воспроизведение ролика в плеере, в консоли Ubuntu запускаем FFmpeg команду, которую разобрали выше: На стороне WCS сервера открываем любой удобный плеер и запускаем воспроизведение захваченного потока скриншаринга по WebRTC (имя потока rtmp_stream). Сравнительная таблица ключей FFmpeg для скриншаринга с захватом системного звука и передачи данных в поток на WCS Windows Linux Драйвер захвата звука -f dshow -f pulse Указание устройства для захвата звука -i  audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{8A4D10E5-8DB9-4B92-8C29-4BA2E60C1DDE}"  -i 0 Драйвер захвата экрана -f  gdigrab -f x11grab Буфер под видео -rtbufsize  100M -rtbufsize  100M Размеры захватываемой на экране области -i desktop -i :0.0  -s  1200x720 Частота кадров при захвате экрана -framerate 30 -framerate 30 Количество кадров необходимое FFmpeg для  идентификации поток -probesize 10M -probesize  10M Захватывать движения мыши -draw_mouse 1 -draw_mouse  1 Кодек для сжатия аудио -acodec  aac -acodec aac Кодек для сжатия видео -c:v libx264 -c:v  libx264 Частота кадров итогового видео -r 30 -r 30 Опция для ускорения кодирования -preset  ultrafast -preset  ultrafast Опция кодека x264 для ускорения  кодирования -tune  zerolatency -tune  zerolatency Качество записываемого видео -crf 25 -crf 25 Цветовой формат результирующего видео -pix_fmt  yuv420p -pix_fmt  yuv420p Запись в поток на сервер demo.flashphoner.com -f flv rtmp://demo.flashphoner.com:1935/live/rtmp_stream -f flv rtmp://demo.flashphoner.com:1935/live/rtmp_stream Сегодня мы в подробностях разобрали тонкости скриншаринга со звуком при помощи FFmpeg для операционных систем Windows и Linux. В дальнейшем, с потоком скриншаринга, который был захвачен на сервере можно производить любые действия, поддерживаемые WCS. Он может быть  записан, воспроизведен, ретранслирован, транскодирован или добавлен к микшеру.  Удачного стриминга!  Наш демо сервер WCS на Amazon EC2 - Быстрое развертывание WCS на базе Amazon WCS на DigitalOcean - Быстрое развертывание WCS на базе DigitalOcean WCS в Docker - Запуск WCS как Docker контейнера  Документация по быстрому развертыванию и тестированию WCS сервера Документация по захвату и транляции видеопотока на сервер при помощи FFmpeg Streaming video engineer