Видео с камеры наблюдения на сайте бесплатно и без смс

  • Tutorial
Появилась необходимость показывать видео с камеры на сайте в режиме онлайн. Виделось несколько вариантов (дополню вариантами из комментов, если будут):

  • Дать доступ к камере. Просто доступ к камере давать не стоит по соображениям безопасности. Камера ляжет уже при очень небольшой нагрузке.
  • Коммерческая услуга. Мы им доступ к камере и деньги, они нам ссылку для размещения на сайте. Они же решают проблему совместимости камеры и браузеров пользователей, производительности канала и доступности
  • На своих мощностях. Между пользователем и камерой ставится нечто, что отвечает за совместимость с браузерами, производительность и доступность. Проблемы решаем сами.

Этот вариант рассмотрим ниже. Т.к. "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
ffmpeg при старте пишет 25 fps при FullHD
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 до, например, такого:

/etc/nginx/sites-enabled/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;
        }
}

Пример страницы с видео:

/tmp/www/index.html
<!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
» Дополненный и расширенный текст статьи на моём блоге
Поделиться публикацией
Никаких подозрительных скриптов, только релевантные баннеры. Не релевантные? Пиши на: adv@tmtm.ru с темой «Полундра»

Зачем оно вам?
Реклама
Комментарии 29
  • 0
    Разрешение камеры HD со звуком

    а сколько кадров в секунду?
    • +1
      Забыл упомянуть fps, вот вывод ffmpeg с живого сервера, да здесь и разрешение оказывается FullHD
      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/
      • 0
        Добавил в статью вывод ffmpeg.
        • 0
          Тогда понятно почему низкая загрузка. Я подумал это дешевая камера с MJPEG и поток перекодируют в h264 и начал подозревать неладное при упоминании Атома.
          • 0
            Цель как раз и была в низкой нагрузке на CPU.

            Перекодирование убивало Atom в ноль.
            В текущем случае похоже идет «перепаковка» не требующая ресурсов процессора.
            Перекодирование звука создает заметную нагрузку.

            Если не нужно разрешение FullHD — возьмите с камеры поток/fps поменьше.
            • 0
              За камеру FullHD уже уплачено, иначе можно купить дешевле. Поэтому надо дожимать всё.
            • 0
              Я решал аналогичную задачу более суровым методом — в итоге гоню поток MJPG через промежуточный прокси во Flash плэйер.

              Эта статья — просто радость какая-то, потому что проще собственно уже некуда.
      • 0
        Было и легко ищется.
        https://habrahabr.ru/post/162237/
        • +1
          Я ждал этого коммента.
          Спасибо, что не обманули ожидания.

          Но почитайте внимательно материал по вашей ссылке и то, что я написал.

          Мой путь проще повторить, на обычной пакетной базе debian.
          Ничего не надо компилировать.
          Всё сопровождение свелось к обеспечению перезапуска ffmpeg, который изредка но падает.
          Работает в любом современном браузере, в т.ч. и на мобильных.
          Не требует flash.
          • 0
            Повторюсь, есть же motion.
            • 0
              Motion видел, пробовал пользоваться, у меня не сложилось с ним.

              Если не трудно оставьте здесь ссылку на инструкцию, как motion приладить к показу на сайте картинки с онлайн камеры. Кому-нибудь это поможет.
              • 0
                А как ещё решить вопрос записи по движению? У меня запущен motion, НЕ доволен. Сразу скажу, что камера — китайская самая дешевая, может поэтому и не нравится качество. На выходе что трансляции, что записи — примерно 0,25 фпс.
        • 0
          Хороший мануал, спасибо.
          Сделал все по нему, на ПК — все ок, а вот на Андроиде (Chrome) я получаю один кадр — статичную картинку и все, что я могу делать не так?
          • 0
            Попробуйте на телефоне посмотреть через последний Firefox.
            • 0
              За 15 минут настроил на Gentoo (некоторые параметры не распознавал, убрал их), работает в Chrome для Windows, сразу начинает трансляцию. А вот из под Safari для IOS пустая страница :(

              Кстати ссылку на плейлист можно скормить VLC, он ее скушает :)
              • 0
                На ios нет устройств — проверить не могу, но по описанию должно работать.
                В Chrome на ios работает?
                • 0
                  Проверил — не работает.
                  Что интересно, если открыть напрямую файл плейлиста — воспроизводит видеопоток.
                  Так, что скорее всего проблема в скрипте hls.
                  • 0
                    Тестировать не на чем — не смогу подсказать ничего.

                    Внизу статьи ссылка «Демо работы hls» — видео работает?
                    • 0
                      нет, видео не проигрывается
                      • 0
                        Тогда похоже этот вариант (ffmpeg+hls реализация) не заработает на ios.
                        • 0
                          ffmpeg как раз работает нормально, файл поток напрямую проигрывается на ios, не играет с веб-страницы!
                        • 0
                          У вас видео+звук или просто видео?
                          • 0
                            только видео
                            • 0
                              hls.js разрабатывается, последнее изменение вчера.
                              Очень вероятно, что скоро допилят до рабочего состояния. Попробуйте последнюю версию с git-hub.

                              У меня тоже (widows+chrome) иногда останавливается картинка+звук. Думал что особенность двух потоков…
                • 0
                  Интересно, а как Ivideon работает, там тоже флеша нет.
                  • 0
                    А как вы запускаете и контролируете ffmpeg?
                    • +1
                      Мало ли кому-то будет полезно, расскажу о своем опыте запуска ffmpeg.
                      Я хочу использовать в качестве «железа» raspberry pi. Не знаю, хватит ли производительности, но для того, чтобы не писать на медленную карту памяти я использую для хранения index* файлов tmpfs. С параметрами ffmpeg как в статье, моя камера выдает около 2 мб файлов. На всякий случай сделал tmpfs на 10 мб.
                      Скрипт, который монтирует tmpfs, запускает ffmpeg, а после выход размонтирует:
                      #!/bin/bash
                      
                      #монтирование tmpfs
                      /bin/mount -t tmpfs -o size=10M tmpfs /www/mysite.name/camera/tmpfs/
                      
                      #запуск ffmpeg
                      /usr/bin/sudo -u www-data /usr/bin/ffmpeg -i rtsp://admin:admin@192.168.168.168:554/1 -an -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 /www/mysite.name/camera/tmpfs/index1.m3u8
                      
                      #размонтирование tmpfs
                      /bin/umount /www/mysite.name/camera/tmpfs/
                      


                      В debian используется systemd, для запуска и перезапуска вот такой конфиг:
                      [Unit]
                      Description=ffmpeg ip camera service
                      After=multi-user.target
                      
                      [Service]
                      Type=simple
                      ExecStart=/www/mysite.name/camera/ffrun.sh
                      Restart=always
                      
                      [Install]
                      WantedBy=multi-user.target
                      


                      В итоге если в ручную прибить процесс ffmpeg, systemd перезапустит скрипт.
                      • 0
                        Какой полезный скрипт :)
                        А архивы не реализовывали?

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.