From cb35bad2376b31933d9e78f0bdad1b08e18addd7 Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 3 Nov 2022 22:01:51 -0500 Subject: [PATCH] media assets: fix incorrect frame counts for certain .webm files. Fix calculating incorrect frame counts for certain .webm files. An example is https://danbooru.donmai.us/media_assets/5968481. Caused by ffmpeg printing multiple `frame= NNN` lines, and us taking the first one instead of the last one: frame= 1 fps=0.0 q=-0.0 size=N/A time=00:00:00.08 bitrate=N/A speed=2.07x [null @ 0x56046ff4e440] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 321 >= 321 [null @ 0x56046ff4e440] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 321 >= 321 frame= 395 fps=0.0 q=-0.0 size=N/A time=00:00:06.66 bitrate=N/A speed=12.3x frame= 791 fps=759 q=-0.0 size=N/A time=00:00:13.26 bitrate=N/A speed=12.7x frame= 1193 fps=772 q=-0.0 size=N/A time=00:00:19.94 bitrate=N/A speed=12.9x frame= 1374 fps=780 q=-0.0 Lsize=N/A time=00:00:22.86 bitrate=N/A speed= 13x video:719kB audio:4288kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown --- app/logical/ffmpeg.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/logical/ffmpeg.rb b/app/logical/ffmpeg.rb index d5dbbc38f..0ee773a29 100644 --- a/app/logical/ffmpeg.rb +++ b/app/logical/ffmpeg.rb @@ -180,15 +180,16 @@ class FFmpeg def playback_info # XXX `-c copy` is faster, but it doesn't decompress the stream so it can't detect corrupt videos. output = shell!("ffmpeg -hide_banner -i #{file.path.shellescape} -f null /dev/null") + lines = output.split(/\r\n|\r|\n/) # time_line = "frame= 10 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.48 bitrate=N/A speed= 179x" # time_info = { "frame"=>"10", "fps"=>"0.0", "q"=>"-0.0", "Lsize"=>"N/A", "time"=>"00:00:00.48", "bitrate"=>"N/A", "speed"=>"188x" } - time_line = output.lines.grep(/\Aframe=/).first.chomp + time_line = lines.grep(/\Aframe=/).last.strip time_info = time_line.scan(/\S+=\s*\S+/).map { |pair| pair.split(/=\s*/) }.to_h # size_line = "video:36kBkB audio:16kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown" # size_info = { "video" => 36000, "audio" => 16000, "subtitle" => 0, "other streams" => 0, "global headers" => 0, "muxing overhead" => 0 } - size_line = output.lines.grep(/\Avideo:/).first.chomp + size_line = lines.grep(/\Avideo:/).last.strip size_info = size_line.scan(/[a-z ]+: *[a-z0-9]+/i).map do |pair| key, value = pair.split(/: */) [key.strip, value.to_i * 1000] # [" audio", "16kB"] => ["audio", 16000]