1

你好视频流之神我正在尝试复制网络摄像头流以发送它并且仍然能够在网络浏览器中使用它例如目标是使用 v4l2Loopback 创建一个虚拟视频设备使用 gstreamer 从真实获取源网络摄像头在我需要的地方(rtps 服务器)制作一个 tee 流,在另一个 tee 分支上使用 v4l2sink 转发到使用 v4l2loopback 创建的虚拟设备

我正在 ubuntu 20.04 下进行测试,但最终我打算在 raspian buster 上使用它

sudo apt install v4l2loopback-dkms v4l2loopback-utils

sudo modprobe v4l2loopback video_nr=100

看起来不错

$ v4l2-ctl --all -d /dev/video100 
Driver Info:
    Driver name      : v4l2 loopback
    Card type        : Dummy video device (0x0000)
    Bus info         : platform:v4l2loopback-000
    Driver version   : 5.4.65
    Capabilities     : 0x85208003
        Video Capture
        Video Output
        Video Memory-to-Memory
        Read/Write
        Streaming
        Extended Pix Format
        Device Capabilities
    Device Caps      : 0x85208000
        Video Memory-to-Memory
        Read/Write
        Streaming
        Extended Pix Format
        Device Capabilities
Priority: 0
Video input : 0 (loopback: ok)
Video output: 0 (loopback in)
Format Video Output:
    Width/Height      : 1920/1080
    Pixel Format      : 'YU12' (Planar YUV 4:2:0)
    Field             : None
    Bytes per Line    : 1920
    Size Image        : 3110400
    Colorspace        : sRGB
    Transfer Function : Default (maps to sRGB)
    YCbCr/HSV Encoding: Default (maps to ITU-R 601)
    Quantization      : Default (maps to Limited Range)
    Flags             : 
Streaming Parameters Video Capture:
    Frames per second: 30.000 (30/1)
    Read buffers     : 8
Streaming Parameters Video Output:
    Frames per second: 30.000 (30/1)
    Write buffers    : 8

User Controls

                    keep_format 0x0098f900 (bool)   : default=0 value=0
              sustain_framerate 0x0098f901 (bool)   : default=0 value=0
                        timeout 0x0098f902 (int)    : min=0 max=100000 step=1 default=0 value=0
               timeout_image_io 0x0098f903 (bool)   : default=0 value=0
 here

在流式传输我的真实网络摄像头之前,我只是尝试像 gstreamer v4l2sink doc 中解释的那样流式传输 videotestsrc

 gst-launch-1.0 videotestsrc ! v4l2sink device=/dev/video100

奇怪的是它说它不是输出设备(GST-DEBUG=3)

    $  gst-launch-1.0 videotestsrc ! v4l2sink device=/dev/video100
    Setting pipeline to PAUSED ...
    0:00:00.137162087 12355 0x5601d5516010 WARN                    v4l2 v4l2_calls.c:636:gst_v4l2_open:<v4l2sink0> error: Device '/dev/video100' is not a output device.
    0:00:00.137209656 12355 0x5601d5516010 WARN                    v4l2 v4l2_calls.c:636:gst_v4l2_open:<v4l2sink0> error: Capabilities: 0x85208000
    ERROR: Pipeline doesn't want to pause.
    ERROR: from element /GstPipeline:pipeline0/GstV4l2Sink:v4l2sink0: Device '/dev/video100' is not a output device.
    Additional debug info:
    v4l2_calls.c(636): gst_v4l2_open (): /GstPipeline:pipeline0/GstV4l2Sink:v4l2sink0:
    Capabilities: 0x85208000
    Setting pipeline to NULL ...
    Freeing pipeline ...

我希望找到像我这样的其他问题,但也许我没有很好地搜索我没有找到任何相关信息如果有人可以提供帮助,我会很高兴

非常感谢您一直阅读到这里,也非常感谢您提供任何帮助信息的想法等

