Python-OpenCV для записи видео MP4 в кодировке H264

OpenCV

предисловие

В связи с недавними проектными требованиями, связанными с контентом, связанным с компьютерным зрением, необходимо реализовать функцию записи видео на Python и функцию воспроизведения видео в интерфейсе браузера после завершения записи; эта статья является крупным планом для записи всего процесса реализации.

2019-08-02 Обновление

Раньше я был занят другими вещами, и я не продолжал углубляться в изучение, и эта статья была временно отложена; но недавно было обнаружено, что предыдущая реализация (вызов FFmpeg для преобразования в mp4 с помощью Java после записи avi видео) повлияет на производительность системы, т.к. при вызове FFmpeg для конвертации видео CPU занимает высокий QAQ, поэтому продолжаю находить решение на основе предыдущего.

Уменьшить использование ЦП FFmpeg

Поскольку загрузка ЦП FFmpeg высока, мы сначала пытаемся уменьшить загрузку ЦП.Ищем и обнаруживаем, что его можно добавить в команду FFmpeg.-threadsпараметр для указания использования ЦП

Тест конвертации FFmpeg

В этом тесте используется тот же видеофайл avi размером 113

1. Исходная команда преобразования
ffmpeg -i test.avi -vcodec libx264 -f mp4 test.mp4
# 转换用时 30s~31s
# CPU占用 950%~1000%
2. Добавить-threads 6параметр
ffmpeg -i test.avi -threads 6 -vcodec libx264 -f mp4 test.mp4
# 转换用时 45s~46s
# CPU 占用490%~550%
3. Добавить-threads 2параметр
ffmpeg -i test.avi -threads 2 -vcodec libx264 -f mp4 test.mp4
# 转换用时 87s~88s
# CPU占用 205%~230%

Видно, что добавление-threadsПосле параметров загрузка процессора действительно снижается, но соответствующее время преобразования видео также увеличивается.Очевидно, что это не тот эффект, который нам нужен, поэтому проблема записи видео H264 по-прежнему неизбежна.

Скомпилируйте и установите OpenCV для записи видео

Раньше мне не удавалось записывать видео в формате MP4 с кодировкой H264, потому что используется opencv-python, установленный для pip.Эта библиотека поставляется с FFmpeg, поэтому, как бы мы ни кидали системный FFmpeg, это не будет иметь никакого эффекта; если мы хотим вызвать системный FFmpeg FFmpeg необходимо вручную скомпилировать и установить OpenCV. Конкретные причины могут относиться к следующему рисунку:

Как скомпилировать и установить OpenCV описывать особо не буду, это не тема данной статьи, но давайте поставим ссылку для ленивых онкобольных!Ubuntu16.04 install OpenCV with ffmpeg

После компиляции и установкиimport cv2Нормальное введение в код на удержании, оригинал и в интернете есть только смена фурсс.

На данный момент можно вызвать OpenCV в Python для записи видео в формате MP4 в кодировке H264, и студенты, у которых нет особых потребностей, могут посмотреть его здесь~ Сахуа!

Запись видео с помощью библиотеки vidgear

По причинам проекта мы не можем использовать OpenCV, скомпилированный вручную (WTF!!!), поэтому мы должны продолжать искать решения QAQ

официальная ссылка vidgar-github, Эта схема была отклонена от темы и была принята только по соображениям проекта, поэтому я не буду подробно описывать ее здесь.Заинтересованные студенты могут посмотреть.

Далее исходный текст


Видео записи Python-OpenCV

окрестности

python 3.7.1
opencv-python 3.4.4.19

Внедрить поддержку библиотек

import cv2

вызов камеры

Входные параметры, такие как "0", "1", "2" и другие цифры - это индекс камеры, 0 - встроенная камера, камера может вызываться последовательно, либо путь к видеофайлу может быть передан в

cap = cv2.VideoCapture(0)

Получить ширину и высоту камеры

width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)

После записи видео с использованием частоты кадров камеры в воспроизведении возникает ситуация перемотки вперед, которая временно записывается на смерть в VideoWriter Я не знаю, связано ли это с камерой, здесь нет глубокого пониманияfps = cap.get(cv2. CV_CAP_PROP_FPS)

Укажите видеокодек

Вам нужно передать четырехсимвольный кодек кодека fourcc (четырехсимвольный код):ссылка на 4cc

encode = cv2.VideoWriter_fourcc(*'mp4v')

Инициализировать VideoWriter

Ссылка на запись:официальная документация

out = cv2.VideoWriter( './test.mp4', encode, 10, (width, height), True)

Получить кадры изображения и записать в видеофайл

  • Цикл, чтобы получить однокадровое изображение с камеры/видео
  • Откройте новое окно, чтобы отобразить кадр изображения, воспроизводите следующий кадр каждые 25 миллисекунд, введите «q», чтобы выйти из цикла.
  • Запись кадров изображения в видеофайл
while True:
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break
    ret, frame = cap.read()
    cv2.imshow('test', frame)
    out.write(frame)

бесплатные ресурсы

  • релиз VideoWriter
  • отпустить камеру
  • закрыть окно
out.release()
cap.release()
cv2.destroyAllWindows()

полный код

Код здесь является демо, только для справки

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import cv2

