предисловие
В связи с недавними проектными требованиями, связанными с контентом, связанным с компьютерным зрением, необходимо реализовать функцию записи видео на 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
Устранение неполадок
- ошибка кода
python录制视频是否成功
前端中video的src是否正确
- сетевой запрос
浏览器控制台是否报错
nginx服务是否启动
请求路径是否正确
是否跨域问题
- Поддержка браузера
Формат | 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+ | - |
- Видео кодек
Формат | кодирование видео | кодирование звука |
---|---|---|
Ogg | Theora | Vorbis |
MPEG 4 | H.264 | AAC |
WebM | VP8 | Vorbis |
выявить проблему
После исключения проблем с кодом и сетевыми запросами вы можете найти проблему в браузере. Я использую браузер Chrome, и проблема версии исключена, поэтому можно определить, что это проблема видеокодека. При записи видео в python, Кодек H.264 не используется. :
encode = cv2.VideoWriter_fourcc(*'mp4v')
Глядя на введение в видео, вы можете обнаружить, что видео действительно не является кодеком H.264, поэтому видео может нормально воспроизводиться в программном обеспечении для воспроизведения видео, но не может воспроизводиться в видео h5, как показано ниже:
попробуй сменить fourcc чтобы перезаписать видео
encode = cv2.VideoWriter_fourcc(*'X264')
Похоже, этот кодек QAQ не поддерживается.Похоже, требуется библиотека FFmpeg.Вводим в терминале под Ubuntu:
$sudo apt-get install ffmpeg x264 libx264-dev
После завершения установки запись не может быть записана в Ubuntu (видеофайлы не могут быть сгенерированы), но это не влияет на запись на моем собственном компьютере:
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, и я, возможно, продолжу попытки в будущем~