如何将来自摄像头的MJPEG格式更改为YUYV422并输出到v4l2loopback?

huangapple go评论71阅读模式
英文:

How to change mjpeg to yuyv422 from a webcam to a v4l2loopback?

问题

Backstory: 我使用的一个直播网站不够智能,无法检测到我的网络摄像头(Logitech Brio,4k)的能力,而是只使用默认的每秒帧数设置,即5fps。

(完整的解决方案在回答中)

我能想到的最好的解决方案(除了更改直播供应商)是使用v4l2loopback创建一个回环虚拟摄像头,我可以强制它具有我想要在该直播网站上使用的确切设置。

对于Brio,较高的帧速率是使用mjpeg而不是默认的yuyv。

问题1:

我可以轻松读取mjpeg,但不幸的是,我一直在尝试解决这个问题,因为v4l2loopback显然只想要yuyv。

我尝试了类似以下的东西:

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -vcodec copy         \
       -f v4l2 /dev/video6

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -vcodec yuyv422      \ # 这一行发生了变化(甚至尝试了“copy”)
       -f v4l2 /dev/video6

但它们不起作用。我收到了类似以下的错误:

> 未知的yuvj422p的V4L2像素格式等效项

> ...使用了不推荐的像素格式,请确保您已正确设置范围...
>
> ...V4L2输出设备仅支持单个原始视频流...

最终,我让这个工作了:

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -pix_fmt yuyv422     \ # 获胜的条目
       -f v4l2 /dev/video6

问题2:

接下来的问题是让Chrome看到虚拟摄像头。它在guvcview上正常工作,在Firefox上,我可以使用网络摄像头测试网站,它也可以正常识别虚拟摄像头。

原来,Google以其过分保护的性质(顺便说一下,它正在窃取我们的所有数据)不想使用可以被读取和写入的网络摄像头。

因此,在启动v4l2loopback时,您必须告诉它向Chrome等消费者宣布它是“只读”的。

以下是我使用的确切modprobe,可以正常工作:

sudo modprobe v4l2loopback devices=1 exclusive_caps=1
英文:

Backstory: One livestreaming site I use isn't smart enough to detect the capabilities of my webcam (Logitech Brio, 4k), and instead just uses the default frames per second settings, which is 5fps.

(full solution walk-through in the answer)

The best solution I could think of (besides changing livestream providers) was to create a loopback virtual webcam using v4l2loopback that I could force to have the exact settings I wanted to use on that livestream site.

For the brio, the higher frame rates come with mjpeg, not the default yuyv.

Problem 1:

I could easily read mjpeg, but unfortunately kept banging my head against the wall because v4l2loopback evidently only wanted yuyv.

I tried things like:

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -vcodec copy         \
       -f v4l2 /dev/video6

and

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -vcodec yuyv422      \ # this line changed (even tried "copy")
       -f v4l2 /dev/video6

But they wouldn't work. I got errors like:

> Unknown V4L2 pixel format equivalent for yuvj422p

and

> ...deprecated pixel format used, make sure you did set range correctly...
>
> ...V4L2 output device supports only a single raw video stream...

Eventually I got this to work:

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -pix_fmt yuyv422     \ # The winning entry
       -f v4l2 /dev/video6

Problem 2

The next problem was getting chrome to see the virtual webcam. It worked correctly with guvcview, and on firefox I could use webcam testing sites and it would pick the virtual camera up without a problem.

Turns out google, in it's overly-protective nature (while it's siphoning off all our data, btw), doesn't want to use webcams that can be read and written to.

So when starting v4l2loopback you have to tell it to announce that it's "read only" to consumers like chrome.

Here's the exact modprobe I use that works:

sudo modprobe v4l2loopback devices=1 exclusive_caps=1

答案1

得分: 14

确切的解决方案。

1. 找出正确的输入摄像头

使用v4l2-ctl列出所有摄像头:

v4l2-ctl --list-devices

我的输出是这样的(你的可能会不同,我将使用我的作为示例):

Logitech BRIO (usb-0000:00:14.0-5.2):
    /dev/video0
    /dev/video1

HP HD Camera: HP HD Camera (usb-0000:00:14.0-9):
    /dev/video2
    /dev/video3
    /dev/video4
    /dev/video5

在这种情况下,我的 Brio 是 video0。

2. 启动 v4l2loopback:

sudo modprobe v4l2loopback devices=1 exclusive_caps=1

3. 确认您的回环设备:

v4l2-ctl --list-devices

现在我的显示如下,指示 video6 是回环设备:

Dummy video device (0x0000) (platform:v4l2loopback-000):
    /dev/video6

Logitech BRIO (usb-0000:00:14.0-5.2):
    /dev/video0
    /dev/video1

