#python #opencv #rtp
#python #opencv #rtp
Вопрос:
Доброе утро / день / вечер,
Я изучаю, как использовать OpenCV в Python, но я сталкиваюсь с некоторыми проблемами, и я считаю, что мне не хватает какой-то части головоломки.
Настройка
IP-камера (Bosh FLEXIDOME IP micro 5000) и мой ноутбук, подключенный к коммутатору PoE, подключены к моему основному маршрутизатору.
Чего я пытаюсь достичь
Мне нужно записывать видео фиксированной длины с камеры (используя RSTP). Например, запишите 30-секундное видео, сохраните его, начните снова. Я использую VP80, потому что он бесплатен.
Проблема
Я жестко кодирую fps в соответствии со спецификациями камеры. В нем говорится, что он может записывать со скоростью 25 кадров в секунду, поэтому я выбрал это число. Я хочу видео продолжительностью 30 секунд.
Я пробовал два подхода, но основная проблема заключается в том, что цикл захвата кадров python не может работать так быстро, как необходимо, до 25 кадров в секунду.
Подход 1
Я вычисляю количество кадров, которые мне нужно захватить, чтобы получить видео продолжительностью 30 секунд. frames_per_seconds = fps * clip_duration_in_seconds
Я зацикливаюсь и захватываю кадры, пока не наберу необходимое количество кадров, и сохраняю видео.
Это дает мне 30 секунд видео (приятно!) за несколько минут (?)
import cv2
import os
import time
from datetime import datetime
import sys
cap = cv2.VideoCapture('rtsp://192.168.178.157:554/?fmt=3')
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = 25
size = (width, height)
clip_duration_in_seconds = 5
frames_per_video = clip_duration_in_seconds * fps
if (cap.isOpened()== False):
raise("Error opening video stream or file")
while(True):
start = datetime.now().strftime("%d-%m-%Y_%H.%M.%S")
output_file = f"Output_{start}.mkv"
out = cv2.VideoWriter(
output_file, cv2.VideoWriter_fourcc(*'VP80'), fps,
size)
frame_count = 0
while(cap.isOpened() and frame_count < frames_per_video):
ret, frame = cap.read()
if ret == True:
out.write(frame)
frame_count = frame_count 1
else:
raise("Broken stream")
out.release()
Подход 2
С помощью time.time()
я проверяю, что прошло 30 секунд. Результатом является промежуток времени 1-3 секунды. Код такой же, как и раньше, но вместо проверки frame_count < frames_per_video
я проверяю время.
Вопрос
Я думаю, я мог бы снизить частоту кадров, но это всегда будет отличаться, так как я могу динамически выбирать частоту кадров? Или как я могу изменить реализацию, чтобы перехватить все кадры?
Или я что-то упускаю? Конечная цель — иметь 30-секундные видеоролики, представляющие 30 секунд реального времени.
Спасибо!
Ответ №1:
Предположение о том, что вы видите:
- VP8 слишком много для вашего компьютера, чтобы кодировать с такой частотой кадров и размером. используйте более простой кодек, возможно, MJPG.
- возможно, сетевая камера не выдает видео со скоростью 30 кадров в секунду
Получите значение CAP_PROP_POS_MSEC из вашей видеозаписи до / после каждого кадра и посмотрите, имеют ли значения смысл для вас.
Возможно, вам придется работать с временными метками презентации. Это обобщение «кадров в секунду» для видео, которое может иметь кадры в произвольное время. Некоторые камеры меняют частоту кадров, когда для них установлены различные «автоматические» настройки.
OpenCV не является медиа-библиотекой. Его функции чтения и записи видео — это просто удобство. Вам нужны более мощные API.
Рассмотрите возможность использования библиотеки ffmpeg. Это сложный API, я согласен, но это необходимая сложность. Проект «PyAV» правильно переносит ffmpeg в python. Любая другая оболочка python «ffmpeg» просто запускает подпроцесс, который не дает вам никакой информации о временных метках презентации.
Комментарии:
1. Спасибо, я изучу предложения, которые вы мне дали. Что касается PyAV / ffmpeg, основной проблемой является их лицензия. Для коммерческого продукта (например, того, над чем я работаю) он очень строгий, поэтому я не могу его использовать..
2. ffmpeg может использоваться в коммерческих целях: video.stackexchange.com/questions/14802 /…
3. OpenCV использует ffmpeg, поэтому, если вы считаете, что OpenCV безопасен для коммерческого использования (что правильно), это включает в себя все библиотеки, которые он использует. возможно, вам придется упаковать соответствующие лицензии в ваше приложение, чтобы соответствовать, может быть, больше, может быть, меньше.