
Estoy usando ffmpeg
para agregar 2 marcas de agua en un video.
Funciona bien, a las mil maravillas. Solo tengo este pequeño problema: ffmpeg
no dejo de codificar a menos que presione CTRL+Cpara salir del proceso. Aquí está mi comando:
/usr/bin/ffmpeg -i /home/twinuts/sd/videobot/www/in.mp4 -y /
-loop 1 -i /home/twinuts/sd/videobot/www/outro.png /
-loop 1 -i /home/twinuts/sd/videobot/www/newlayer.png /
-filter_complex "[1:v]fade=t=in:st=7:d=1:alpha=1[wm]; /
[2:v]fade=t=out:st=7:d=1:alpha=1[wm2]; /
[0:v][wm]overlay[v];[v][wm2]overlay" /
-codec:v libx264 -codec:a libfdk_aac /
/home/twinuts/sd/videobot/www/videos/newvideo.avi
Aquí está mi consola de salida:
ffmpeg version git-2015-09-06-db18b3d Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-16)
configuration: --prefix=/usr/ffmpeg_build --extra-cflags=-I/usr/ffmpeg_build/include --extra-ldflags=-L/usr/ffmpeg_build/lib --bindir=/usr/bin --pkg-config-flags=--static --enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265
libavutil 55. 0.100 / 55. 0.100
libavcodec 57. 0.100 / 57. 0.100
libavformat 57. 0.100 / 57. 0.100
libavdevice 57. 0.100 / 57. 0.100
libavfilter 6. 0.100 / 6. 0.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.100 / 2. 0.100
libpostproc 54. 0.100 / 54. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/twinuts/sd/videobot/www/in.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.0.100
Duration: 00:00:10.05, start: 0.046440, bitrate: 1607 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1477 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
Input #1, png_pipe, from '/home/twinuts/sd/videobot/www/outro.png':
Duration: N/A, bitrate: N/A
Stream #1:0: Video: png, rgb24(pc), 1280x720, 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #2, png_pipe, from '/home/twinuts/sd/videobot/www/newlayer.png':
Duration: N/A, bitrate: N/A
Stream #2:0: Video: png, rgba(pc), 1280x720, 25 fps, 25 tbr, 25 tbn, 25 tbc
[libx264 @ 0x4afb4a0] using SAR=1/1
[libx264 @ 0x4afb4a0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 0x4afb4a0] profile High, level 3.1
Output #0, avi, to '/home/twinuts/sd/videobot/www/videos/newvideo.avi':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
ISFT : Lavf57.0.100
Stream #0:0: Video: h264 (libx264) (H264 / 0x34363248), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=-1--1, 25 fps, 25 tbn, 25 tbc (default)
Metadata:
encoder : Lavc57.0.100 libx264
Stream #0:1(und): Audio: aac (libfdk_aac) ([255][0][0][0] / 0x00FF), 44100 Hz, stereo, s16, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
encoder : Lavc57.0.100 libfdk_aac
Stream mapping:
Stream #0:0 (h264) -> overlay:main (graph 0)
Stream #1:0 (png) -> fade (graph 0)
Stream #2:0 (png) -> fade (graph 0)
overlay (graph 0) -> Stream #0:0 (libx264)
Stream #0:1 -> #0:1 (aac (native) -> aac (libfdk_aac))
Press [q] to stop, [?] for help
Past duration 0.839836 too large 1475kB time=00:00:10.00 bitrate=1207.7kbits/s
frame= 251 fps= 23 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=110 frame= 251 fps= 22 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=143 frame= 251 fps= 21 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=176 frame= 251 fps= 20 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=201 frame= 251 fps= 20 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=222 frame= 251 fps= 19 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=254 frame= 251 fps= 18 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=287 frame= 251 fps= 18 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=319 frame= 251 fps= 17 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=352 frame= 251 fps= 16 q=28.0 size= 1504kB time=00:00:10.00 bitrate=1230.9kbits/s dup=0 drop=385 frame= 251 fps= 16 q=-1.0 Lsize= 1580kB time=00:00:10.05 bitrate=1287.7kbits/s dup=0 drop=392
video:1395kB audio:159kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.686170%
[libx264 @ 0x4afb4a0] frame I:2 Avg QP:18.98 size: 35646
[libx264 @ 0x4afb4a0] frame P:109 Avg QP:20.17 size: 9465
[libx264 @ 0x4afb4a0] frame B:140 Avg QP:20.37 size: 2329
[libx264 @ 0x4afb4a0] consecutive B-frames: 15.9% 23.9% 15.5% 44.6%
[libx264 @ 0x4afb4a0] mb I I16..4: 20.7% 56.8% 22.5%
[libx264 @ 0x4afb4a0] mb P I16..4: 9.9% 12.2% 0.4% P16..4: 42.1% 6.4% 1.7% 0.0% 0.0% skip:27.3%
[libx264 @ 0x4afb4a0] mb B I16..4: 0.7% 0.5% 0.0% B16..8: 25.7% 1.0% 0.0% direct: 1.9% skip:70.2% L0:41.5% L1:56.8% BI: 1.7%
[libx264 @ 0x4afb4a0] 8x8 transform intra:53.7% inter:90.7%
[libx264 @ 0x4afb4a0] coded y,uvDC,uvAC intra: 19.7% 62.5% 15.3% inter: 5.2% 20.7% 0.1%
[libx264 @ 0x4afb4a0] i16 v,h,dc,p: 38% 23% 15% 23%
[libx264 @ 0x4afb4a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 36% 16% 32% 2% 3% 3% 3% 2% 2%
[libx264 @ 0x4afb4a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 39% 21% 16% 3% 6% 6% 4% 3% 2%
[libx264 @ 0x4afb4a0] i8c dc,h,v,p: 62% 16% 19% 3%
[libx264 @ 0x4afb4a0] Weighted P-Frames: Y:19.3% UV:19.3%
[libx264 @ 0x4afb4a0] ref P L0: 79.2% 7.0% 11.3% 2.3% 0.1%
[libx264 @ 0x4afb4a0] ref B L0: 91.4% 8.0% 0.6%
[libx264 @ 0x4afb4a0] ref B L1: 96.7% 3.3%
[libx264 @ 0x4afb4a0] kb/s:1138.61
[root@xxx ~]#
Supongo que tiene que ver con que la velocidad de fotogramas PNG no es la misma que la del mp4 (en negrita, en realidad), pero se agradecería cualquier sugerencia.
Respuesta1
¿Por qué ffmpeg
mi video se procesa para siempre?
Lo que sucede es que ffmpeg
llega al final de una de tus entradas (el video), pero continúa codificando porque otras entradas (en este caso, tus imágenes, configuradas en -loop 1
) todavía están en marcha. Esto da como resultado fotogramas eliminados hasta que finalice ffmpeg
manualmente con qo
Ctrl+C:
... drop=110
... drop=143
... drop=176
... drop=201
... drop=222
...
... drop=385
... drop=392
¿Cómo le digo ffmpeg
que use el segmento de video más corto?
Dependiendo de la entrada y el flujo de trabajo, hay dos opciones.
Puedes utilizar la -shortest
opción (desdeffmpeg
documentación):
-shortest (output) Finish encoding when the shortest input stream ends.
o utilice el shortest
parámetro para el overlay
filtro (desde eldocumentación de filtros):
shortest If set to 1, force the output to terminate when the shortest input terminates. Default value is 0.
Estoy superponiendo dos marcas de agua usando el overlay
filtro...
En este caso, dado que está usando filter_complex
para administrar entradas, usaría overlay
la shortest
opción; entonces tu comando se convierte en:
/usr/bin/ffmpeg -i /home/twinuts/sd/videobot/www/in.mp4 -y /
-loop 1 -i /home/twinuts/sd/videobot/www/outro.png /
-loop 1 -i /home/twinuts/sd/videobot/www/newlayer.png /
-filter_complex "[1:v]fade=t=in:st=7:d=1:alpha=1[wm]; /
[2:v]fade=t=out:st=7:d=1:alpha=1[wm2]; /
[0:v][wm]overlay=shortest=1[v];[v][wm2]overlay=shortest=1" /
-codec:v libx264 -codec:a libfdk_aac /
/home/twinuts/sd/videobot/www/videos/newvideo.avi
que luego termina cuando in.mp4
termina.