HP HD Camera: HP HD Camera (usb-0000:00:14.0-9):
    /dev/video2
    /dev/video3
    /dev/video4
    /dev/video5

4. 确定您的最佳输入设置

使用 guvcview 确定哪种编解码器提供您所需的分辨率和帧率(您可能需要使用菜单 -> 视频 -> 视频编解码器 -> 原始摄像头输入)。

我使用 mjpeg 得到了60fps,我只需要30fps。默认的 yuyv 提供了可怜的5fps。

现在使用 ffmpeg 列出摄像头的功能并获取匹配的编解码器:

ffmpeg -f v4l2 -list_formats all -i /dev/video0  # 在这里使用您的摄像头,来自第2步

在输出中,你会看到类似以下的内容:

[video4linux2,v4l2 @ 0x55f1a4e989c0] Raw       :     yuyv422 :           YUYV 4:2:2 : 640x480 160x120 176x144 320x180 320x240 352x288 340x340 424x240 440x440 480x270 640x360 800x448 800x600 848x480 960x540 1024x576 1280x720 1600x896 1920x1080
[video4linux2,v4l2 @ 0x55f1a4e989c0] Compressed:       mjpeg :          Motion-JPEG : 640x480 160x120 176x144 320x180 320x240 352x288 424x240 480x270 640x360 800x448 800x600 848x480 960x540 1024x576 1280x720 1600x896 1920x1080

在我的情况下,mjpeg 提供了 guvcview 中最佳的输出,并且这就是编解码器的确切名称(如上所示)。

5. 使用该输入编解码器并将像素格式更改为 yuyv 启动 ffmpeg:

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -pix_fmt yuyv422     \
       -f v4l2 /dev/video6  

将视频大小更新为您的直播/视频录制支持的最高大小,只要您的摄像头也支持它。

现在,当您想要进行直播时,只需使用标记为“Dummy”的摄像头。

英文:

Exact solution.

1. Figure out which webcam is the correct input webcam

Use v4l2-ctl to list all the webcams:

v4l2-ctl --list-devices

My output is this (yours will vary, I'll use mine as an example as I go):

Logitech BRIO (usb-0000:00:14.0-5.2):
	/dev/video0
	/dev/video1

HP HD Camera: HP HD Camera (usb-0000:00:14.0-9):
	/dev/video2
	/dev/video3
	/dev/video4
    /dev/video5

In this case my brio is video0.

2. Start v4l2loopback:

sudo modprobe v4l2loopback devices=1 exclusive_caps=1

3. Confirm your loopback device:

v4l2-ctl --list-devices

Mine now shows this, indicating video6 is the loopback:

Dummy video device (0x0000) (platform:v4l2loopback-000):
	/dev/video6

Logitech BRIO (usb-0000:00:14.0-5.2):
	/dev/video0
	/dev/video1

HP HD Camera: HP HD Camera (usb-0000:00:14.0-9):
	/dev/video2
	/dev/video3
	/dev/video4
	/dev/video5

4. Determine your optimal input settings

Use guvcview to figure out which codec gives you the resolution and framerate you're looking for (you may have to use the menu -> Video -> Video Codec -> Raw camera input).

I got 60fps using mjpeg, I only needed 30. The default yuyv gave a miserable 5fps.

Now use ffmpeg to list the capabilities of the camera and get the matching codec:

ffmpeg -f v4l2 -list_formats all -i /dev/video0  #use your camera here from step 2

In the output you'll see something like this:

[video4linux2,v4l2 @ 0x55f1a4e989c0] Raw       :     yuyv422 :           YUYV 4:2:2 : 640x480 160x120 176x144 320x180 320x240 352x288 340x340 424x240 440x440 480x270 640x360 800x448 800x600 848x480 960x540 1024x576 1280x720 1600x896 1920x1080
[video4linux2,v4l2 @ 0x55f1a4e989c0] Compressed:       mjpeg :          Motion-JPEG : 640x480 160x120 176x144 320x180 320x240 352x288 424x240 480x270 640x360 800x448 800x600 848x480 960x540 1024x576 1280x720 1600x896 1920x1080

In my case it was the mjpeg that gave the best output in guvcview, and that was the exact name of the codec (as indicated above).

5. Start ffmpeg using that input codec and changing the pixel format to yuyv:

ffmpeg -f v4l2              \
       -input_format mjpeg  \
       -framerate 30        \
       -video_size 1280x720 \
       -i /dev/video0       \
       -pix_fmt yuyv422     \
       -f v4l2 /dev/video6  

Update the video size to the highest size your livestream/video record will support, as long as your camera also supports it.

Now when you want to livestream, just use the camera labeled "Dummy"

huangapple
  • 本文由 发表于 2020年1月3日 15:53:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/59574987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定