如何将网络摄像头录制到 X11 以外的文件中?

How to record a webcam to a file outside of X11?

我正在与教师合作,自动记录他们的 类,这样我们就可以审查他们并提高教学质量。我们有计算机 运行ning Ubuntu 17.10,在几个教室里有多个网络摄像头 - 但我可以 运行 其他软件,如果它可以使这项任务更容易。

我可以使用 gstreamer 成功地将网络摄像头的流记录到 h264 编码文件中。以下应该适用于大多数安装了 gstreamer 的人,但我有使用 vaapi 的更高级的管道,它可以在 NUC 上同时编码多个 4k 流,并有剩余空间!我的观点是,当我在 GUI 的终端上输入时,Gstreamer 工作得很好。示例:

.\gst-launch-1.0.exe -e autovideosrc ! videoconvert ! \
  openh264enc max-bitrate=256000 ! h264parse ! \
  mp4mux ! filesink location=somefile.mp4

我想我也可以这样做 with ffmpeg, or OpenCV,甚至可能是 VLC(我可以通过 GUI 录制网络摄像头,所以我想我可以用它来生成命令行?)。

但是当我尝试上述任何一种方法时,例如,通过 SSH,我从 GStreamer 和 OpenCV 中得到错误,从 ffmpeg 中得到空白视频(我没有尝试过 VLC,因为我目前无法访问这些机)。我需要自动化 - 但我可能会让用户保持登录状态。我只需要 一些 方法来通过一定程度的合理压缩将网络摄像头捕获到磁盘。

我天真地认为我可以将上面的内容放入 cron 作业中并且我会很高兴(打算发送 SIGINT 以结束记录)。但是任何可以以某种方式自动安排的东西都会很棒。

编辑:下面是我正在尝试使用 ffmpeg 的一种方法。从输出中可以看出,我想不出如何以ffmpeg关注的方式指定pixel_format!首先,命令(使用 mkv 因为它似乎是 "low-stress" 格式,但也尝试过 mov 和 mp4):

ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 \
  -f v4l2 -framerate 30 -video_size hd720 -pixel_format yuv420p -i /dev/video1 output.mkv

就像我说的,我正在尝试获得硬件加速,您可以在下面看到 VAAPI 正在运行(但我认为只是为了解码)。您可以轻松地从第一行中删除选项,无论哪种方式,我都会得到类似的结果。我没有将 header 包含在编译选项和库版本中,因为它是标准 Ubuntu 17.10.

libva info: VA-API version 0.40.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_40
libva info: va_openDriver() returns 0
Input #0, video4linux2,v4l2, from '/dev/video1':
  Duration: N/A, start: 42437.238243, bitrate: 442368 kb/s
    Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1280x720, 442368 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
File 'output.mkv' already exists. Overwrite ? [y/N] y
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Press [q] to stop, [?] for help
No pixel format specified, yuv422p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264 @ 0x55d1a26a71a0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
[libx264 @ 0x55d1a26a71a0] profile High 4:2:2, level 3.1, 4:2:2 8-bit
[libx264 @ 0x55d1a26a71a0] 264 - core 148 r2795 aaa9aa8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, matroska, to 'output.mkv':
  Metadata:
    encoder         : Lavf57.71.100
    Stream #0:0: Video: h264 (libx264) (H264 / 0x34363248), yuv422p, 1280x720, q=-1--1, 30 fps, 1k tbn, 30 tbc
    Metadata:
      encoder         : Lavc57.89.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
Past duration 0.717049 too large
Past duration 0.879128 too large
frame=  567 fps= 16 q=27.0 size=    2156kB time=00:00:34.16 bitrate= 516.9kbits/s speed=0.938x

我退出 ctrl-C。这导致看似有序的退出:

[libx264 @ 0x55d1a26a71a0] frame I:11    Avg QP:15.75  size: 18573
[libx264 @ 0x55d1a26a71a0] frame P:2176  Avg QP:19.91  size:  4435
[libx264 @ 0x55d1a26a71a0] frame B:173   Avg QP:20.00  size:  3232
[libx264 @ 0x55d1a26a71a0] consecutive B-frames: 90.1%  0.1%  0.6%  9.2%
[libx264 @ 0x55d1a26a71a0] mb I  I16..4: 34.0% 56.1%  9.8%
[libx264 @ 0x55d1a26a71a0] mb P  I16..4:  0.1%  1.2%  0.0%  P16..4: 32.7%  3.1%  6.1%  0.0%  0.0%    skip:56.8%
[libx264 @ 0x55d1a26a71a0] mb B  I16..4:  0.0%  0.3%  0.0%  B16..8: 31.9%  0.7%  0.1%  direct: 1.4%  skip:65.6%  L0:41.8% L1:57.9% BI: 0.3%
[libx264 @ 0x55d1a26a71a0] 8x8 transform intra:81.2% inter:92.4%
[libx264 @ 0x55d1a26a71a0] coded y,uvDC,uvAC intra: 25.4% 20.1% 2.1% inter: 10.2% 7.4% 0.0%
[libx264 @ 0x55d1a26a71a0] i16 v,h,dc,p: 78% 10%  7%  5%
[libx264 @ 0x55d1a26a71a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu:  7%  6% 72%  2%  3%  3%  2%  2%  3%
[libx264 @ 0x55d1a26a71a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 34% 21% 25%  4%  5%  3%  4%  1%  3%
[libx264 @ 0x55d1a26a71a0] i8c dc,h,v,p: 69% 14% 15%  2%
[libx264 @ 0x55d1a26a71a0] Weighted P-Frames: Y:1.7% UV:0.1%
[libx264 @ 0x55d1a26a71a0] ref P L0: 49.3%  2.7% 29.6% 18.1%  0.3%
[libx264 @ 0x55d1a26a71a0] ref B L0: 69.3% 24.1%  6.6%
[libx264 @ 0x55d1a26a71a0] ref B L1: 86.6% 13.4%
[libx264 @ 0x55d1a26a71a0] kb/s:529.95
Exiting normally, received signal 2.

使用

ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 \
  -f v4l2 -framerate 30 -video_size hd720 -pixel_format yuv420p -i /dev/video1 \
  -c:v libx264 -pix_fmt yuv420p output.mkv

输出的像素格式应在输入之后和输出之前指定,并且使用 pix_fmt 指定。