编辑:我还尝试了 raspian buster raspberry pi 4 我在安装时遇到了 v4l2loopback 的一些问题,但我遵循了该主题https://github.com/RPi-Distro/repo/issues/188 并且能够安装它我已经做同样的事情(modprobe 然后是 gstream)并且 gstreamer v4l2Sink 在使用解决方法以避免 not negociated-4 错误时看起来可以工作

gst-launch-1.0 videotestsrc ! identity drop-allocation=1 ! v4l2sink device=/dev/video100

它看起来有效,但我收到了很多警告:

$ gst-launch-1.0 -v videotestsrc ! identity drop-allocation=1 ! v4l2sink device=/dev/video100
Définition du pipeline à PAUSED...
Le pipeline est en phase de PREROLL…
0:00:00.128889803 11076   0xe230f0 FIXME                default gstutils.c:3981:gst_pad_create_stream_id_internal:<videotestsrc0:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id
0:00:00.129497619 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YUYV@48x32: 0
0:00:00.129647893 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at UYVY@48x32: 0
0:00:00.129766111 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at 422P@48x32: 0
0:00:00.129872201 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YU12@48x32: 0
0:00:00.129975513 11076   0xe230f0 WARN                    v4l2 gstv4l2o$ gst-launch-1.0 -v videotestsrc ! identity drop-allocation=1 ! v4l2sink device=/dev/video100
Définition du pipeline à PAUSED...
Le pipeline est en phase de PREROLL…
0:00:00.128889803 11076   0xe230f0 FIXME                default gstutils.c:3981:gst_pad_create_stream_id_internal:<videotestsrc0:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id
0:00:00.129497619 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YUYV@48x32: 0
0:00:00.129647893 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at UYVY@48x32: 0
0:00:00.129766111 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at 422P@48x32: 0
0:00:00.129872201 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YU12@48x32: 0
0:00:00.129975513 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YV12@48x32: 0
0:00:00.130079232 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at 411P@48x32: 0
0:00:00.130190210 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YVU9@48x32: 0
0:00:00.130291689 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YUV9@48x32: 0
0:00:00.130395612 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at JPEG@48x32: 0
0:00:00.130483220 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at MJPG@48x32: 0
0:00:00.130570810 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at dvsd@48x32: 0
0:00:00.130658326 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at RGB4@48x32: 0
0:00:00.130753046 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at BGR4@48x32: 0
0:00:00.130847173 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at RGB3@48x32: 0
0:00:00.130959966 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at BGR3@48x32: 0
0:00:00.131055000 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at NV12@48x32: 0
0:00:00.131170441 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at RGBQ@48x32: 0
0:00:00.131266012 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at RGBP@48x32: 0
0:00:00.131359676 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at RGBO@48x32: 0
0:00:00.131454285 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at BA81@48x32: 0
0:00:00.131539338 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at GBRG@48x32: 0
0:00:00.131623317 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at GRBG@48x32: 0
0:00:00.131707907 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at RGGB@48x32: 0
0:00:00.131792701 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at GREY@48x32: 0
0:00:00.131889365 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at VP90@48x32: 0
0:00:00.131974881 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at VP80@48x32: 0
0:00:00.132062378 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at VC1L@48x32: 0
0:00:00.132151839 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at VC1G@48x32: 0
0:00:00.132250595 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at XVID@48x32: 0
0:00:00.132340129 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at MPG4@48x32: 0
0:00:00.132427053 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at MPG2@48x32: 0
0:00:00.132513495 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at MPG1@48x32: 0
0:00:00.132601677 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at H263@48x32: 0
0:00:00.132691304 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at AVC1@48x32: 0
0:00:00.132781080 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at H264@48x32: 0
0:00:00.132869910 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at Y16 @48x32: 0
0:00:00.132966408 11076   0xe230f0 WARN                    v4l2 gstv4l2object.c:2514:gst_v4l2_object_probe_caps_for_format_and_size:<v4l2sink0:sink> Unknown frame interval type at YVYU@48x32: 0
/GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0.GstPad:src: caps = video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, framerate=(fraction)30/1, multiview-mode=(string)mono, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, pixel-aspect-ratio=(fraction)1/1
/GstPipeline:pipeline0/GstIdentity:identity0.GstPad:src: caps = video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, framerate=(fraction)30/1, multiview-mode=(string)mono, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, pixel-aspect-ratio=(fraction)1/1
/GstPipeline:pipeline0/GstV4l2Sink:v4l2sink0.GstPad:sink: caps = video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, framerate=(fraction)30/1, multiview-mode=(string)mono, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, pixel-aspect-ratio=(fraction)1/1
/GstPipeline:pipeline0/GstIdentity:identity0.GstPad:sink: caps = video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, framerate=(fraction)30/1, multiview-mode=(string)mono, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, pixel-aspect-ratio=(fraction)1/1
Le pipeline a terminé la phase PREROLL…
Passage du pipeline à la phase PLAYING…
New clock: GstSystemClock

