I'm testing out the "blackdetect" filter in ffmpeg. I want to have the times when the video is black to be read by a script (like actionscript or javascript). I tried:
ffmpeg -i video1.mp4 -vf "blackdetect=d=2:pix_th=0.00" -an -f null -
And I get a nice result in the ffmpeg log:
ffmpeg version N-55644-g68b63a3 Copyright (c) 2000-2013 the FFmpeg developers
built on Aug 19 2013 20:32:00 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-av
isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enab
le-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetyp
e --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --ena
ble-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libsp
eex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-
amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --
enable-libxvid --enable-zlib
libavutil 52. 42.100 / 52. 42.100
libavcodec 55. 28.100 / 55. 28.100
libavformat 55. 13.103 / 55. 13.103
libavdevice 55. 3.100 / 55. 3.100
libavfilter 3. 82.100 / 3. 82.100
libswscale 2. 5.100 / 2. 5.100
libswresample 0. 17.103 / 0. 17.103
libpostproc 52. 3.100 / 52. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video1.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
creation_time : 1970-01-01 00:00:00
encoder : Lavf53.13.0
Duration: 00:02:01.54, start: 0.000000, bitrate: 275 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 768x432 [
SAR 1:1 DAR 16:9], 211 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc
Metadata:
creation_time : 1970-01-01 00:00:00
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 59
kb/s
Metadata:
creation_time : 1970-01-01 00:00:00
handler_name : SoundHandler
Output #0, null, to 'pipe:':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf55.13.103
Stream #0:0(eng): Video: rawvideo (I420 / 0x30323449), yuv420p, 768x432 [SAR
1:1 DAR 16:9], q=2-31, 200 kb/s, 90k tbn, 25 tbc
Metadata:
creation_time : 1970-01-01 00:00:00
handler_name : VideoHandler
Stream mapping:
Stream #0:0 -> #0:0 (h264 -> rawvideo)
Press [q] to stop, [?] for help
[null @ 00000000003279a0] Encoder did not produce proper pts, making some up.
[blackdetect @ 0000000004d5e800] black_start:0 black_end:17.08 black_duration:17
.08
[blackdetect @ 0000000004d5e800] black_start:62.32 black_end:121.48 black_durati
on:59.16
frame= 3038 fps=2317 q=0.0 Lsize=N/A time=00:02:01.52 bitrate=N/A
video:285kB audio:0kB subtitle:0 global headers:0kB muxing overhead -100.007543%
And I'm particularly interested in this part:
[blackdetect @ 0000000004e2e340] black_start:0 black_end:17.08 black_duration:17.08
[blackdetect @ 0000000004e2e340] black_start:62.32 black_end:121.48 black_duration:59.16
So my question:
example:
ffmpeg -f concat -i mylist.txt -c copy concat.mp4
Where mylist.txt is a list of videos:
file 'video1.mp4'
file 'video2.mp4'
file 'video3.mp4'
file 'video4.mp4'
Basically what I want to have is one or more text files containing information about the black frames in every video in this list to be used by another program
If using ffprobe
is acceptable there is now a simpler way to do it with metadata injection:
ffprobe -f lavfi -i "movie=input.mp4,blackdetect[out0]" -show_entries tags=lavfi.black_start,lavfi.black_end -of default=nw=1 -v quiet
The command outputs only the lavfi
tags black_start
and black_end
.
The advantage is you can also get frame information etc, or multiple tags in a format which is easier to parse.
ffprobe
can also output JSON or XML but I can't find a way to skip the frames with no tags which produce empty nodes. This should be easy to patch though.
Is there a way to only take the blackdetect filter output and put it in a .txt file?
By default ffmpeg logs to stderr. You can output to stdout
and then use grep
to isolate the blackdetect
lines:
$ ffmpeg -i video1.mp4 -vf "blackdetect=d=2:pix_th=0.00" -an -f null - 2>&1 | grep blackdetect > output.txt
Resulting in:
$ cat output.txt
[blackdetect @ 0x1d2b980] black_start:5.16 black_end:10.24 black_duration:5.08
If you want to append to output.txt
instead of overwriting for each instance then use >>
instead of >
, as in: blackdetect >> output.txt
.
Is there a way to do this in a statement with multiple video inputs?
You can use blackdetect
with the concat
demuxer as shown in your question, but be aware that the black_start
and black_end
times will be cumulative, and not independent to each input, because you are concatenating all inputs.
Alternatively you can use a bash "for loop" if you want each input to be independently run through blackdetect
:
for f in *.mp4; do ffmpeg -i "$f" -vf "blackdetect=d=2:pix_th=0.00" -an -f null - 2>&1 | grep blackdetect > "$f".txt; done
This may create empty txt files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With