Mesclar vários vídeos com canal de áudio e sem áudio

1

Eu preciso mesclar vídeos muito diferentes em um vídeo de saída. Os vídeos de entrada podem ter diferentes resoluções, taxa de quadros, canais e assim por diante. Assim, alguns vídeos podem ser sem canal de áudio e devem ser mesclados com o vídeo com o canal de áudio . Eu não sei de antemão se é com ou sem canal de áudio Então eu uso ffmpeg com -filter_complex para fazer vídeos com o mesmo tamanho de frame e próximo filtro concat para mesclá-los. (também preciso cortar vídeos de entrada, mas deixe-me pular esta parte aqui)

ffmpeg.exe -i "withAudio.flv" -i "noAudio.mpg" \
-filter_complex \
    "[0:v]scale=1280:720, setsar=1/1, setpts=PTS-STARTPTS[v0]; \
    [1:v]scale=1280:720, setsar=1/1, setpts=PTS-STARTPTS[v1]; \
    [v0][0:a] [v1][1:a] concat=n=2:v=1:a=1[v][a]" \
 -map "[v]" -map "[a]" -vcodec libx264 -b 512k -acodec libfaac -ar 44100 -ab 128k  \
-pix_fmt yuv420p -movflags faststart -y "result.mp4"

E no resultado eu recebo um erro sobre falta de canal

Stream specifier ':a' in filtergraph description [0:v]scale=1280:720, setsar=1/1
, setpts=PTS-STARTPTS[v0]; [1:v]scale=1280:720, setsar=1/1, setpts=PTS-STARTPTS[
v1];  [v0][0:a] [v1][1:a] concat=n=2:v=1:a=1[v][a] matches no streams.

Completo

ffmpeg version 2.8.6 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.9.3 (GCC)
  configuration: --prefix=/opt/xtendx/local --arch=x86 --target-os=mingw32 --cross-prefix=i686-w64-mingw32- --pkg-config=pkg-config --disable-pthreads --enable-w32threads --extra-libs=-lws2_32 --extra-libs=-lwinmm --extra-libs=-lgdi32 --enable-static --disable-shared --disable-debug --disable-indevs --disable-outdevs --disable-iconv --disable-bzlib --disable-ffplay --disable-ffserver --enable-gpl --enable-version3 --enable-nonfree --enable-librtmp --enable-libmp3lame --enable-libfaac --enable-libfdk-aac --enable-libx264 --enable-libvpx --disable-libxcb --disable-libxcb-shm --disable-libxcb-xfixes --disable-libxcb-shape --enable-decoder=prores_lgpl --disable-decoder=prores --enable-runtime-cpudetect --disable-openssl
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
Input #0, flv, from 'withAudio.flv':
  Metadata:
    starttime       : 0
    totalduration   : 30
    totaldatarate   : 484
    bytelength      : 1846185
    canseekontime   : true
    sourcedata      : B4A7D0D44HH1361885066111689
    purl            :
    pmsg            :
    httphostheader  : r15---sn-1gi7zn7s.c.youtube.com
  Duration: 00:00:30.48, start: 0.000000, bitrate: 484 kb/s
    Stream #0:0: Video: h264 (Main), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 388 kb
/s, 25 fps, 25 tbr, 1k tbn, 50 tbc
    Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp, 99 kb/s
Input #1, mpeg, from 'noAudio.mpg':
  Duration: 00:00:29.96, start: 0.500000, bitrate: 8040 kb/s
    Stream #1:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv), 720x576 [SAR 64:4
5 DAR 16:9], 8000 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc


Stream specifier ':a' in filtergraph description [0:v]scale=1280:720, setsar=1/1
, setpts=PTS-STARTPTS[v0]; [1:v]scale=1280:720, setsar=1/1, setpts=PTS-STARTPTS[
v1];  [v0][0:a] [v1][1:a] concat=n=2:v=1:a=1[v][a] matches no streams.

Na documentação do FFmpeg para filtro de concat:

The filter works on segments of synchronized video and audio streams.
All segments must have the same number of streams of eachtype, 
and that will also be the number of streams at output.

Então, como posso criar o comando para mesclar vários vídeos com diferentes canais numéricos ?

    
por Alex V 24.02.2016 / 17:51

1 resposta

2

O FFmpeg espera que um fluxo de áudio seja emparelhado com o segundo vídeo. Como não há um, você terá que fornecer um manequim.

Como você não tem certeza se as entradas possuem áudio, execute este comando para cada entrada:

ffmpeg -i <input> -f lavfi -i anullsrc -c:v copy \
-map 0:v -map 0:a? -map 1:a -shortest <output>

E depois, com os arquivos processados

ffmpeg.exe -i <input1> -i <input2> \
-filter_complex \
"[0:v]scale=1280:720, setsar=1/1, setpts=PTS-STARTPTS[v0]; \
 [1:v]scale=1280:720, setsar=1/1, setpts=PTS-STARTPTS[v1]; \
 [v0][0:a] [v1][1:a] concat=n=2:v=1:a=1[v][a]" \
-map "[v]" -vcodec libx264 -b:v 512k -pix_fmt yuv420p \
-map "[a]" -acodec libfaac -b:a 128k -ar 44100 \
-movflags faststart -y "result.mp4"
    
por 24.02.2016 / 18:09