FFMPEG用VP8创建MPEG-DASH流

时间:2017-04-23 20:21:37

标签: video ffmpeg mpeg-dash vp8

我正在尝试使用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帧设置为相隔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 ...

1 个答案:

答案 0 :(得分: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

Source

您也可以下载我的GitHub repository以获得完整的e2e解决方案。