- Дать доступ к камере. Просто доступ к камере давать не стоит по соображениям безопасности. Камера ляжет уже при очень небольшой нагрузке.
- Коммерческая услуга. Мы им доступ к камере и деньги, они нам ссылку для размещения на сайте. Они же решают проблему совместимости камеры и браузеров пользователей, производительности канала и доступности
- На своих мощностях. Между пользователем и камерой ставится нечто, что отвечает за совместимость с браузерами, производительность и доступность. Проблемы решаем сами.
Этот вариант рассмотрим ниже. Т.к. "flash умер" или "flash вот-вот умрет", вариант с размещением flash плейера на сайте не рассматривался. Тернистый путь поисков решений в интернетах не привел к готовому решению. Пришлось изобрести велосипед.
Подробнее изобретения под катом.
Описание полученного велосипеда подробнее:
- камера видеонаблюдения отдает поток по протоколу rtsp.
- ffmpeg берет видео поток с камеры и создает видео для показа через тег video стандарта html5.
- nginx отдает созданные файлы пользователям
- видео на странице показываем с помощью hls, точнее вот эта реализация
Подробнее о настройках
На каждый поток с камеры надо запустить ffmpeg для преобразования rtsp в файлы который поймет hls.
ffmpeg и поток со звуком
/usr/bin/ffmpeg -i rtsp://<этот путь можно найти через ONVIF Device Manager> -ar 44100 -acodec aac -ac 1 -strict -2 -crf 18 -c:v copy -preset ultrafast -flags -global_header -fflags flush_packets -tune zerolatency -hls_time 1 -hls_list_size 3 -hls_wrap 4 -hls_flags delete_segments -start_number 0 /tmp/www/index1.m3u8
Guessed Channel Layout for Input Stream #0.1 : mono
Input #0, rtsp, from 'rtsp://192.168.X.X:554/user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?':
Metadata:
title : RTSP Session
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: h264 (Baseline), yuv420p, 1920x1080, 25 fps, 9 tbr, 90k tbn, 50 tbc
Stream #0:1: Audio: pcm_alaw, 8000 Hz, 1 channels, s16, 64 kb/s
Output #0, hls, to '/tmp/www/index1.m3u8':
Metadata:
title : RTSP Session
encoder : Lavf56.25.101
Stream #0:0: Video: h264, yuv420p, 1920x1080, q=2-31, 25 fps, 9 tbr, 90k tbn, 25 tbc
Stream #0:1: Audio: aac, 44100 Hz, mono, fltp, 128 kb/s
Metadata:
encoder : Lavc56.26.100 aac
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (pcm_alaw (native) -> aac (native))
Видео просто копируется, аудио пришлось перекодировать иначе тишина.Камера noname.
Как работает:
Берем поток, без перекодирования создаем файлы и список для воспроизведения в папке /tmp/www/.
nginx
Сокращаем стандартный для пакета debian файл default до, например, такого:
server {
listen 80 default_server;
listen [::]:80 default_server;
access_log off;
error_log /dev/null;
root /tmp/www;
index index.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
Пример страницы с видео:
<!DOCTYPE html>
<html>
<head>
<title>Заголовок</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/hls.js/latest/hls.min.js"></script>
<video id="video"></video>
<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.loadSource('/index1.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
</script>
Скрипт стоит разместить локально, он не имеет внешних зависимостей. Подробнее о настройках hls.
Как работает:
на странице подключается hls и воспроизводит файлы из списка index1.m3u8. Список и файлы обновляются ffmpeg.
Что получилось:
- Работает;
- Самую большую нагрузку создает ffmpeg, на процессоре Atom трехлетней давности;
- Разрешение камеры Full HD без звука — 1%;
- Разрешение камеры Full HD со звуком — 5%;
- Количество процессов nginx — смотреть по нагрузке и доступному каналу. Нагрузку на процессор увидеть не удалось — не очень много надо на просто отдачу небольших файлов.;
- Сервер с ffmpeg и nginx можно разместить где угодно, не обязательно на хостинге или в месте расположения камер;
- Отставание от потока зависит от количества файлов в списке и размера(в секундах) файла. Например отставание в 10 секунд не очень влияет на просмотр процесса строительства многоэтажки;
- Видеофайлы лучше размещать на tmpfs, они имеют небольшие размеры и часто они перезаписываются;
- Весь сервис стоит поместить в контейнер. Все пакеты стандартные для
FROM debian:jessie
; - По итогам эксплуатации ffmpeg иногда падает, за ним нужно следить и перезапускать если упал.
Вывод top из контейнера:top - 11:05:20 up 6 days, 12:15, 0 users, load average: 1.29, 1.09, 1.03 Tasks: 17 total, 1 running, 16 sleeping, 0 stopped, 0 zombie %Cpu(s): 38.8 us, 1.0 sy, 0.0 ni, 59.6 id, 0.0 wa, 0.0 hi, 0.5 si, 0.0 st KiB Mem: 16359132 total, 16027988 used, 331144 free, 782968 buffers KiB Swap: 6369276 total, 3776 used, 6365500 free. 12784916 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 281 root 20 0 341040 29192 19632 S 4.7 0.2 10:08.39 ffmpeg 16 root 20 0 315888 27944 18984 S 1.0 0.2 2:50.95 ffmpeg 9 root 20 0 46916 15128 6408 S 0.3 0.1 0:58.04 supervisord
- Смотреть можно на десктопах и мобильных устройствах с современными браузерами;
- В обозримом будущем не потребует вмешательства.
Ссылки:
» Реализация hls
» Демо работы hls
» ffmpeg
» nginx
» Дополненный и расширенный текст статьи на моём блоге
Комментарии (26)
bitver
31.01.2017 13:59Было и легко ищется.
https://habrahabr.ru/post/162237/ErshoFF
31.01.2017 14:03+1Я ждал этого коммента.
Спасибо, что не обманули ожидания.
Но почитайте внимательно материал по вашей ссылке и то, что я написал.
Мой путь проще повторить, на обычной пакетной базе debian.
Ничего не надо компилировать.
Всё сопровождение свелось к обеспечению перезапуска ffmpeg, который изредка но падает.
Работает в любом современном браузере, в т.ч. и на мобильных.
Не требует flash.Segmentq
31.01.2017 14:11Повторюсь, есть же motion.
ErshoFF
31.01.2017 14:14Motion видел, пробовал пользоваться, у меня не сложилось с ним.
Если не трудно оставьте здесь ссылку на инструкцию, как motion приладить к показу на сайте картинки с онлайн камеры. Кому-нибудь это поможет.LionisIAm
01.02.2017 10:43А как ещё решить вопрос записи по движению? У меня запущен motion, НЕ доволен. Сразу скажу, что камера — китайская самая дешевая, может поэтому и не нравится качество. На выходе что трансляции, что записи — примерно 0,25 фпс.
sriver
31.01.2017 17:49Хороший мануал, спасибо.
Сделал все по нему, на ПК — все ок, а вот на Андроиде (Chrome) я получаю один кадр — статичную картинку и все, что я могу делать не так?
Avenit
01.02.2017 00:33За 15 минут настроил на Gentoo (некоторые параметры не распознавал, убрал их), работает в Chrome для Windows, сразу начинает трансляцию. А вот из под Safari для IOS пустая страница :(
Кстати ссылку на плейлист можно скормить VLC, он ее скушает :)ErshoFF
01.02.2017 07:29На ios нет устройств — проверить не могу, но по описанию должно работать.
В Chrome на ios работает?Avenit
01.02.2017 10:18Проверил — не работает.
Что интересно, если открыть напрямую файл плейлиста — воспроизводит видеопоток.
Так, что скорее всего проблема в скрипте hls.ErshoFF
01.02.2017 10:48Тестировать не на чем — не смогу подсказать ничего.
Внизу статьи ссылка «Демо работы hls» — видео работает?Avenit
01.02.2017 16:10нет, видео не проигрывается
ErshoFF
01.02.2017 17:46У вас видео+звук или просто видео?
Avenit
02.02.2017 17:17только видео
ErshoFF
02.02.2017 23:36hls.js разрабатывается, последнее изменение вчера.
Очень вероятно, что скоро допилят до рабочего состояния. Попробуйте последнюю версию с git-hub.
У меня тоже (widows+chrome) иногда останавливается картинка+звук. Думал что особенность двух потоков…
Rumlin
а сколько кадров в секунду?
ErshoFF
Забыл упомянуть fps, вот вывод ffmpeg с живого сервера, да здесь и разрешение оказывается FullHD
Видео просто копируется, аудио пришлось перекодировать иначе тишина.
Камера noname/
ErshoFF
Добавил в статью вывод ffmpeg.
Rumlin
Тогда понятно почему низкая загрузка. Я подумал это дешевая камера с MJPEG и поток перекодируют в h264 и начал подозревать неладное при упоминании Атома.
ErshoFF
Цель как раз и была в низкой нагрузке на CPU.
Перекодирование убивало Atom в ноль.
В текущем случае похоже идет «перепаковка» не требующая ресурсов процессора.
Перекодирование звука создает заметную нагрузку.
Если не нужно разрешение FullHD — возьмите с камеры поток/fps поменьше.
Rumlin
За камеру FullHD уже уплачено, иначе можно купить дешевле. Поэтому надо дожимать всё.
remzalp
Я решал аналогичную задачу более суровым методом — в итоге гоню поток MJPG через промежуточный прокси во Flash плэйер.
Эта статья — просто радость какая-то, потому что проще собственно уже некуда.
ErshoFF
Спасибо.