Раздача картинки с видеокамеры


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

Важным моментом в задаче, являлось то, что обновление кадров может происходить достаточно редко - от раз в секунду до нескольких минут.

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

Первой мыслью было сделать это все через rtmp потоки через vlc или erlyvideo. Но, похоже, VLC этого просто не умеет, а elyvideo у меня под FreeBSD с первой попытки не завелся, хотя говорят должно отлично работать.

В итоге, после некоторых мучений было решено получать поток через ffmpeg, из него сохранять картинки с некоторой периодичностью, и уже их публиковать на сайт.

С помощью ffmpeg получаем видео и складываем картинки в выбранный каталог:

ffmpeg -i rtsp://user:pass@IP-camera/mpeg4/ch1/main/av_stream -r ${time_caprute} -loglevel quiet pict_%d.jpg > /dev/null 2>&1

После этого полученными файлами вида pict_1.jpg, pict_2.jpg и т.д. нужно обновлять файл pict.jpg. Делаем это следующим образом:

find -s ${base_dir}/  -name "pict_*.jpg" -ctime +${time_update}s -size +${min_size_file} -exec mv {} ${base_dir}/pict.jpg \;

здесь:

  • ${time_update} - задаем в секундах, насколько свежие файлы не нужно обрабатывать, чтобы не использовать файл, который еще полностью не записан.
  • ${min_size_file} - минимальный размер файла, который мы будем использовать. Требуется для того, чтобы в случае проблем, не показывать некачественную или черную картинку.

Удаляем брак

find ${base_dir}/ -name "pict_*.jpg" -ctime +${time_update}s -size -${min_size_file} -delete

Для того, чтобы особо не насиловать жесткий диск, предварительно под это дело создаем образ диска в памяти. Т.к. картинки маленькие и запас картинок у нас не большой, то вполне хватает и 5 MB, а вообще по вкусу.

mdmfs -s 5m md10 ${base_dir}

Для просмотра делаем простую страничку:

<HTML>
<HEAD>
<SCRIPT LANGUAGE=JavaScript>
<!--
var n = 0;
function camon() {
cam1.innerHTML = "<img src=pict.jpg?"+(n++)+" height=480 width=640>";
var timer=setTimeout ("camon()", 15000)
}
//-->
</SCRIPT>

<center>
<font size=+2>My Pict</font><br>
<span id="cam1" style="visibility: visible; font-family: Arial,sans-serif"></span>
</center>
</HEAD>
<BODY onLoad="camon()">
</BODY>
</HTML>

При открытии этой станички у нас будет каждые 15 секунд обновляться картинка.

Итого, мы имеем сервер, который получает RTSP видео поток (а на самом деле, может получать любой поток) с одного источника, и раздает уже более статичную, но обновляемую с нужной частотой картинку.

Возможно, решение кривое, но вполне рабочее и совместимое с любыми клиентами поддерживающими яваскрипт, ну или можно вручную нажимать кнопочку "обновить". wink

P.S. Всем, у кого, что-то стырил, большое спасибо. smiley