LINUX.ORG.RU
ФорумAdmin

Запись RTSP потоков с IP-камер в *.mp4 файлы с датой-временем в имени файла

 , , , ,


2

2

Здравствуйте, уважаемые форумчане. Прошу помощи по следующему вопросу. У меня есть в локальной сети три IP-камеры и компьютер с Debian.

Вот RTSP-URL-ы к этим камерам:

rtsp://admin:123456@192.168.0.124:1004/mpeg4
rtsp://admin:123456@192.168.0.125:1005/mpeg4
rtsp://admin:123456@192.168.0.126:1006/mpeg4

Нужно на компьютере с Debian организовать что-то вроде видеорегистратора: записать эти RTSP-потоки в *.mp4 файлы, длительностью в 1 час (время настраиваемое) на каждый файл, и разложить их по папкам в таком виде:

/home/user/records/cam_192_168_0_124_1004/2016/07/26
/home/user/records/cam_192_168_0_125_1005/2016/07/26
/home/user/records/cam_192_168_0_126_1006/2016/07/26

где «cam_»-простая приписка, «192_168_0_124_1004» взять из IP-адреса и порта соответственно, «2016»-год, «07»-месяц, «26»-день в которые записан файл.

Туда положить файлы с именами в таком виде:

cam_192_168_0_124_1004-YYYY-MM-DD--HH-MM-SS-mmm.mp4

где «cam_»-простая приписка, «192_168_0_124_1004» взять из IP-адреса и порта соответственно, YYYY-год, MM-месяц, DD-день, HH-часы, MM-минуты, SS-секунды, mmm-миллисекунды (то есть, IP адрес, порт, дата-время создания файла в имени этого файла).

Чтобы шаблоны имен файлов и папок были настраиваемыми. Чтобы можно было также регулировать занимаемое дисковое пространство папкой

/home/user/records
если объем превышен - удалить самый старый файл

Перерыл весь интернет, ничего нормального не нашел. Как это можно сделать?

Ответ на: комментарий от DALDON

zoneminder лютое УГ. пишет всё в картинки.

Deleted
()

Флюссоник, который мы разрабатываем в Эрливидео имеет такую фичу (DVR) и она у нас хорошо обкатана: http://erlyvideo.ru/ Но наш софт стоит денег.

А вообще можешь попробовать сделать скрипт, который будет запускать ffmpeg, который будет читать видео с камеры и записывать в mp4.

Соответственно раз в час убивать ffmpeg, и стартовать заново (можно чуть загодя). Побочный эффект — будут пропуски либо наоборот видео внахлёст между двумя часовыми файлами.

Кроме того, ffmpeg может отвалиться (если камера начнёт глючить и давать плохой контент или ещё чего), нужно ещё не забывать поднимать его. Отвалившийся ffmpeg, значит что нужно открыть новый файл и писать заново. Не уверен что ffmpeg умеет дописывать в mp4.

vladimir-vg ★★
()
Ответ на: комментарий от vladimir-vg

Ффмпег, который мы разрабатываем в опенсорсе имеет такую фичу (DVR) и она у нас хорошо обкатана: http://ffmpeg.org/ Но наш софт нужно уметь использовать.

А вообще можешь попробовать сделать скрипт, который будет запускать Флюссоник, который будет читать видео с камеры и записывать в mp4.

Соответственно раз в час убивать Флюссоник, и стартовать заново (можно чуть загодя). Побочный эффект — будут пропуски либо наоборот видео внахлёст между двумя часовыми файлами.

Кроме того, Флюссоник может отвалиться (если камера начнёт глючить и давать плохой контент или ещё чего), нужно ещё не забывать поднимать его. Отвалившийся Флюссоник, значит что нужно открыть новый файл и писать заново. Не уверен что Флюссоник умеет дописывать в mp4.

ruzisufaka
()

Я делаю так:

openRTSP -K -b 1000000 -4 -P 300 -c -v -t -F ./cam rtsp://10.0.1.249/11

Получаю файлы по пять минут, потом склеиваю раз в час:

local OLD_FNAME=`echo \`ls -tr ${DIR_CAM}rec/*.mp4 | grep "-" | sed -e '$d'\``;
mencoder -msglevel all=-1 -forceidx -oac copy -ovc copy -of lavf -lavfopts format=mp4 -o ${DIR_CAM}rec/_temp.mp4 $OLD_FNAME

