Eu tenho um caso de uso em que pego alguns arquivos MPEG-4, corto-os e concateno-os em um arquivo. Eu tenho um segundo caso de uso em que um desses arquivos é cortado e também cortado/dimensionado, esses arquivos devem ser recodificados.
O problema com o segundo caso de uso é que acabo com uma mistura de dois layouts de arquivo diferentes:
Corte apenas:
Format : MPEG-4
Format : AVC
Format/Info : Advanced Video Codec
Format profile : [email protected]
Format settings, CABAC : Yes
Format settings, ReFrames : 4 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 28s 17ms
Bit rate : 3 362 Kbps
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Variable
Frame rate : 60.000 fps
Minimum frame rate : 58.824 fps
Maximum frame rate : 62.500 fps
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.061
Stream size : 11.2 MiB (95%)
Color primaries : BT.709
Transfer characteristics : sYCC
Matrix coefficients : BT.709
Aparar + cortar/escalar (recodificar)
Format : MPEG-4
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High 4:4:4 [email protected]
Format settings, CABAC : No
Format settings, ReFrames : 1 frame
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 29s 0ms
Bit rate : 24.8 Mbps
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 60.000 fps
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.448
Stream size : 85.7 MiB (99%)
Writing library : x264 core 144 r96 40bb568
Encoding settings : cabac=0 / ref=1 / deblock=0:0:0 / analyse=0:0 / me=dia / subme=0 / psy=0 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=0 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=0 / chroma_qp_offset=0 / threads=3 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=250 / keyint_min=25 / scenecut=0 / intra_refresh=0 / rc=cqp / mbtree=0 / qp=0
comando dimensionar/cortar:
ffmpeg -i -ss 05 test.mp4 -c:a copy -vf "crop=w=(in_w/1000)*%d:h=(in_h/566)*%d:x=(in_w/1000)*%d:y=(in_h/566)*%d,scale=in_w:in_h" out-scale-crop.mp4
A pedido de LordNeckbeard, a saída do FFMPEG foi adicionada
ffmpeg version N-43527-gb23a866- http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2015 the FFmpeg developers
built on Jan 13 2015 01:29:05 with gcc 4.9.2 (Debian 4.9.2-10)
configuration: --enable-gpl --enable-version3 --disable-shared --disable-debug --enable-runtime-cpudetect --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libwebp --enable-libspeex --enable-libvorbis --enable-libvpx --enable-libfreetype --enable-fontconfig --enable-libxvid --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-gray --enable-libopenjpeg --enable-libopus --disable-ffserver --enable-libass --enable-gnutls --cc=gcc
libavutil 54. 16.100 / 54. 16.100
libavcodec 56. 20.100 / 56. 20.100
libavformat 56. 18.101 / 56. 18.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 7.100 / 5. 7.100
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rohan/render_cache/v4033205_745.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.18.101
Duration: 00:00:35.77, start: 0.000000, bitrate: 2143 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 2001 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 131 kb/s (default)
Metadata:
handler_name : SoundHandler
[libx264 @ 0x360bd20] using cpu capabilities: MMX2 SSE Cache64
[libx264 @ 0x360bd20] profile High 4:4:4 Predictive, level 3.0, 4:2:0 8-bit
[libx264 @ 0x360bd20] 264 - core 144 r96 40bb568 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, mp4, to '/home/rohan/render_cache/v4033205_745_1_cut.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.18.101
Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 690x384, q=-1--1, 30 fps, 15360 tbn, 30 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : Lavc56.20.100 libx264
Stream #0:1(und): Audio: aac ([64][0][0][0] / 0x0040), 44100 Hz, stereo, 131 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 15 fps=0.0 q=0.0 size= 633kB time=00:00:00.55 bitrate=9409.0kbits/sframe= 65 fps= 65 q=0.0 size= 2986kB time=00:00:02.22 bitrate=11002.2kbits/frame= 117 fps= 77 q=0.0 size= 5507kB time=00:00:03.96 bitrate=11380.3kbits/frame= 182 fps= 91 q=0.0 size= 7832kB time=00:00:06.12 bitrate=10476.3kbits/frame= 244 fps= 97 q=0.0 size= 10248kB time=00:00:08.19 bitrate=10250.0kbits/frame= 290 fps= 96 q=0.0 size= 12275kB time=00:00:09.72 bitrate=10342.1kbits/frame= 337 fps= 96 q=0.0 size= 14408kB time=00:00:11.27 bitrate=10464.6kbits/frame= 401 fps= 99 q=0.0 size= 17318kB time=00:00:13.41 bitrate=10575.5kbits/frame= 458 fps=101 q=0.0 size= 20332kB time=00:00:15.31 bitrate=10872.8kbits/frame= 477 fps= 90 q=0.0 size= 21308kB time=00:00:15.94 bitrate=10946.6kbits/frame= 541 fps= 93 q=0.0 size= 24973kB time=00:00:18.08 bitrate=11314.0kbits/frame= 601 fps= 95 q=0.0 size= 28271kB time=00:00:20.07 bitrate=11534.2kbits/frame= 654 fps= 96 q=0.0 size= 31201kB time=00:00:21.84 bitrate=11701.2kbits/frame= 714 fps= 97 q=0.0 size= 34484kB time=00:00:23.86 bitrate=11837.8kbits/frame= 769 fps= 98 q=0.0 size= 37860kB time=00:00:25.69 bitrate=12069.0kbits/frame= 814 fps= 97 q=0.0 size= 40593kB time=00:00:27.18 bitrate=12232.8kbits/frame= 840 fps= 97 q=-1.0 Lsize= 42204kB time=00:00:28.02 bitrate=12338.7kbits/s dup=1 drop=0
video:41726kB audio:453kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.058509%
[libx264 @ 0x360bd20] frame I:4 Avg QP: 0.00 size:132759
[libx264 @ 0x360bd20] frame P:836 Avg QP: 0.00 size: 50474
[libx264 @ 0x360bd20] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x360bd20] mb P I16..4: 15.1% 0.0% 0.0% P16..4: 40.7% 0.0% 0.0% 0.0% 0.0% skip:44.2%
[libx264 @ 0x360bd20] coded y,uvDC,uvAC intra: 99.5% 98.9% 98.7% inter: 36.3% 39.9% 39.5%
[libx264 @ 0x360bd20] i16 v,h,dc,p: 56% 44% 0% 0%
[libx264 @ 0x360bd20] i8c dc,h,v,p: 0% 44% 55% 0%
[libx264 @ 0x360bd20] kb/s:12207.68
comando de corte:
ffmpeg -i -ss 05 test.mp4 -codec copy trimmed.mp4
ffmpeg version N-43527-gb23a866- http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2015 the FFmpeg developers
built on Jan 13 2015 01:29:05 with gcc 4.9.2 (Debian 4.9.2-10)
configuration: --enable-gpl --enable-version3 --disable-shared --disable-debug --enable-runtime-cpudetect --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libwebp --enable-libspeex --enable-libvorbis --enable-libvpx --enable-libfreetype --enable-fontconfig --enable-libxvid --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-gray --enable-libopenjpeg --enable-libopus --disable-ffserver --enable-libass --enable-gnutls --cc=gcc
libavutil 54. 16.100 / 54. 16.100
libavcodec 56. 20.100 / 56. 20.100
libavformat 56. 18.101 / 56. 18.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 7.100 / 5. 7.100
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rohan/render_cache/v4033205_6295.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.18.101
Duration: 00:00:36.02, start: 0.000000, bitrate: 2142 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 2001 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 131 kb/s (default)
Metadata:
handler_name : SoundHandler
Output #0, mp4, to '/home/rohan/render_cache/v4033205_6295_0_cut.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.18.101
Stream #0:0(und): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1920x1080, q=2-31, 2001 kb/s, 30 fps, 30 tbr, 90k tbn, 90k tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac ([64][0][0][0] / 0x0040), 44100 Hz, stereo, 131 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 841 fps=0.0 q=-1.0 Lsize= 7498kB time=00:00:28.02 bitrate=2192.1kbits/s
Quando eu reproduzo um conjunto de arquivos cortados concatenados em um arquivo, tudo parece ser reproduzido corretamente no MPC-HC e no Youtube, mas quando eu adiciono arquivos dimensionados/cortados e os concateno junto com os arquivos não dimensionados/cortados, ambos os jogadores congelam ao mudar para os próximos segmentos.
Eu suspeito que a mudança de taxa de quadros variável/constante seja a culpada.
A solução fácil seria apenas recodificar tudo para a mesma taxa de quadros constante, mas espero não precisar (codec: a cópia é rápida e mantém a qualidade) e a fonte que estou recebendo esses arquivos de poderia ter taxas de quadros diferentes, etc.
De preferência, eu gostaria de realizar a recodificação de corte/escala usando exatamente as mesmas configurações do arquivo de entrada, para não encontrar essa incompatibilidade nos arquivos de saída ao concatenar. Isso é possível?
Edição nº 2, @occvtech
Na verdade, estou usando o protocolo concat usando um merge_list.txt assim:
./ffmpeg -f concat -i merge_list.txt -codec copiar saída.mp4
E sua saída:
ffmpeg version 2.6.2- http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.9.2 (Debian 4.9.2-10)
configuration: --enable-gpl --enable-version3 --disable-shared --disable-debug --enable-runtime-cpudetect --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libwebp --enable-libspeex --enable-libvorbis --enable-libvpx --enable-libfreetype --enable-fontconfig --enable-libxvid --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-gray --enable-libopenjpeg --enable-libopus --enable-libass --enable-gnutls --enable-libvidstab --enable-libsoxr --cc=gcc-4.9
libavutil 54. 20.100 / 54. 20.100
libavcodec 56. 26.100 / 56. 26.100
libavformat 56. 25.101 / 56. 25.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 11.102 / 5. 11.102
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, concat, from '/home/rohan/render_cache/merge_list.txt':
Duration: N/A, start: 0.000000, bitrate: 2208 kb/s
Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 2076 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 131 kb/s
Output #0, mp4, to '/home/rohan/render_cache/sivhd_final.mp4':
Metadata:
encoder : Lavf56.25.101
Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1920x1080, q=2-31, 2076 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc
Stream #0:1: Audio: aac ([64][0][0][0] / 0x0040), 44100 Hz, stereo, 131 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[concat @ 0x3204d60] DTS 92955 < 541117 out of order
[mp4 @ 0x322eb80] Non-monotonous DTS in output stream 0:0; previous: 92351, current: 15864; changing to 92352. This may result in incorrect timestamps in the output file. x 2000
frame= 421 fps=0.0 q=-1.0 Lsize= 13507kB time=00:00:14.07 bitrate=7862.8kbits/s
video:13268kB audio:226kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.096110%
O aviso DTS não monótono é impresso bastante (240 vezes), mas DTS se refere ao áudio e o áudio no arquivo de saída soa bem até a parte cortada/aparada.
Também tentei sua sugestão para alterar a taxa de quadros (e combinações com diferentes parâmetros vsync) tanto na etapa de corte / corte ffmpeg quanto na etapa concat, mas elas só parecem realmente ter efeito quando estou recodificando, não copiando o codec.
--
Depois que comecei a escrever esta segunda edição, tenho tentado todos os argumentos vsync, filter:v fps, framerate, -r por algumas horas e a única solução real de trabalho até agora foi recodificar tudo com 60 fps (mesmo que eles não são aparados/cortados) e concatenando isso. Usando -preset ultrafast e -qp 0 parece rápido o suficiente e os tamanhos dos arquivos são muito grandes, mas não vou guardar os arquivos de qualquer maneira.
Portanto, parece que a cópia do codec é proibida quando há pelo menos um arquivo cortado/dimensionado.
Se alguém tiver uma solução para isso sem precisar recodificar tudo, aceitarei com prazer, caso contrário, concederei a recompensa a @occvtech.
Responder1
Tive problemas semelhantes com o filtro concat e acho que é devido às diferentes bases de tempo usadas para as entradas.
Eu superei isso com o concatmétodo de protocolo.
Acho que está mostrando uma taxa de quadros variável para sua saída somente de corte porque com um tempo base de 1/90000, um vídeo de 60 Hz esperará um quadro a cada 1.500, mas o filtro concat pode ter esmagado dois vídeos juntos com um intervalo de 1.530 ciclos entre o último e o primeiro frames (58.824 fps) e em algum outro lugar 1440 (62.500 fps). Além disso, por alguma razão, o ffmpeg decidiu definir a base de tempo de saída para 1/15360.
Quando você cortou, ele reavaliou o tempo base para toda a duração da saída, e é por isso que você obtém a taxa de quadros constante. Observe que seu primeiro vídeo mostra um tbn de 15360, enquanto o segundo é de 90k.
No meu caso, notei que com o filtro concat, os valores PTS/DTS estavam sendo definidos em termos da base de tempo da primeira entrada, mesmo quando a base de tempo para os outros fluxos de vídeo de entrada não era a mesma. Com o primeiro vídeo usando 1/25 e o segundo usando 1/90000, executando isso na saída (que tinha uma nova base de tempo de 1/12800):
ffprobe -hide_banner -show_frames -i output.mp4 2>&1 | grep -A 21 video | grep ts=
No ponto de transição entre os vídeos isso acontece:
pkt_pts=253952
pkt_dts=253952
pkt_pts=254464
pkt_dts=254464
pkt_pts=254976
pkt_dts=254976
pkt_pts=255488
pkt_dts=255488
pkt_pts=256000
pkt_dts=923443200
pkt_pts=925286400
pkt_dts=925286400
pkt_pts=923443200
pkt_dts=1045094400
pkt_pts=952934400
pkt_dts=1046937600
pkt_pts=954777600
pkt_dts=1048780800
pkt_pts=956620800
pkt_dts=1050624000
Responder2
Você não pode copiar o codec ao aplicar um filtro.
Além disso, o YouTube tem uma taxa de quadros máxima de 60 fps, portanto, se esse for seu objetivo final, você eliminará frames do seu arquivo de taxa de quadros variável em algum ponto da cadeia de transcodificação.
É difícil dar conselhos melhores sem ter um conhecimento mais específico do tipo de arquivo e de qual é o formato final desejado.
Dito isso, se você estiver enviando o arquivo para o YouTube, recomendo transcodificar seus arquivos e colocá-los em uma taxa de quadros estática. Você poderia fazer tudo em uma única etapa usando o filtro concatenado em vez do protocolo concatenado também - dessa forma, você não precisa produzir arquivos intermediários.
ffmpeg -i [INPUT1] -i [INPUT2] -filter_complex "[0:v] [0:a] [1:v] [1:a] concat=n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" ... [OUTPUT]
Se a qualidade é o seu objetivo principal e você não mantém seus arquivos intermediários antes de entrar no YouTube, você pode transcodificar para um formato descompactado usando -c:v rawvideo
. Os tamanhos dos arquivos serão MUITO maiores - então, novamente, sem saber mais especificamente seu objetivo final, não tenho certeza se descompactado é a melhor opção para você