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.hdr и stream_manifest.mpd записываются, и начинают создаваться фрагменты (т.е. stream_1.chk, stream_2.chk и т. д.). Однако FFMPEG выдает следующую ошибку:

Не удалось записать заголовок для выходного файла №0 (неверные параметры кодека?): при обработке входных данных обнаружены неверные данные

Я объясню, что, по моему мнению, я делаю с этим сценарием, и, надеюсь, это выявит любые ошибки в моем мышлении.

Во-первых, мы вызываем FFMPEG, чтобы использовать Video for Linux 2 (v4l2) для чтения с моей веб-камеры (/dev/video0) с разрешением 640x480. Входной формат — mjpeg с частотой кадров 24 кадра в секунду.

Затем я заявляю, что FFMPEG должен «отображать» (копировать) видеопоток, выводимый v4l2, в файл. Я указываю формат пикселей (YUV420P) и использую libvpx (кодирование VP8) для кодирования видеопотока. Я установил размер 640x480, использовал 4 потока, установил битрейт 50 кбит/с, поколдовал с параметрами колонок тайлов и параллельности кадров, а 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 ...

person Kenny Worden    schedule 23.04.2017    source источник
comment
Необходимо увидеть полные выходные данные консоли для команд. В любом случае, -s 640x480 -input_format mjpeg -r 24 должно быть -video_size 640x480 -framerate 24 -input_format mjpeg и должно стоять перед -i /dev/video0. Если ваше разрешение такое же, вы можете отказаться от второго -s 640x480 и сэкономить время.   -  person Gyan    schedule 24.04.2017
comment
Я внедрил ваши изменения и опубликовал полный вывод консоли.   -  person Kenny Worden    schedule 24.04.2017


Ответы (1)


Попробуйте использовать 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.

person Beshoy Hanna    schedule 16.09.2019