3

我正在尝试使用 FFMPEG 从我的网络摄像头流式传输实时视频/dev/video0。遵循分散的教程和稀缺的文档(这是编码社区的一个已知问题吗?)我得到了以下 bash 脚本:

#!/bin/bash

ffmpeg \
    -y \
    -f v4l2 \
        -i /dev/video0 \
        -s 640x480 \
        -input_format mjpeg \
        -r 24 \
    -map 0:0 \
    -pix_fmt yuv420p \
    -codec:v libvpx \
        -s 640x480 \
        -threads 4 \
        -b:v 50k \
        -tile-columns 4 \
        -frame-parallel 1 \
        -keyint_min 24 -g 24 \
    -f webm_chunk \
        -header "stream.hdr" \
        -chunk_start_index 1 \
    stream_%d.chk &

sleep 2

ffmpeg \
    -f webm_dash_manifest -live 1 \
    -i stream.hdr \
    -c copy \
    -map 0 \
    -f webm_dash_manifest -live 1 \
        -adaptation_sets "id=0,streams=0" \
        -chunk_start_index 1 \
        -chunk_duration_ms 1000 \
        -time_shift_buffer_depth 30000 \
        -minimum_update_period 60000 \
    stream_manifest.mpd

当我运行这个脚本时,我的网络摄像头灯亮起,stream.hdrstream_manifest.mpd文件被写入,并且开始创建块(即stream_1.chkstream_2.chk等...)。但是,FFMPEG 会引发以下错误:

无法为输出文件 #0 写入标头(编解码器参数不正确?):处理输入时发现无效数据

我将解释我认为我在用这个脚本做什么,并希望这会暴露我的想法中的任何错误。

首先,我们调用 FFMPEG 以使用 Video for Linux 2 (v4l2) 从/dev/video0分辨率为 640x480 的网络摄像头 ( ) 中读取数据。输入格式mjpeg的帧率为 24fps。

然后我声明 FFMPEG 应该将 v4l2 输出的视频流“映射”(复制)到一个文件。我指定像素格式(YUV420P)并使用 libvpx(VP8 编码)对视频流进行编码。我将大小设置为 640x480,使用 4 个线程,将比特率设置为 50kbps,使用 tile-columns 和 frame-parallel 选项做一些魔术,并将 I-frames 设置为相隔 24 帧。

然后我创建一个stream.hdr文件。起始索引为 1。此命令继续无限运行,直到我将其杀死,从我的网络摄像头中抓取新视频并将其输出为块。

然后我休眠 2 秒,给前面的命令时间来生成头文件。

就是这样。FFMPEG 的下一次调用只是根据上一步中生成的标头创建 MPEG-DASH 清单文件。

发生什么了?为什么我不能在网络浏览器中观看视频(我使用的是 Dash.js)?我在 Node.js 服务器上提供清单、标头和块,因此琐碎的问题不是问题。


编辑:这是我的完整控制台输出。

ffmpeg version 3.0.7-0ubuntu0.16.10.1 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.2.0 (Ubuntu 6.2.0-5ubuntu12) 20161005
  configuration: --prefix=/usr --extra-version=0ubuntu0.16.10.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librubberband --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-chromaprint --enable-libx264
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
[video4linux2,v4l2 @ 0x55847e244ea0] The driver changed the time per frame from 1/24 to 1/30
[mjpeg @ 0x55847e245c00] Changing bps to 8
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 64305.102081, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, -5 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Codec AVOption frame-parallel (Enable frame parallel decodability features) specified for output file #0 (stream_%d.chk) has not been used for any stream. The most likely reason is either wrong type (e.g. a video option with no video streams) or that it is a private option of some encoder which was not actually used for any stream.
Codec AVOption tile-columns (Number of tile columns to use, log2) specified for output file #0 (stream_%d.chk) has not been used for any stream. The most likely reason is either wrong type (e.g. a video option with no video streams) or that it is a private option of some encoder which was not actually used for any stream.
[swscaler @ 0x55847e24b720] deprecated pixel format used, make sure you did set range correctly
[libvpx @ 0x55847e248a20] v1.5.0
Output #0, webm_chunk, to 'stream_%d.chk':
  Metadata:
    encoder         : Lavf57.25.100
    Stream #0:0: Video: vp8 (libvpx), yuv420p, 640x480, q=-1--1, 50 kb/s, 30 fps, 30 tbn, 30 tbc
    Metadata:
      encoder         : Lavc57.24.102 libvpx
    Side data:
      unknown side data type 10 (24 bytes)
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> vp8 (libvpx))
Press [q] to stop, [?] for help
frame=   21 fps=0.0 q=0.0 size=N/A time=00:00:00.70 bitrate=N/A dup=5 drop=frame=   36 fps= 35 q=0.0 size=N/A time=00:00:01.20 bitrate=N/A dup=5 drop=frame=   51 fps= 33 q=0.0 size=N/A time=00:00:01.70 bitrate=N/A dup=5 drop=ffmpeg version 3.0.7-0ubuntu0.16.10.1 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.2.0 (Ubuntu 6.2.0-5ubuntu12) 20161005
  configuration: --prefix=/usr --extra-version=0ubuntu0.16.10.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librubberband --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-chromaprint --enable-libx264
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, webm_dash_manifest, from 'stream.hdr':
  Metadata:
    encoder         : Lavf57.25.100
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: vp8, yuv420p, 640x480, SAR 1:1 DAR 4:3, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
    Metadata:
      webm_dash_manifest_file_name: stream.hdr
      webm_dash_manifest_track_number: 1
Output #0, webm_dash_manifest, to 'stream_manifest.mpd':
  Metadata:
    encoder         : Lavf57.25.100
    Stream #0:0: Video: vp8, yuv420p, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
    Metadata:
      webm_dash_manifest_file_name: stream.hdr
      webm_dash_manifest_track_number: 1
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Could not write header for output file #0 (incorrect codec parameters ?): Invalid data found when processing input
frame=   67 fps= 33 q=0.0 size
frame=   82 fps= 32 q=0.0 size=N/A time=00:00:02.73 bitrate=N/A dup=5 drop=
frame=   97 fps= 32 q=0.0 size=N/A time=00:00:03.23 bitrate=N/A dup=5 drop=
frame=  112 fps= 32 q=0.0 size=N/A time=00:00:03.73 bitrate=N/A dup=5 ...
4

1 回答 1

0

尝试使用 DashCast。对于 Linux,命令类似于:

DashCast -vf video4linux2 -v4l2f mjpeg -vfr 30 -vres 1280x720 -v /dev/video0 -af alsa -a plughw:2,0 -conf dashcast.conf -live

资源

您还可以下载我的GitHub 存储库以获得完整的 e2e 解决方案。

于 2019-09-16T14:49:56.747 回答