Вопрос или проблема
Я пробовал комбинацию:
- v4l2loopback
- ffmpeg
- mpv
Но либо видео с веб-камеры, либо запись веб-камеры работает, но никогда не работает оба одновременно.
Может кто-нибудь предоставить скрипт, который этого добьется?
Вот что я попробовал до сих пор:
#!/usr/bin/env bash
set -x
# Это требует установки модуля видеопетли.
# sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="VirtualCam" exclusive_caps=1
# используйте `pw-cli list-objects | grep node.name`, чтобы получить аудиоустройство
AUDIO_DEVICE="alsa_input.pci-0000_00_1f.3.analog-stereo"
VIDEO_DEVICE="/dev/video0"
VIRTUAL_VIDEO_DEVICE="/dev/video10"
read -p "Введите имя для видео: " VIDEO_NAME
if [ -z "$VIDEO_NAME" ]; then
VIDEO_NAME="unnamed_video"
fi
OUTPUT_FILE="$HOME/videos/${VIDEO_NAME}_$(date +%Y%m%d_%H%M%S).mkv"
trap 'echo "Остановка записи..."; pkill -P $$; exit 0' SIGINT
ffmpeg -f v4l2 -framerate 30 -video_size 640x480 -i "$VIDEO_DEVICE" \
-f v4l2 -video_size 640x480 -i "$VIRTUAL_VIDEO_DEVICE" &
sleep 2
# Начать отображение потока виртуальной веб-камеры с mpv
mpv --no-osc \
--no-input-default-bindings \
--profile=low-latency \
--geometry=50%:50% \
--autofit=100% \
--input-conf=/dev/null \
--title="WebcamDisplay" \
--framedrop=no \
--vf=scale=640:-1 \
--vo=vaapi \
"$VIRTUAL_VIDEO_DEVICE" &
# Начать запись с виртуального устройства с помощью ffmpeg
ffmpeg -f v4l2 -framerate 30 -video_size 640x480 -i "$VIRTUAL_VIDEO_DEVICE" \
-f pulse -i "$AUDIO_DEVICE" \
-c:v libx264 -preset ultrafast -crf 28 -pix_fmt yuv420p \
-c:a aac -b:a 192k -ar 48000 \
"$OUTPUT_FILE"
# Остановить все процессы после завершения
pkill ffmpeg
pkill mpv
Вот моя установка петли:
$ v4l2-ctl --list-devices
VirtualCam (platform:v4l2loopback-010):
/dev/video10
Integrated_Webcam_HD: Integrate (usb-0000:00:14.0-12):
/dev/video0
/dev/video1
/dev/media0
Вы на 90% на правильном пути. Вместо того чтобы пытаться считывать одно и то же устройство камеры (виртуальное или нет), просто добавьте другой вывод к вашему первому вызову ffmpeg
.
Опции ffmpeg обычно имеют следующий формат:
ffmpeg {общие и входные опции} {опции для первого вывода} спецификация первого вывода {опции для второго вывода} спецификация второго вывода
ffmpeg -f v4l2 -i /dev/video0 -f v4l2 /dev/video10 -c:v libx264 out.mkv
# | входные опции+спецификация | | вывод 1: нет -i !! | | вывод 2 |
Вы также можете включить свой аудиопоток в тот же момент; вот где -map
в ffmpeg оказывается полезным: вы можете сопоставлять различные входные и выходные назначения.
Как указал @marcus-müller (https://unix.stackexchange.com/a/783282/663280), вы можете использовать ffmpeg, чтобы записывать выходной файл и поток к устройству петли. Измените первый вызов ffmpeg, чтобы он выглядел (похоже) так:
ffmpeg -f v4l2 -r 30 -video_size 640x480 -input_format mjpeg -i "$VIDEO_DEVICE" \
-f pulse -i "$AUDIO_DEVICE" \
-c:v copy -f v4l2 "$VIRTUAL_VIDEO_DEVICE" \
-c:v libx264 -preset ultrafast -crf 28 -pix_fmt yuv420p \
-c:a aac -b:a 192k -ar 48000 \
"$OUTPUT_FILE" &
Относительно вашего оригинального вызова у нас есть:
- Добавлена
-input_format mjpeg
в первую строку, так как это то, что большинство (USB) веб-камер будут использовать для более высокого разрешения и более высокой частоты кадров (если используется что-то другое, например H264, конечно, укажите это здесь). - Вставлен
-f pulse -i "$AUDIO_DEVICE"
после первой строки, чтобы подключить аудиоход. - Выбрали ‘пропускать’ видео на устройство петли с помощью
-c:v copy
перед устройством (outfile). - Вставлены строки для вывода на диск из вашего оригинального второго вызова к ffmpeg.
- Примечание: используется кодек, установленный на H264 для вывода на диск через
-c:v
опцию перед именем файла (outfile).
- Примечание: используется кодек, установленный на H264 для вывода на диск через
Также нужно помочь mpv понять устройство петли. Я нашел следующий ресурс: https://github-wiki-see.page/m/mpv-player/mpv/wiki/Video4Linux2-Input.
Мы можем легко изменить ваш вызов mpv, чтобы получить правильный результат:
# Начать отображение потока виртуальной веб-камеры с mpv
mpv --no-osc \
--no-input-default-bindings \
--profile=low-latency \
--untimed \
--geometry=50%:50% \
--autofit=100% \
--input-conf=/dev/null \
--title="WebcamDisplay" \
--framedrop=no \
--vf=scale=640:-1 \
--vo=vaapi \
"av://v4l2:$VIRTUAL_VIDEO_DEVICE"
По сравнению с вашим оригинальным вызовом:
- Мы добавили
--untimed
– что может быть полезно для потоков MJPEG (см.man mpv
). - Мы изменили имя файла, чтобы включить префикс
av://v4l2:
(опять же, большинство деталей доступно вman mpv
). - Теперь его больше не нужно отделять с помощью
&
.
Второй вызов ffmpeg должен быть удален.
В общем и целом:
#!/usr/bin/env bash
set -x
# Это требует установки модуля видеопетли.
# sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="VirtualCam" exclusive_caps=1
# используйте `pw-cli list-objects | grep node.name`, чтобы получить аудиоустройство
AUDIO_DEVICE="alsa_input.pci-0000_00_1f.3.analog-stereo"
VIDEO_DEVICE="/dev/video0"
VIRTUAL_VIDEO_DEVICE="/dev/video10"
read -p "Введите имя для видео: " VIDEO_NAME
if [ -z "$VIDEO_NAME" ]; then
VIDEO_NAME="unnamed_video"
fi
OUTPUT_FILE="$HOME/videos/${VIDEO_NAME}_$(date +%Y%m%d_%H%M%S).mkv"
trap 'echo "Остановка записи..."; pkill -P $$; exit 0' SIGINT
ffmpeg -f v4l2 -r 30 -video_size 640x480 -input_format mjpeg -i "$VIDEO_DEVICE" \
-f pulse -i "$AUDIO_DEVICE" \
-c:v copy -f v4l2 "$VIRTUAL_VIDEO_DEVICE" \
-c:v libx264 -preset ultrafast -crf 28 -pix_fmt yuv420p \
-c:a aac -b:a 192k -ar 48000 \
"$OUTPUT_FILE" &
sleep 2
# Начать отображение потока виртуальной веб-камеры с mpv
mpv --no-osc \
--no-input-default-bindings \
--profile=low-latency \
--untimed \
--geometry=50%:50% \
--autofit=100% \
--input-conf=/dev/null \
--title="WebcamDisplay" \
--framedrop=no \
--vf=scale=640:-1 \
--vo=vaapi \
"av://v4l2:$VIRTUAL_VIDEO_DEVICE"
# Остановить все процессы после завершения
pkill ffmpeg
pkill mpv
Ответ или решение
Создание скрипта для одновременной трансляции камеры и записи видео
Если вы хотите одновременно отображать картинку с веб-камеры в отдельном окне и записывать видео, сочетание инструментов ffmpeg
, v4l2loopback
, и mpv
является отличным выбором. В этом руководстве приведён актуализированный и оптимизированный скрипт для достижения данной цели.
Исходные предпосылки
Перед тем как приступить к созданию скрипта, убедитесь, что у вас установлены необходимые пакеты и модули:
-
Установка v4l2loopback: Убедитесь, что модуль
v4l2loopback
активирован. Используйте следующую команду для его загрузки:sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="VirtualCam" exclusive_caps=1
-
Установка FFmpeg: Если FFmpeg ещё не установлен, выберите подходящий способ установки, в зависимости от вашей операционной системы.
-
Установка MPV: Убедитесь, что у вас установлен MPV для вывода изображения с веб-камеры.
Пример скрипта
Ниже представлен пример скрипта, который реализует вышеописанный функционал:
#!/usr/bin/env bash
set -x
# Аудио- и видеоустройства
AUDIO_DEVICE="alsa_input.pci-0000_00_1f.3.analog-stereo" # Замените на ваше устройство
VIDEO_DEVICE="/dev/video0" # Ваша веб-камера
VIRTUAL_VIDEO_DEVICE="/dev/video10" # Виртуальная камера
# Запрос имени видеофайла
read -p "Введите имя для видео: " VIDEO_NAME
if [ -z "$VIDEO_NAME" ]; then
VIDEO_NAME="unnamed_video"
fi
OUTPUT_FILE="$HOME/videos/${VIDEO_NAME}_$(date +%Y%m%d_%H%M%S).mkv"
# Обработка сигнала для остановки записи
trap 'echo "Остановлено."; pkill -P $$; exit 0' SIGINT
# Запуск FFmpeg для записи и вывода в виртуальную камеру
ffmpeg -f v4l2 -r 30 -video_size 640x480 -input_format mjpeg -i "$VIDEO_DEVICE" \
-f pulse -i "$AUDIO_DEVICE" \
-c:v copy -f v4l2 "$VIRTUAL_VIDEO_DEVICE" \
-c:v libx264 -preset ultrafast -crf 28 -pix_fmt yuv420p \
-c:a aac -b:a 192k -ar 48000 \
"$OUTPUT_FILE" &
sleep 2
# Запуск MPV для отображения изображения с виртуальной камеры
mpv --no-osc \
--no-input-default-bindings \
--profile=low-latency \
--untimed \
--geometry=50%:50% \
--autofit=100% \
--input-conf=/dev/null \
--title="WebcamDisplay" \
--framedrop=no \
--vf=scale=640:-1 \
--vo=vaapi \
"av://v4l2:$VIRTUAL_VIDEO_DEVICE"
# Остановка всех процессов при завершении
pkill ffmpeg
pkill mpv
Описание кода
-
Переменные: Задаются переменные для аудио и видео устройств, а также для имени выходного файла.
-
Обработка сигнала: При нажатии
Ctrl+C
выполняется остановка записи и выводится сообщение о завершении. -
Запуск FFmpeg:
- Входные параметры: Указываются параметры для получения потока с веб-камеры и аудиопотока.
- Выходные параметры: Видеопоток передаётся в виртуальную камеру, а также записывается в файл.
-
Запуск MPV: После небольшой паузы запускается MPV для отображения контента с виртуальной камеры.
Заключение
Этот скрипт позволяет одновременно использовать веб-камеру для трансляции и записи видео, что может быть полезно для различных задач, таких как создание обучающих материалов или прямые эфиры. Настройка и запуск такого решения требуют базовых знаний в области работы с Linux, но это прозрачное решение позволит вам легко начать работать с вашим видеопотоком.