mirror of https://github.com/OpenIPC/python-dvr
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.2 KiB
121 lines
3.2 KiB
#! /usr/bin/python3
|
|
from dvrip import DVRIPCam, SomethingIsWrongWithCamera
|
|
from signal import signal, SIGINT, SIGTERM
|
|
from sys import argv, stdout, exit
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from time import sleep, time
|
|
import logging
|
|
|
|
baseDir = argv[3]
|
|
retryIn = 5
|
|
rebootWait = 10
|
|
camIp = argv[1]
|
|
camName = argv[2]
|
|
cam = None
|
|
isShuttingDown = False
|
|
chunkSize = 600 # new file every 10 minutes
|
|
logFile = baseDir + '/' + camName + '/log.log'
|
|
|
|
def log(str):
|
|
logging.info(str)
|
|
|
|
def mkpath():
|
|
path = baseDir + '/' + camName + "/" + datetime.today().strftime('%Y/%m/%d/%H.%M.%S')
|
|
Path(path).parent.mkdir(parents=True, exist_ok=True)
|
|
return path
|
|
|
|
def shutDown():
|
|
global isShuttingDown
|
|
isShuttingDown = True
|
|
log('Shutting down...')
|
|
try:
|
|
cam.stop_monitor()
|
|
close()
|
|
except (RuntimeError, TypeError, NameError, Exception):
|
|
pass
|
|
log('done')
|
|
exit(0)
|
|
|
|
def handler(signum, b):
|
|
log('Signal ' + str(signum) + ' received')
|
|
shutDown()
|
|
|
|
signal(SIGINT, handler)
|
|
signal(SIGTERM, handler)
|
|
|
|
def close():
|
|
cam.close()
|
|
|
|
def theActualJob():
|
|
|
|
prevtime = 0
|
|
video = None
|
|
audio = None
|
|
|
|
def receiver(frame, meta, user):
|
|
nonlocal prevtime, video, audio
|
|
if frame is None:
|
|
log('Empty frame')
|
|
else:
|
|
tn = time()
|
|
if tn - prevtime >= chunkSize:
|
|
if video != None:
|
|
video.close()
|
|
audio.close()
|
|
prevtime = tn
|
|
path = mkpath()
|
|
log('Starting files: ' + path)
|
|
video = open(path + '.video', "wb")
|
|
audio = open(path + '.audio', "wb")
|
|
if 'type' in meta and meta["type"] == "g711a": audio.write(frame)
|
|
elif 'frame' in meta: video.write(frame)
|
|
|
|
log('Starting to grab streams...')
|
|
cam.start_monitor(receiver)
|
|
|
|
def syncTime():
|
|
log('Synching time...')
|
|
cam.set_time()
|
|
log('done')
|
|
|
|
def jobWrapper():
|
|
global cam
|
|
log('Logging in to camera ' + camIp + '...')
|
|
cam = DVRIPCam(camIp)
|
|
if cam.login():
|
|
log('done')
|
|
else:
|
|
raise SomethingIsWrongWithCamera('Cannot login')
|
|
syncTime()
|
|
theActualJob()
|
|
|
|
def theJob():
|
|
while True:
|
|
try:
|
|
jobWrapper()
|
|
except (TypeError, ValueError) as err:
|
|
if isShuttingDown:
|
|
exit(0)
|
|
else:
|
|
try:
|
|
log('Error. Attempting to reboot camera...')
|
|
cam.reboot()
|
|
log('Waiting for ' + str(rebootWait) + 's for reboot...')
|
|
sleep(rebootWait)
|
|
except (UnicodeDecodeError, ValueError, TypeError):
|
|
raise SomethingIsWrongWithCamera('Failed to reboot')
|
|
|
|
def main():
|
|
Path(logFile).parent.mkdir(parents=True, exist_ok=True)
|
|
logging.basicConfig(filename=logFile, level=logging.INFO, format='[%(asctime)s] %(message)s')
|
|
while True:
|
|
try:
|
|
theJob()
|
|
except SomethingIsWrongWithCamera as err:
|
|
close()
|
|
log(str(err) + '. Waiting for ' + str(retryIn) + ' seconds before trying again...')
|
|
sleep(retryIn)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|