Recientemente, una tarea apareció diariamente para formar un lapso de tiempo con un par de cámaras de vigilancia conectadas a IPEYE. Si está interesado en cómo una persona con un mínimo conocimiento de Python se ocupó de esto, o si desea señalarme mis errores, bienvenido a ...
Introducción
Mi padre decidió mudarse y construir una casa en otra región. Me pidió que lo ayudara con la videovigilancia. Datos de entrada:
- No hay sala técnica.
- El equipo puede ser robado.
- Necesito una imagen de calidad.
- Las cámaras deben estar al aire libre.
- Todo lo que necesitas es 2 cámaras.
- Realmente quiero cámaras PTZ con zoom.
- Me gustaría una aplicación móvil.
Mirando los precios en las tiendas de equipos de marca, se decidió comprar cámaras PoE no nominales con todos los bollos en Ali. Las cámaras eran lo suficientemente baratas, alrededor de 5 mil cada una.
No quería colocar el DVR en un sitio de construcción, por lo que se decidió utilizar una solución en la nube. Después de que llegaron las cámaras, intenté hacer amigos con diferentes servicios para que todo funcionara, incluido PTZ. De todos los servicios que probé, resultó hacer amigos de las cámaras chinas solo con IPEYE.
Esto terminará la introducción. Creo que ahora será claro para todos por qué la conversación será sobre este servicio.
Experiencia con IPEYE
Servicio como servicio. Todo lo prometido se cumple. El soporte técnico responde preguntas. El punto clave es que puede especificar un enlace a la secuencia rstp, cambiar la configuración de PTZ y todo funcionará. La aplicación móvil de Android funciona. Es posible crear usuarios invitados para sus cámaras y otorgar derechos de acceso a cada pariente. La interfaz web en Vivaldi a veces tiene errores; en Chrome, tales fallas son menos comunes. Un poco aburrido navegar por el archivo.
El archivo de la cámara se puede descargar, pero por hasta 3 horas. El procedimiento lleva bastante tiempo.
Todo parece estar bien, pero sientes con tu alma que algo no está bien. Y no hay suficiente profundidad de archivo. Puede aumentar la profundidad, pero la opción más cara: 12 meses costará 25 mil rublos al año para una cámara (cuando se graba por detección).
Vamos a inventar algo?
Esa es la pregunta que me hizo mi padre. Mi padre quería capturar todas las etapas de la construcción.
¿Cuáles son las opciones para resolver este problema? Puede ir a la interfaz web a diario y exportar varios videos de cada cámara. ¿Quién realizará una tarea tan triste? Nadie! ¿Varias veces al día para abrir cámaras de transmisión y tomar capturas de pantalla? Bueno, también locura. ¿Aumentar la profundidad del archivo a 1 año? Bueno, una solución muy barata. Google me dijo que la función TimeLapse ya está integrada en este servicio, pero la resolución es baja y no puede descargarla para el archivo futuro :(
UPD: se puede descargar el timelapse original. Para hacer esto, abra el lapso de tiempo en la interfaz web. Usando herramientas de desarrollador, inspeccione la página web y encuentre un enlace a nuestro archivo. Formato de enlace:
sr <número_servidor> .ipeye.ru / api / v1 / stream / <uuid> / nvr / timelapse / 0 / <unixtimestamp> /100/video.mjpeg
Se decidió escribir algo para guardar capturas de pantalla de la cámara y formar el video final.
Descargo de responsabilidad
El autor de esta obra no es un programador y no busca convertirse en uno. OOP conoce los conceptos básicos superficialmente. Ágil, etc. No estudiado. Hace un mes, vio un breve curso en video sobre python y decidió usarlo para resolver el problema actual.
API
Fue muy agradable descubrir que el servicio IPEYE es una
API disponible públicamente. La API proporciona ejemplos solo para PHP, pero ha demostrado ser útil.
Basado en el hecho de que mi computadora nunca se apaga, se desarrolló el siguiente concepto:
- El Programador de Windows ejecuta un script cada 30 minutos.
- El script a través de la API determina el uuid de mis cámaras.
- El script a través de la API recibe la foto de las cámaras y la guarda en un directorio.
- El guión una vez al día genera un archivo de video para cada cámara.
- El catálogo con fotos de origen y videos finales está vinculado a la nube y compartido.
- Familiares cuando quieren ver timelapse y operar en archivos como quieran.
Para trabajar con la API, escribí un par de funciones: registrar y ejecutar solicitudes al servidor API.
writeLog ()def writeLog(logdata): if LogEnable == 1: log_time = datetime.now() log_time = log_time.isoformat(timespec='seconds') log_file = open(log_file_path, "a+") log_file.write(log_time + ": " + str(logdata) + "\n") log_file.close else: return True
getApiResponse () def getApiResponse(method, api_uri): if method == "GET": try: r = requests.get(api_url + api_uri, timeout = api_timeout) r.raise_for_status()
De acuerdo con la API, tenemos la capacidad de acceder / dispositivos / todo y obtener información sobre todos los hilos. Me confundió de inmediato que no se requiere autorización, si cree en la documentación de la API ... Cuando solicité / devices / all, recibí un error:
Error fatal: 401 Error del cliente: No autorizado para url: api.ipeye.ru : 8111 / devices / all
Modifiqué mi función getApiResponse para pasar mis credenciales, pero también obtuve un error 401. No enumero la función, porque no fue útil en el futuro.
Tuve que contactar al soporte técnico sobre esto. El equipo de soporte explicó que para usar la API con autorización, primero debe concluir un acuerdo con IPEYE y configurar su servidor web. Qué tipo de servidor web y por qué no me explicaron, pero al mismo tiempo me dieron una pista de dónde conseguir cámaras uuid y acceder a la API sin autorización.
Correspondencia con apoyoYo: buenas tardes. ¿Es posible usar la API? No encontré cámaras uuid en la interfaz web. Quería obtener una lista de mis cámaras cuando le pregunté a api.ipeye.ru : 8111 / devices / all pero mi enlace de nombre de usuario / contraseña no funcionaba.
IPEYE: como nombre de usuario / contraseña, se utilizan los datos de autorización del usuario de la API, proporcionamos acceso de forma contractual.
En consecuencia, la lista de cámaras que verá no será para su inicio de sesión, sino para todas las cámaras de la API del usuario.
Yo: ¿Cuánto cuesta obtener acceso a la API de dos cámaras?
IPEYE: Todo es más complicado allí, deberá iniciar su sitio y usar nuestra API para agregar cámaras y continuar trabajando con ellos.
¿Vale la pena hacerlo por el bien de 2 cámaras?
Yo: en general, para comprenderlo, necesito acceso a la API solo para descargar automáticamente capturas de pantalla de las cámaras. Para la posterior formación de lapso de tiempo.
IPEYE: ¿Y qué no api.ipeye.ru/doc#AppDeviceJPEGOnline no se adapta en este caso?
Yo: ¿Y dónde puedo encontrar los UUID de mis cámaras?
IPEYE: desde la barra de direcciones del navegador, por ejemplo. El mismo UUID aparece en el "Código para el sitio" como el parámetro devcode.
¿Qué tenemos en el residuo seco? De hecho, las cámaras uuid se pueden encontrar en su cuenta, si observa los parámetros GET. Hay un método / dispositivo / jpeg / online /: uuid /: name para tomar una captura de pantalla, hay uuid y ya sabíamos el nombre de la cámara.
Creo una función para guardar imágenes de una secuencia.
saveJpegFromStream () def saveJpegFromStream(uuid, name):
Hago una solicitud y entiendo que algo no está bien ... Recibimos el archivo. La imagen es de mi cámara, pero el tamaño es sospechosamente pequeño: 66Kb. Miro las propiedades y entiendo que 608 * 342 no es en absoluto 1920 * 1080. Cuando solicito / device / thumb / online / uuid / 1920 / name, obtengo el archivo 1920 * 1080, pero este es solo el archivo anterior 608 * 342 ampliado a la escala requerida. Por supuesto, este estado de cosas no me convenía.
También durante los experimentos, se descubre que el parámetro de nombre no se verifica ni se usa de ninguna manera. Puedes enviar lo que quieras.
Después de eso, concluí que el comando / dispositivo / url / rtsp / más útil es obtener un enlace a la transmisión RTSP. Tuve que recurrir a Google porque No se entendía cómo trabajar con RTSP.
getStreamRTSP () def getStreamRTSP(uuid, name): api_uri = "/device/url/rtsp/" + uuid writeLog("Trying get stream RTSP link for " + name + " " + uuid) response = json.loads(getApiResponse("GET", api_uri).text) writeLog("Stream RTSP link for " + name + ": " + str(response["message"])) return str(response["message"])
saveJpegFromRTSP def saveJpegFromRTSP(name, rtspLink): writeLog("Trying save RTSP screenshot for camera: " + name) rtspClient = cv2.VideoCapture(rtspLink) if rtspClient.isOpened(): _,frame = rtspClient.read() rtspClient.release()
Después de escribir un par de funciones arriba, me di cuenta de que no había necesidad de usar la API para la tarea inicial :) Tengo un enlace directo al flujo rtsp de la cámara, y con la última función puedo capturar la imagen de la cámara. Pero no comencé a cambiar el concepto en este paso.
Al trabajar a través de la API, hay 2 ventajas: el servidor IPEYE inicializa la transmisión mucho más rápido que la cámara, y la transmisión de la cámara rtsp puede cerrarse mediante un firewall.
jpg2mp4
El último paso es agregar todas las imágenes de una cámara al video. Elegí el códec mp4v, porque MEGA le permite reproducir estos archivos de video en una interfaz web.
makeVideoFile () def makeVideoFile(name): height = 1080 width = 1920
Como referencia: 45 archivos jpg con un volumen total de 37.3 MB en formato de video ocupan 16.9 MB.
Gracias por leer mi primer artículo público. Traté de describir todo en el formato de la historia, y no es fácil de hacer, porque no quería obtener un artículo seco al salir.
Estaré encantado de comentar, porque conocí a Python hace menos de un mes.
El guión completo con comentarios extendidos se puede encontrar en
github . Además, la secuencia de comandos tiene en cuenta la diferencia en las zonas horarias, y todas las funciones restantes se escriben para escalar rápidamente a un número diferente de cámaras.