Потом перемещаю куда надо.

screamager
()
Ответ на: комментарий от frozen_twilight

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

В описании установки у него написано «убедитесь что ffmpeg, node и npm установлены, если это так - выполните команду»

npm install -g aa-recorder

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

1. Установил ffmpeg как написано здесь, единственный рабочий вариант установки, который я нашел

2. Установил nodejs

apt-get install nodejs-legacy

3. Установил npm

apt-get install npm

4. Установил на всякий случай git

apt-get install git

5. Cкачал и распаковал aa-recorder

wget https://github.com/asquared/aa-recorder/archive/master.zip
unzip master.zip
cd aa-recorder-master
6. Запустил указанную команду
npm install -g aa-recorder
после чего на экран было выдано куча ошибок
root@oper4:/home/user/aa-recorder-master# npm install -g aa-recorder
-
> ref@1.3.2 install /usr/local/lib/node_modules/aa-recorder/node_modules/diskusage/node_modules/ref
> node-gyp rebuild

make: вход в каталог «/usr/local/lib/node_modules/aa-recorder/node_modules/diskusage/node_modules/ref/build»
  CXX(target) Release/obj.target/binding/src/binding.o
In file included from ../src/binding.cc:7:0:
../node_modules/nan/nan.h:324:47: error: ‘REPLACE_INVALID_UTF8’ is not a member of ‘v8::String’
   static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
                                               ^
binding.target.mk:84: ошибка выполнения рецепта для цели «Release/obj.target/binding/src/binding.o»
make: *** [Release/obj.target/binding/src/binding.o] Ошибка 1
make: выход из каталога «/usr/local/lib/node_modules/aa-recorder/node_modules/diskusage/node_modules/ref/build»
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/share/node-gyp/lib/build.js:267:23)
gyp ERR! stack     at ChildProcess.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:809:12)
gyp ERR! System Linux 3.16.0-4-amd64
gyp ERR! command "nodejs" "/usr/bin/node-gyp" "rebuild"
gyp ERR! cwd /usr/local/lib/node_modules/aa-recorder/node_modules/diskusage/node_modules/ref
gyp ERR! node -v v0.10.29
gyp ERR! node-gyp -v v0.12.2
gyp ERR! not ok
npm WARN This failure might be due to the use of legacy binary "node"
npm WARN For further explanations, please read
/usr/share/doc/nodejs/README.Debian


> ffi@2.0.0 install /usr/local/lib/node_modules/aa-recorder/node_modules/diskusage/node_modules/ffi
> node-gyp rebuild


gyp ERR! UNCAUGHT EXCEPTION
gyp ERR! stack Error: ENOENT, no such file or directory
gyp ERR! stack     at process.cwd (/usr/lib/nodejs/graceful-fs/polyfills.js:8:19)
gyp ERR! stack     at Object.exports.resolve (path.js:309:52)
gyp ERR! stack     at configure (/usr/share/node-gyp/lib/configure.js:26:23)
gyp ERR! stack     at Object.self.commands.(anonymous function) [as configure] (/usr/share/node-gyp/lib/node-gyp.js:66:37)
gyp ERR! stack     at run (/usr/share/node-gyp/bin/node-gyp.js:72:30)
gyp ERR! stack     at process._tickCallback (node.js:419:13)
gyp ERR! System Linux 3.16.0-4-amd64
gyp ERR! command "nodejs" "/usr/bin/node-gyp" "rebuild"

/usr/lib/nodejs/graceful-fs/polyfills.js:8
    cwd = origCwd.call(process)
                  ^
Error: ENOENT, no such file or directory
    at process.cwd (/usr/lib/nodejs/graceful-fs/polyfills.js:8:19)
    at errorMessage (/usr/share/node-gyp/bin/node-gyp.js:119:28)
    at issueMessage (/usr/share/node-gyp/bin/node-gyp.js:125:3)
    at process.<anonymous> (/usr/share/node-gyp/bin/node-gyp.js:109:3)
    at process.emit (events.js:95:17)
    at process._fatalException (node.js:272:26)