最后在尝试从此视频设备获取图像时

     $ ffmpeg -f video4linux2 -s 640x480 -i /dev/video100 -ss 0:0:2 -frames 1 /tmp/out2.jpg
    ffmpeg version 4.1.6-1~deb10u1+rpt1 Copyright (c) 2000-2020 the FFmpeg developers
      built with gcc 8 (Raspbian 8.3.0-6+rpi1)
...[truncated because of stack overflow body size limit]...
    Stream mapping:
      Stream #0:0 -> #0:0 (rawvideo (native) -> mjpeg (native))
    Press [q] to stop, [?] for help
    [swscaler @ 0x136f230] deprecated pixel format used, make sure you did set range correctly
    Output #0, image2, to '/tmp/out2.jpg':
      Metadata:
        encoder         : Lavf58.20.100
        Stream #0:0: Video: mjpeg, yuvj422p(pc), 320x240, q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc
        Metadata:
          encoder         : Lavc58.35.100 mjpeg
        Side data:
          cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
    [video4linux2,v4l2 @ 0x1363200] Dequeued v4l2 buffer contains 155648 bytes, but 153600 were expected. Flags: 0x00000001.
    /dev/video100: Invalid data found when processing input
    frame=    0 fps=0.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed=   0x    
    video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
    Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
4

1 回答 1

1

我刚刚完成了这个,并将解释 v4l2 视频设备的最大绊脚石。基本问题是真实设备只能访问一次,而环回设备不受限制。首先启动您的 USB 网络摄像头。您现在应该拥有 /dev/video0 和 /dev/video1。我不知道为什么会创建 video1,但请忽略它。接下来用“modprobe v4l2loopback devices=4”启动 v4l2loopback 现在你应该有 video0 到 video6。现在是棘手的部分,如果您尝试将 /dev/video0 复制到 /dev/video3,video3 将工作,但 video0 现在将报告“设备或资源繁忙”,因此您仍然卡在 1 个视频输出。这是因为 REAL 设备一次只能由 1 个程序访问,因为它们具有真正的 v4l2 控件。您不能有 2 个程序访问相同的控件。

解决方案是复制 /dev/video0 两次,如下所示: ffmpeg -f video4linux2 -i /dev/video0 -codec copy -f v4l2 /dev/video3 -codec copy -f v4l2 /dev/video4

现在,您可以使用“ffplay -i /dev/video3”查看正常的 video0,并且可以使用 /dev/video4 执行其他操作,如下所示

gst-launch-1.0 -v v4l2src device=/dev/video4 !自动视频转换!视频转换!视频/x-raw,宽度=640,高度=480,帧率=30/1!眩晕!v4l2sink 设备=/dev/video5

现在您可以使用“ffplay -i /dev/video3”查看原始视频,使用“ffplay -i /dev/video5”查看您处理过的视频

我希望它有所帮助,我花了几个小时的谷歌搜索才弄清楚这一点。:-)

于 2020-11-06T14:58:04.507 回答