Fall back to video container for duration
Some video formats, such as WebM, do not store duration information at the level of the video stream. Instead, the duration is stored as part of the container format information. This commit modifies `VideoAnalyzer` to use the duration from the video container when the duration from the video stream is not available. Fixes #40130.
This commit is contained in:
parent
57da1d0188
commit
a197d39e13
@ -44,7 +44,8 @@ def height
|
||||
end
|
||||
|
||||
def duration
|
||||
Float(video_stream["duration"]) if video_stream["duration"]
|
||||
duration = video_stream["duration"] || container["duration"]
|
||||
Float(duration) if duration
|
||||
end
|
||||
|
||||
def angle
|
||||
@ -98,12 +99,22 @@ def streams
|
||||
probe["streams"] || []
|
||||
end
|
||||
|
||||
def container
|
||||
probe["format"] || {}
|
||||
end
|
||||
|
||||
def probe
|
||||
download_blob_to_tempfile { |file| probe_from(file) }
|
||||
@probe ||= download_blob_to_tempfile { |file| probe_from(file) }
|
||||
end
|
||||
|
||||
def probe_from(file)
|
||||
IO.popen([ ffprobe_path, "-print_format", "json", "-show_streams", "-v", "error", file.path ]) do |output|
|
||||
IO.popen([ ffprobe_path,
|
||||
"-print_format", "json",
|
||||
"-show_streams",
|
||||
"-show_format",
|
||||
"-v", "error",
|
||||
file.path
|
||||
]) do |output|
|
||||
JSON.parse(output.read)
|
||||
end
|
||||
rescue Errno::ENOENT
|
||||
|
@ -45,9 +45,21 @@ class ActiveStorage::Analyzer::VideoAnalyzerTest < ActiveSupport::TestCase
|
||||
assert_nil metadata[:display_aspect_ratio]
|
||||
end
|
||||
|
||||
test "analyzing a video with a container-specified duration" do
|
||||
blob = create_file_blob(filename: "video.webm", content_type: "video/webm")
|
||||
metadata = extract_metadata_from(blob)
|
||||
|
||||
assert_equal 640, metadata[:width]
|
||||
assert_equal 480, metadata[:height]
|
||||
assert_equal 5.229000, metadata[:duration]
|
||||
end
|
||||
|
||||
test "analyzing a video without a video stream" do
|
||||
blob = create_file_blob(filename: "video_without_video_stream.mp4", content_type: "video/mp4")
|
||||
metadata = extract_metadata_from(blob)
|
||||
assert_equal({ "analyzed" => true, "identified" => true }, metadata)
|
||||
|
||||
assert_not_includes metadata, :width
|
||||
assert_not_includes metadata, :height
|
||||
assert_equal 1.022000, metadata[:duration]
|
||||
end
|
||||
end
|
||||
|
BIN
activestorage/test/fixtures/files/video.webm
vendored
Normal file
BIN
activestorage/test/fixtures/files/video.webm
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user