npm ERR! ref@1.3.2 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the ref@1.3.2 install script.
npm ERR! This is most likely a problem with the ref package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get their info via:
npm ERR!     npm owner ls ref
npm ERR! There is likely additional logging output above.
npm ERR! System Linux 3.16.0-4-amd64
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "-g" "aa-recorder"
npm ERR! cwd /home/user/aa-recorder-master
npm ERR! node -v v0.10.29
npm ERR! npm -v 1.4.21
npm ERR! code ELIFECYCLE
npm WARN This failure might be due to the use of legacy binary "node"
npm WARN For further explanations, please read
/usr/share/doc/nodejs/README.Debian

npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /home/user/aa-recorder-master/npm-debug.log
npm ERR! not ok code 0

7. Решил запустить вручную скрипт, скопировал файл config.json из папки examples в папку bin, назвал его «yourConfig.json» и отредактировал в нем rtsp-url и создал папку «/srv/video-storage» (как я понял в нее должны складываться mp4 файлы). Зашел в папку bin и запустил скрипт таким образом как это написано тут, только добавил два символа "./" (иначе ничего не выдается):

./aa-recorder yourConfig.json

в ответ мне снова было выдано кучу ошибок:

root@oper4:/home/user/aa-recorder-master/bin# ./aa-recorder yourConfig.json

module.js:340
    throw err;
          ^
Error: Cannot find module 'filesize-parser'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/home/user/aa-recorder-master/bin/aa-recorder:7:24)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

Очень прошу. Помогите разобраться что я не так делаю или что нужно делать, чтобы этот скрипт заработал.

pospelov
() автор топика
Ответ на: комментарий от pospelov

что я не так делаю

Ты пытаешься использовать софт от веб-обезьян, которые на своем недоязыке пытаются писать системный софт. Запомни: JS где-то вне браузера - верный признак говна, а уж ставить вебсервер для записи видео - это вообще за гранью нормального

ruzisufaka
()
Ответ на: комментарий от pospelov

У вас достаточно четкие требования, но при этом несколько специфичное. Если вы придумали эти требования - придумывайте и софт для них. Написание скриптов - это совсем небольшая проблема. Хотя я бы лично написал сегментер на сишке. Я даже подкажу - в ffmpeg уже есть сегментер, вам нужно просто следить за новыми файликами и рассовывать по той структуре директорий, что вы себе напридумывали, это совсем несложный скрипт.

ruzisufaka
()

мой рабочий быстроскрипт (первая редакция)

cat bin/captute_cam_stream.sh 
#!/bin/sh

LANG=C
PATH=/bin:/usr/bin:/usr/lib/nagios/plugins

if [ $# -lt 1 ]; then
	echo "Usage: $0 <cam number>"
	exit 1
fi

CAMNUM="$1"
if [ "$CAMNUM" -eq 1 ]; then
	IP='10.0.0.202'
elif [ "$CAMNUM" -eq 2 ]; then
	IP='10.0.0.201'
else
	echo "Unknown cam number: \"$CAMNUM\""
	exit 1
fi

while :; do
	if check_ping -H "$IP" -w 10,25% -c 20,50% -t 10 >/dev/null 2>/dev/null; then
		# 2016-02-29
		DATE=$(date '+%F')
		START=$(date '+h-m-s_%H-%M-%S')

		mkdir -p /Cams/cam0$CAMNUM/$DATE

		ffmpeg -i "rtsp://$IP/user=admin&password=$BLAHBLAHBLAH" -r 30 -vcodec copy -an -t 300 "/Cams/cam0$CAMNUM/$DATE/${START}.mp4" </dev/null >/dev/null 2>/dev/null
	else
		echo "No ping to camera \"$IP\""
		sleep 60
	fi
done
futurama ★★★★★
()
Ответ на: комментарий от futurama

спасибо! буду разбираться как он работает...

pospelov
() автор топика
7 ноября 2017 г.
Ответ на: комментарий от futurama

Удалось решить проблему?

День добрый! Возникла такая же задача. Хотелось бы узнать, получилось ли у автора решить эту задачку?

Podpolschik
()
Ответ на: комментарий от futurama

Спасибо за ответ! Это именно с таким кодом работает, как тут выше ты написал? Если за, могу я его использовать (для личного пользования) ? ffmpeg + linux (кстати, какой дистрибутив посоветуешь для этих задач) будет достаточно? Заранее благодарю.

P.S. Я в линукс/unixe не знаток, прошу извинить за примитивные вопросы, если что.. :)

Podpolschik
()
Ответ на: комментарий от Podpolschik

