From 5f8fefccaa4d8c7d83e453363279cbb6fada0717 Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 3 Nov 2022 21:03:03 -0500 Subject: [PATCH] media assets: fix .webm files not including video/audio bit rates in metadata. Fix .webm files not including the `FFmpeg:VideoBitRate` and `FFmpeg:AudioBitRate` fields in the media_metadata table. This was because the .webm format doesn't include the video or audio bit rates in the metadata, and ffprobe doesn't calculate them either, so we have to calculate them ourselves by hand. Fixup for 523d7afdd. --- app/logical/ffmpeg.rb | 79 +++++++++++++++++++++++++++----- app/logical/media_file/image.rb | 4 +- app/logical/media_file/video.rb | 7 +-- test/files/webm/test-audio.webm | Bin 0 -> 62428 bytes test/unit/media_file_test.rb | 43 ++++++++++++++++- 5 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 test/files/webm/test-audio.webm diff --git a/app/logical/ffmpeg.rb b/app/logical/ffmpeg.rb index 9ce231a8b..d5dbbc38f 100644 --- a/app/logical/ffmpeg.rb +++ b/app/logical/ffmpeg.rb @@ -11,9 +11,10 @@ class FFmpeg attr_reader :file # Operate on a file with FFmpeg. - # @param file [File, String] a webm, mp4, gif, or apng file + # + # @param file [MediaFile, String] A webm, mp4, gif, or apng file. def initialize(file) - @file = file.is_a?(String) ? File.open(file) : file + @file = file.is_a?(String) ? MediaFile.open(file) : file end # Generate a .png preview image for a video or animation. Generates @@ -38,7 +39,7 @@ class FFmpeg # # @return [Hash] A hash of the file's metadata. Will be empty if reading the file failed for any reason. def metadata - output = shell!("ffprobe -v quiet -print_format json -show_format -show_streams #{file.path.shellescape}") + output = shell!("ffprobe -v quiet -print_format json -show_format -show_streams -show_packets #{file.path.shellescape}") json = JSON.parse(output) json.with_indifferent_access rescue Error => e @@ -95,6 +96,18 @@ class FFmpeg video_stream[:codec_name] end + # @return [Integer, nil] The bit rate of the video stream, in bits per second, or nil if it can't be calculated. + def video_bit_rate + if video_stream.has_key?(:bit_rate) + video_stream[:bit_rate].to_i + # .webm doesn't have the bit rate in the metadata, so we have to calculate it from the video stream size and duration. + elsif video_size > 0 && duration > 0 + ((8.0 * video_size) / duration).to_i + else + nil + end + end + def video_stream video_streams.first || {} end @@ -107,6 +120,18 @@ class FFmpeg audio_stream[:codec_name] end + # @return [Integer, nil] The bit rate of the audio stream, in bits per second, or nil if it can't be calculated. + def audio_bit_rate + if audio_stream.has_key?(:bit_rate) + audio_stream[:bit_rate].to_i + # .webm doesn't have the bit rate in the metadata, so we have to calculate it from the audio stream size and duration. + elsif audio_size > 0 && duration > 0 + ((8.0 * audio_size) / duration).to_i + else + nil + end + end + def audio_stream audio_streams.first || {} end @@ -119,6 +144,28 @@ class FFmpeg audio_streams.present? end + def packets + metadata[:packets].to_a + end + + def video_packets + packets.select { |stream| stream[:codec_type] == "video" } + end + + def audio_packets + packets.select { |stream| stream[:codec_type] == "audio" } + end + + # @return [Integer] The size of the compressed video stream in bytes. + def video_size + video_packets.pluck("size").map(&:to_i).sum + end + + # @return [Integer] The size of the compressed audio stream in bytes. + def audio_size + audio_packets.pluck("size").map(&:to_i).sum + end + # @return [Boolean] True if the video is unplayable. def is_corrupt? error.present? @@ -129,15 +176,25 @@ class FFmpeg metadata[:error] || playback_info[:error] end - # Decode the full video and return a hash containing the frame count, fps, and runtime. + # Decode the full video and return a hash containing the frame count, fps, runtime, and the sizes of the decompressed video and audio streams. def playback_info - output = shell!("ffmpeg -i #{file.path.shellescape} -f null /dev/null") - status_line = output.lines.grep(/\Aframe=/).first.chomp + # 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") - # status_line = "frame= 10 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.48 bitrate=N/A speed= 179x" - # info = {"frame"=>"10", "fps"=>"0.0", "q"=>"-0.0", "Lsize"=>"N/A", "time"=>"00:00:00.48", "bitrate"=>"N/A", "speed"=>"188x"} - info = status_line.scan(/\S+=\s*\S+/).map { |pair| pair.split(/=\s*/) }.to_h - info.with_indifferent_access + # 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_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_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] + end.to_h + + { **time_info, **size_info }.with_indifferent_access rescue Error => e { error: e.message.strip }.with_indifferent_access end @@ -149,5 +206,5 @@ class FFmpeg output end - memoize :metadata, :playback_info, :frame_count, :duration, :error + memoize :metadata, :playback_info, :frame_count, :duration, :error, :video_size, :audio_size end diff --git a/app/logical/media_file/image.rb b/app/logical/media_file/image.rb index 9566c68d2..1b41b0f90 100644 --- a/app/logical/media_file/image.rb +++ b/app/logical/media_file/image.rb @@ -132,7 +132,7 @@ class MediaFile::Image < MediaFile def preview_frame if is_animated? - FFmpeg.new(file).smart_video_preview + FFmpeg.new(self).smart_video_preview else self end @@ -172,7 +172,7 @@ class MediaFile::Image < MediaFile end def video - FFmpeg.new(file) + FFmpeg.new(self) end memoize :image, :video, :preview_frame, :dimensions, :error, :metadata, :is_corrupt?, :is_animated_gif?, :is_animated_png? diff --git a/app/logical/media_file/video.rb b/app/logical/media_file/video.rb index b92a00c2f..4f08c8acd 100644 --- a/app/logical/media_file/video.rb +++ b/app/logical/media_file/video.rb @@ -5,7 +5,7 @@ # # @see https://github.com/streamio/streamio-ffmpeg class MediaFile::Video < MediaFile - delegate :duration, :frame_count, :frame_rate, :has_audio?, :is_corrupt?, :major_brand, :pix_fmt, :video_codec, :video_stream, :video_streams, :audio_codec, :audio_stream, :audio_streams, :error, to: :video + delegate :duration, :frame_count, :frame_rate, :has_audio?, :is_corrupt?, :major_brand, :pix_fmt, :video_codec, :video_bit_rate, :video_stream, :video_streams, :audio_codec, :audio_bit_rate, :audio_stream, :audio_streams, :error, to: :video def dimensions [video.width, video.height] @@ -23,10 +23,11 @@ class MediaFile::Video < MediaFile "FFmpeg:FrameCount" => frame_count, "FFmpeg:VideoCodec" => video_codec, "FFmpeg:VideoProfile" => video_stream[:profile], + "FFmpeg:VideoBitRate" => video_bit_rate, "FFmpeg:AudioCodec" => audio_codec, "FFmpeg:AudioProfile" => audio_stream[:profile], "FFmpeg:AudioLayout" => audio_stream[:channel_layout], - "FFmpeg:AudioBitRate" => audio_stream[:bit_rate], + "FFmpeg:AudioBitRate" => audio_bit_rate, }.compact_blank) end @@ -53,7 +54,7 @@ class MediaFile::Video < MediaFile private def video - FFmpeg.new(file) + FFmpeg.new(self) end def preview_frame diff --git a/test/files/webm/test-audio.webm b/test/files/webm/test-audio.webm new file mode 100644 index 0000000000000000000000000000000000000000..75873b637ebf88e938fcdfe55c59453523038559 GIT binary patch literal 62428 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 lYnVzGwJ_c-+q=FuGJb4gUiYDq2LQK142A#z literal 0 HcmV?d00001 diff --git a/test/unit/media_file_test.rb b/test/unit/media_file_test.rb index b54636340..4974fefe0 100644 --- a/test/unit/media_file_test.rb +++ b/test/unit/media_file_test.rb @@ -200,18 +200,36 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal(false, MediaFile.open("test/files/mp4/test-300x300.mp4").has_audio?) end - should "determine the duration of the video" do + should "determine the metadata for a video with audio" do file = MediaFile.open("test/files/mp4/test-audio.mp4") assert_equal(false, file.is_corrupt?) assert_equal(1.002667, file.duration) assert_equal(10/1.002667, file.frame_rate) assert_equal(10, file.frame_count) + assert_equal(10, file.metadata["FFmpeg:FrameCount"]) + assert_equal("mp42", file.metadata["FFmpeg:MajorBrand"]) + assert_equal("yuv420p", file.metadata["FFmpeg:PixFmt"]) + assert_equal("h264", file.metadata["FFmpeg:VideoCodec"]) + assert_equal("High", file.metadata["FFmpeg:VideoProfile"]) + assert_equal(291624, file.metadata["FFmpeg:VideoBitRate"]) + assert_equal("aac", file.metadata["FFmpeg:AudioCodec"]) + assert_equal("LC", file.metadata["FFmpeg:AudioProfile"]) + assert_equal("stereo", file.metadata["FFmpeg:AudioLayout"]) + assert_equal(128002, file.metadata["FFmpeg:AudioBitRate"]) + end + should "determine the metadata for a video without audio" do file = MediaFile.open("test/files/mp4/test-300x300.mp4") assert_equal(false, file.is_corrupt?) assert_equal(5.7, file.duration) assert_equal(1.75, file.frame_rate.round(2)) assert_equal(10, file.frame_count) + assert_equal(10, file.metadata["FFmpeg:FrameCount"]) + assert_equal("mp42", file.metadata["FFmpeg:MajorBrand"]) + assert_equal("yuv420p", file.metadata["FFmpeg:PixFmt"]) + assert_equal("h264", file.metadata["FFmpeg:VideoCodec"]) + assert_equal("Constrained Baseline", file.metadata["FFmpeg:VideoProfile"]) + assert_equal(25003, file.metadata["FFmpeg:VideoBitRate"]) end should "determine the pixel format of the video" do @@ -251,11 +269,32 @@ class MediaFileTest < ActiveSupport::TestCase end context "for a webm file" do - should "determine the duration of the video" do + should "determine the metadata for a video with audio" do + file = MediaFile.open("test/files/webm/test-audio.webm") + + assert_equal(1.01, file.duration) # 1.01 + assert_equal(10/1.01, file.frame_rate) + assert_equal(10, file.frame_count) + assert_equal(10, file.metadata["FFmpeg:FrameCount"]) + assert_equal("yuv420p", file.metadata["FFmpeg:PixFmt"]) + assert_equal("vp9", file.metadata["FFmpeg:VideoCodec"]) + assert_equal("Profile 0", file.metadata["FFmpeg:VideoProfile"]) + assert_equal(432546, file.metadata["FFmpeg:VideoBitRate"]) + assert_equal("opus", file.metadata["FFmpeg:AudioCodec"]) + assert_equal("stereo", file.metadata["FFmpeg:AudioLayout"]) + assert_equal(50661, file.metadata["FFmpeg:AudioBitRate"]) + end + + should "determine the metadata for a video without audio" do file = MediaFile.open("test/files/webm/test-512x512.webm") assert_equal(0.48, file.duration) assert_equal(10/0.48, file.frame_rate) assert_equal(10, file.frame_count) + assert_equal(10, file.metadata["FFmpeg:FrameCount"]) + assert_equal("yuv420p", file.metadata["FFmpeg:PixFmt"]) + assert_equal("vp8", file.metadata["FFmpeg:VideoCodec"]) + assert_equal("0", file.metadata["FFmpeg:VideoProfile"]) + assert_equal(196650, file.metadata["FFmpeg:VideoBitRate"]) end should "detect supported files" do