# 调用摄像头
cap = cv2.VideoCapture(0)
# 获取摄像头宽高
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 获取摄像头帧率
#fps = cap.get(cv2.CAP_PROP_FPS)
# 指定fourcc编解码
encode = cv2.VideoWriter_fourcc(*'mp4v')
# 初始化VideoWriter
out = cv2.VideoWriter('./test.mp4', encode, 10, (width, height), True)
while True:
    # 每隔25毫秒播放下一帧,若键入“q”跳出循环
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break
    # 从摄像头获取下一帧
    ret, frame = cap.read()
    # 新开窗口展示图像
    cv2.imshow('test', frame)
    # 将当前帧写入视频文件
    out.write(frame)
# 释放VideoWriter
out.release()
# 释放摄像头
cap.release()
# 关闭窗口
cv2.destroyAllWindows()

Воспроизвести видео в браузере

окрестности

macOS Mojave 10.14.3
Ubuntu 16.04
vue 2.9.6
nginx 1.15.5
Передняя часть представляет собой проект vue, который упакован и развернут в nginx, а блок сервера/блок местоположения настроен для предоставления доступа к статическим ресурсам, таким как изображения/видео.

Видео не может воспроизводить видео в h5

Устранение неполадок
  1. ошибка кода
    • python录制视频是否成功
    • 前端中video的src是否正确
  2. сетевой запрос
    • 浏览器控制台是否报错
    • nginx服务是否启动
    • 请求路径是否正确
    • 是否跨域问题
  3. Поддержка браузера
Формат IE Firefox Opera Chrome Safari
Ogg - 3.5+ 10.5+ 5.0+ -
MPEG 4 9.0+ - - 5.0+ 3.0+
WebM - 4.0+ 10.6+ 6.0+ -
  1. Видео кодек
Формат кодирование видео кодирование звука
Ogg Theora Vorbis
MPEG 4 H.264 AAC
WebM VP8 Vorbis

выявить проблему

После исключения проблем с кодом и сетевыми запросами вы можете найти проблему в браузере. Я использую браузер Chrome, и проблема версии исключена, поэтому можно определить, что это проблема видеокодека. При записи видео в python, Кодек H.264 не используется. :

encode = cv2.VideoWriter_fourcc(*'mp4v')

Глядя на введение в видео, вы можете обнаружить, что видео действительно не является кодеком H.264, поэтому видео может нормально воспроизводиться в программном обеспечении для воспроизведения видео, но не может воспроизводиться в видео h5, как показано ниже:

视频编解码-MP4V.jpg

попробуй сменить fourcc чтобы перезаписать видео

encode = cv2.VideoWriter_fourcc(*'X264')

报错信息.jpg
Похоже, этот кодек QAQ не поддерживается.Похоже, требуется библиотека FFmpeg.Вводим в терминале под Ubuntu:

$sudo apt-get install ffmpeg x264 libx264-dev

После завершения установки запись не может быть записана в Ubuntu (видеофайлы не могут быть сгенерированы), но это не влияет на запись на моем собственном компьютере:

视频编解码-X264.jpg

Java использует FFmpeg для конвертации видео

Поскольку в настоящее время невозможно записывать видео MP4 с кодеком H.264, мы используем окольную тактику: после записи видео в формате .avi на python внешний интерфейс запрашивает фон и использует FFmpeg в java для преобразования формата .avi. видео в формат .mp4 видео

Сначала установите FFmpeg (я не устанавливал его под Ubuntu, кажется, он идет в комплекте?)macOS установить FFmpeg Убунту установить FFmpegJava не будет здесь вдаваться в подробности, просто перейдите к коду~ (также для демонстрационной демонстрации, только для справки)

    // FFmpeg转换命令
    String transferCommand = "ffmpeg -i filePath/fileName.avi -vcodec libx264 -f mp4 filePath/fileName.mp4";
    Process process = Runtime.getRuntime().exec("/bin/bash");
    printWriter = new PrintWriter(new BufferedWriter(new 
    OutputStreamWriter(process.getOutputStream())), true);
    printWriter.println(transferCommand);
    // 这个命令必须执行,否则in流不结束。
    printWriter.println("exit");
    printWriter.close();
    process.waitFor();

Процесс преобразования занимает некоторое время.Решение состоит в том, чтобы запустить поток для завершения преобразования видео, не влияя на время отклика текущего интерфейса, и завершить преобразование видео без восприятия пользователем.

Суммировать

Вышеупомянутое содержимое представляет собой запись этого процесса реализации. Код представляет собой демонстрационную демонстрацию, а не код практического приложения. При необходимости его можно скорректировать в соответствии с фактическими потребностями. Из-за нехватки времени мне не удалось приложить много усилий для записи видео в формате H.264, и я, возможно, продолжу попытки в будущем~

Если у вас есть какие-либо вопросы или вы столкнулись с подобными потребностями, пожалуйста, оставьте сообщение или личное сообщение мне~
Если вы можете записать видео в формате .264 или у вас есть лучшее решение, дайте мне знать~

Ссылка на ссылку

видео не может воспроизвести mp4 проблема

что такое кодек для видео mp4 в python OpenCV

FFmpeg ограничивает использование ЦП

opencv-python-issues

vidgear-github