тебе потребуется адаптация под свои камеры, адреса, директории хранения

P. S. без знаний будет тяжело

futurama ★★★★★
()
Ответ на: комментарий от futurama

С адаптацией проблем нет (адреса камеры известны,rtsp-поток, директории). Т.е., эта версия и является окончательной и стабильно рабочей, или же добавились какие-то дополнительные «плюшечки»?

Podpolschik
()
Ответ на: комментарий от Podpolschik

вот что у меня сейчас работает

#!/bin/sh
LANG=C
PATH=/bin:/usr/bin:/usr/lib/nagios/plugins

if [ $# -lt 1 ]; then
        echo "Usage: $0 <cam number [1|2|3]>"
        exit 1
fi
CAMNUM="$1"
if   [ "$CAMNUM" -eq 1 ]; then
        IP='10.0.0.202'
elif [ "$CAMNUM" -eq 2 ]; then
        IP='10.0.0.201'
elif [ "$CAMNUM" -eq 3 ]; then
        IP='10.0.0.203'
else
        echo "Unknown cam number: \"$CAMNUM\""
        exit 1
fi

echo "Start on cam N${CAMNUM}, IP=$IP"
while :; do
        if check_ping -H "$IP" -w 10,25% -c 20,50% -t 10 >/dev/null 2>/dev/null; then
                # 2016-07-29
                 DATE=$(date '+%F')
                START=$(date '+%H-%M-%S')

                mkdir -p /Cams/cam0$CAMNUM/$DATE

                timeout -k 5 305 ffmpeg -rtsp_transport tcp -i 'rtsp://'"$IP"'/user=admin&password=&channel=1&stream=0' -r 30 -vcodec copy -an -t 300 "/Cams/cam0$CAMNUM/$DATE/hms_${START}.mp4" </dev/null >/dev/null 2>/dev/null
                sleep 1
        else
                echo "$DATE $START : No ping to camera N${CAMNUM}, \"${IP}\""
                sleep 60
        fi
done

$ df -h /Cams/
Filesystem             Size  Used Avail Use% Mounted on
/dev/mapper/vg2-cam01  2.0T  1.8T  205G  91% /Cams

$ ls /Cams/
cam01  cam02  cam03

$ ls /Cams/cam02
2017-10-26  2017-10-28  2017-10-30  2017-11-01  2017-11-03  2017-11-05  2017-11-07
2017-10-27  2017-10-29  2017-10-31  2017-11-02  2017-11-04  2017-11-06  2017-11-08

$ crontab -l | grep capture
10   0 * * * /home/user/bin/remove_old_capture.sh

$ cat /home/user/bin/remove_old_capture.sh

#!/bin/sh

BASEDIR='/Cams'

set -e
exec  >> /var/tmp/remove_old_capture.log
exec 2>> /var/tmp/remove_old_capture.err
while :; do
/usr/lib/nagios/plugins/check_disk -w 5% -c 3% "$BASEDIR" && exit 0
        for d1 in $BASEDIR/cam*; do
                d2=`ls -1tr "$d1" | head -1`
                if [ -d "$d1/$d2" ]; then
                        rm -rf "$d1/$d2"
                fi
        done
done
exit 0

futurama ★★★★★
()
Последнее исправление: futurama (всего исправлений: 2)
Ответ на: комментарий от futurama

Премного благодарен. Вижу, что тут несколько камер, как раз намеревался несколько камер и подключить. Огромное спасибо и успехов!

Podpolschik
()
Ответ на: комментарий от Podpolschik

Скрипт надо запускать столько раз сколько камер, естественно. У меня он в screen'e

$ screen -c cams

$ cat cams

screen -t cam01 /home/user/bin/captute_cam_stream.sh 1
screen -t cam02 /home/user/bin/captute_cam_stream.sh 2
screen -t cam03 /home/user/bin/captute_cam_stream.sh 3
futurama ★★★★★
()
Ответ на: комментарий от futurama

Реализация скрипта на Raspberry Pi или Orange Pi?

Возможна ли реализация скрипта на Raspberry Pi или Orange Pi? В качестве памяти поставить флэшку на 32/64 Гб, линукс. Поставить это все в корпус, он же будет подставкой для одной из камер. Или я не учёл какой-то важной детали в этой сборке? Благодарю за советы.

Podpolschik
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.