Недавно я наткнулся на топик "Сервер онлайн-вещаний на базе nginx" о замечательном модуле Романа Арутюняна (@rarutyunyan) для nginx: nginx-rtmp-module. Модуль очень прост в настройке и позволяет на основе nginx создать сервер публикации видеозаписей и живого вещания.
Про сам модуль можно прочитать на его странице на GitHub, я же хочу привести несколько простых примеров использования. Надеюсь, топик поможет новичкам в видеоделах (таким как я).
RTMP (Real Time Messaging Protocol) — проприетарный протокол вещания от Adobe. В качестве транспорта по умолчанию используется TCP (порт 1935). Также можно инкапсулировать RTMP в HTTP (RTMPT). Клиент RTMP — это в первую очередь Adobe Flash Player.
Кодек видео — H.264, кодек аудио AAC, nellymoser или MP3, контейнеры MP4 или FLV.
Иначе говоря, видео по запросу (VOD). Просто добавьте в nginx.conf в секцию rtmp { server {… }}.
(Прим.: конечно, секцию не обязательно называть vod)
Теперь можно положить в папку /var/videos видеофайл в правильном формате и «скормить» плееру источник, например rtmp://server/vod/file.flv. Насколько я понял, MP4 нативно поддерживает перемотку видео, а FLV придется индексировать отдельно.
Все приведенные далее примеры будут уже про «живую» трансляцию с помощью ffmpeg под Windows. Впрочем, эта информация будет полезна и для пользователей Linux.
Мы можем отправить поток видео и аудио на сервер используя все тот же протокол RTMP для публикации. А наши клиенты смогут трансляцию смотреть. Для этого на сервере надо добавить секцию:
Рекомендую сразу закрыть доступ на публикацию всем, кроме доверенных IP, как показано в примере.
На машине, с которой мы будем вещать, для начала надо получить список устройств DirectShow. Пуск — Выполнить — cmd, переходим в папку ffmpeg/bin и запускаем:
Если в названии вашего источника есть русские буквы, то они могут отобразиться кракозябрами. ТруЪ админы заюзают iconv, а простые парни вроде меня раскодируют бяку на сайте Лебедева. FFmpeg'у нужно скормить читабельную надпись.
Теперь, зная имя видео и аудио источника, можно захватить его при помощи ffmpeg и отправить на сервер.
Как минимум нужно указать источник видео, кодек и сервер:
Вместо «Webcam C170» нужно подставить название вашей камеры из списка.
Ключ -an говорит о том, что мы не передаем аудио поток. Если аудио поток нужен, то строка запуска будет выглядеть примерно так:
Здесь мы использует кодек libfaac, частота дискретизации 44100, 2 канала (стерео). Можно вместо AAC использовать MP3 (кодек libmp3lame).
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/1db/31b/9e0/1db31b9e0032fcb8169e0988afb7db77.jpg)
Если у вашей камеры аналоговый выход, то ее можно подключить к компьютеру с помощью устройства захвата. Я использую дешевую PAL камеру и USB плату захвата с Dealextreme.
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/85d/d50/4fb/85dd504fb35ad6b954911159ca2eba03.jpg)
Тут есть два варианта: установить FFSplit или использовать screen-capture-recorder с FFmpeg.
FFSplit использовать проще, т.к. у него есть удобный GUI, но он не работает под XP/2003.
Если вы решили выбрать второй способ, то строка запуска FFmpeg будет выглядеть примерно так:
Аудио-поток можно захватить с virtual-audio-capturer.
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/9ed/44d/3cc/9ed44d3cca963e6adac56fa167c7e6e1.jpg)
Пример захвата экрана в приложении
Естественно, вы можете ретранслировать видео или аудио файл (или поток) FFmpeg на сервер. В примере ниже мы передаем MJPEG видео с удаленной камеры:
Но для таких целей более разумно использовать опцию push на самом RTMP-сервере, чтобы исключить промежуточное звено и вытягивать поток на самом сервере.
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/2a1/e3b/ce1/2a1e3bce175c9143dcdf87430a60c3c0.jpg)
Какая-то веб-камера в Японии
-preset имя У H.264 есть несколько наборов настроек соотношения компрессия/скорость: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. Поэтому если вы хотите повысить производительность, стоит использовать:
-crf число непосредственно влияет на битрейт и качество. Принимает значения от 0 до 51 — чем больше, тем ниже качество картинки. По умолчанию 23, 18 — losless качество. Битрейт примерно удваивается при уменьшении CRF на 6.
-r число задает входной и выходной FPS. Для источников, с которых вы захватываете картинку, можно установить вместо -r -re, чтобы использовать «родной» FPS.
-rtbufsize число размер буфера реального времени. Если у вас постоянно появляются сообщения о переполнении буфера и отбрасывании кадров, вы можете поставить большой буфер (например, 100000k), однако это может увеличить задержку передачи.
-pix_fmt задает цветовую модель. Если у вас вместо картинки показывается черный квадрат, а звук работает, попробуйте поставить yuv420p или yuv422p.
-s ширинаxвысота входной и выходной размер картинки.
-g число насколько я понял, это максимальное число кадров между ключевыми. Если у вас FPS очень маленький, то можно поставить это значение поменьше, чтобы уменьшить задержку начала трансляции.
-keyint_min число минимальное число кадров между ключевыми.
-vf «crop=w:h:x:y» обрезать видео
-tune zerolatency «волшебная» опция уменьшения задержки трансляции. Что она конкретно делает я так и не нашел (-:
-analyzeduration 0 отключает анализ длительности, что помогает снизить задержку трансляции
Помимо рассмотренных выше параметров аудио вам может понадобиться -acodec copy в том случае, если ваш аудио поток не требует дополнительной перекодировки в MP3/AAC.
Пример: вещаем с веб-камеры с низкой задержкой без звука, рисуем в верхней части картинки текущее время
Тут все просто. Поставьте на свой сайт один из популярных плееров, например Flowplayer или JW Player.
Пример подключения JW Player вы можете посмотреть на странице демо трансляции.
С помощью модуля rtmp можно создать не только видеотрансляцию, но и видеочат, интернет-радио, простую платформу для вебинаров. Дерзайте!
Я рассмотрел лишь базовую функциональность nginx-rtmp-module и ffmpeg. Возможности у них гораздо шире, поэтому обратите внимание на документацию:
Блог nginx-rtmp-module
Wiki nginx-rtmp-module
Документация FFmpeg
Streaming Guide
x264 Encoding Guide
Filtering Guide
Про сам модуль можно прочитать на его странице на GitHub, я же хочу привести несколько простых примеров использования. Надеюсь, топик поможет новичкам в видеоделах (таким как я).
Коротко об RTMP
RTMP (Real Time Messaging Protocol) — проприетарный протокол вещания от Adobe. В качестве транспорта по умолчанию используется TCP (порт 1935). Также можно инкапсулировать RTMP в HTTP (RTMPT). Клиент RTMP — это в первую очередь Adobe Flash Player.
Кодек видео — H.264, кодек аудио AAC, nellymoser или MP3, контейнеры MP4 или FLV.
Публикация видеозаписи
Иначе говоря, видео по запросу (VOD). Просто добавьте в nginx.conf в секцию rtmp { server {… }}.
application vod {
play /var/videos;
}
(Прим.: конечно, секцию не обязательно называть vod)
Теперь можно положить в папку /var/videos видеофайл в правильном формате и «скормить» плееру источник, например rtmp://server/vod/file.flv. Насколько я понял, MP4 нативно поддерживает перемотку видео, а FLV придется индексировать отдельно.
Все приведенные далее примеры будут уже про «живую» трансляцию с помощью ffmpeg под Windows. Впрочем, эта информация будет полезна и для пользователей Linux.
Онлайн-трансляция
Мы можем отправить поток видео и аудио на сервер используя все тот же протокол RTMP для публикации. А наши клиенты смогут трансляцию смотреть. Для этого на сервере надо добавить секцию:
application live {
allow publish 1.2.3.4;
allow publish 192.168.0.0/24;
deny publish all;
allow play all;
live on;
}
Рекомендую сразу закрыть доступ на публикацию всем, кроме доверенных IP, как показано в примере.
На машине, с которой мы будем вещать, для начала надо получить список устройств DirectShow. Пуск — Выполнить — cmd, переходим в папку ffmpeg/bin и запускаем:
ffmpeg -list_devices true -f dshow -i dummy
Если в названии вашего источника есть русские буквы, то они могут отобразиться кракозябрами. ТруЪ админы заюзают iconv, а простые парни вроде меня раскодируют бяку на сайте Лебедева. FFmpeg'у нужно скормить читабельную надпись.
Теперь, зная имя видео и аудио источника, можно захватить его при помощи ffmpeg и отправить на сервер.
Веб-камера
Как минимум нужно указать источник видео, кодек и сервер:
ffmpeg -f dshow -i video="Webcam C170" -c:v libx264 -an -f flv "rtmp://1.2.3.4/live/test.flv live=1"
Вместо «Webcam C170» нужно подставить название вашей камеры из списка.
Ключ -an говорит о том, что мы не передаем аудио поток. Если аудио поток нужен, то строка запуска будет выглядеть примерно так:
ffmpeg -f dshow -i video="Webcam C170" -f dshow -i audio="Микрофон ..." -c:v libx264 -c:a libfaac -ar 44100 -ac 2 -f flv "rtmp://1.2.3.4/live/test.flv live=1"
Здесь мы использует кодек libfaac, частота дискретизации 44100, 2 канала (стерео). Можно вместо AAC использовать MP3 (кодек libmp3lame).
![image](https://habrastorage.org/getpro/habr/post_images/1db/31b/9e0/1db31b9e0032fcb8169e0988afb7db77.jpg)
Аналоговая камера
Если у вашей камеры аналоговый выход, то ее можно подключить к компьютеру с помощью устройства захвата. Я использую дешевую PAL камеру и USB плату захвата с Dealextreme.
ffmpeg -r pal -s pal -f dshow -i video="USB2.0 ATV" -c:v libx264 -an -f flv "rtmp://1.2.3.4/live/test.flv live=1"
![image](https://habrastorage.org/getpro/habr/post_images/85d/d50/4fb/85dd504fb35ad6b954911159ca2eba03.jpg)
Захват экрана
Тут есть два варианта: установить FFSplit или использовать screen-capture-recorder с FFmpeg.
FFSplit использовать проще, т.к. у него есть удобный GUI, но он не работает под XP/2003.
Если вы решили выбрать второй способ, то строка запуска FFmpeg будет выглядеть примерно так:
ffmpeg -f dshow -i video="screen-capture-recorder" -c:v libx264 -an -r 2 -f flv "rtmp://1.2.3.4/live/test.flv live=1"
Аудио-поток можно захватить с virtual-audio-capturer.
![image](https://habrastorage.org/getpro/habr/post_images/9ed/44d/3cc/9ed44d3cca963e6adac56fa167c7e6e1.jpg)
Пример захвата экрана в приложении
Ретрансляция
Естественно, вы можете ретранслировать видео или аудио файл (или поток) FFmpeg на сервер. В примере ниже мы передаем MJPEG видео с удаленной камеры:
ffmpeg -f mjpeg -i video="http://iiyudana.miemasu.net/nphMotionJpeg?Resolution=320x240&Quality=Standard" -c:v libx264 -f flv "rtmp://1.2.3.4/live/test.flv live=1"
Но для таких целей более разумно использовать опцию push на самом RTMP-сервере, чтобы исключить промежуточное звено и вытягивать поток на самом сервере.
![image](https://habrastorage.org/getpro/habr/post_images/2a1/e3b/ce1/2a1e3bce175c9143dcdf87430a60c3c0.jpg)
Какая-то веб-камера в Японии
Тюнинг, решение проблем
-preset имя У H.264 есть несколько наборов настроек соотношения компрессия/скорость: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. Поэтому если вы хотите повысить производительность, стоит использовать:
-preset ultrafast
-crf число непосредственно влияет на битрейт и качество. Принимает значения от 0 до 51 — чем больше, тем ниже качество картинки. По умолчанию 23, 18 — losless качество. Битрейт примерно удваивается при уменьшении CRF на 6.
-r число задает входной и выходной FPS. Для источников, с которых вы захватываете картинку, можно установить вместо -r -re, чтобы использовать «родной» FPS.
-rtbufsize число размер буфера реального времени. Если у вас постоянно появляются сообщения о переполнении буфера и отбрасывании кадров, вы можете поставить большой буфер (например, 100000k), однако это может увеличить задержку передачи.
-pix_fmt задает цветовую модель. Если у вас вместо картинки показывается черный квадрат, а звук работает, попробуйте поставить yuv420p или yuv422p.
-s ширинаxвысота входной и выходной размер картинки.
-g число насколько я понял, это максимальное число кадров между ключевыми. Если у вас FPS очень маленький, то можно поставить это значение поменьше, чтобы уменьшить задержку начала трансляции.
-keyint_min число минимальное число кадров между ключевыми.
-vf «crop=w:h:x:y» обрезать видео
-tune zerolatency «волшебная» опция уменьшения задержки трансляции. Что она конкретно делает я так и не нашел (-:
-analyzeduration 0 отключает анализ длительности, что помогает снизить задержку трансляции
Помимо рассмотренных выше параметров аудио вам может понадобиться -acodec copy в том случае, если ваш аудио поток не требует дополнительной перекодировки в MP3/AAC.
Пример: вещаем с веб-камеры с низкой задержкой без звука, рисуем в верхней части картинки текущее время
ffmpeg -r 25 -rtbufsize 1000000k -analyzeduration 0 -s vga -copyts -f dshow -i video="Webcam C170" -vf "drawtext=fontfile=verdana.ttf:fontcolor=yellow@0.8:fontsize=48:box=1:boxcolor=blue@0.8:text=%{localtime}" -s 320x240 -c:v libx264 -g 10 -keyint_min 1 -preset UltraFast -tune zerolatency -crf 25 -an -r 3 -f flv "rtmp://1.2.3.4:1935/live/b.flv live=1"
Плеер на сайте
Тут все просто. Поставьте на свой сайт один из популярных плееров, например Flowplayer или JW Player.
Пример подключения JW Player вы можете посмотреть на странице демо трансляции.
Что дальше?
С помощью модуля rtmp можно создать не только видеотрансляцию, но и видеочат, интернет-радио, простую платформу для вебинаров. Дерзайте!
Я рассмотрел лишь базовую функциональность nginx-rtmp-module и ffmpeg. Возможности у них гораздо шире, поэтому обратите внимание на документацию:
Блог nginx-rtmp-module
Wiki nginx-rtmp-module
Документация FFmpeg
Streaming Guide
x264 Encoding Guide
Filtering Guide