Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge pull request #45837 from hahmed/ha/active-storage-fix-rotation-… #48558

Merged
merged 1 commit into from Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions activestorage/CHANGELOG.md
@@ -1,3 +1,12 @@
* Fix retrieving rotation value from FFmpeg on version 5.0+.

In FFmpeg version 5.0+ the rotation value has been removed from tags.
Instead the value can be found in side_data_list. Along with
this update it's possible to have values of -90, -270 to denote the video
has been rotated.

*Haroon Ahmed*

## Rails 7.0.5 (May 24, 2023) ##

* No changes.
Expand Down
15 changes: 11 additions & 4 deletions activestorage/lib/active_storage/analyzer/video_analyzer.rb
Expand Up @@ -16,7 +16,7 @@ module ActiveStorage
# ActiveStorage::Analyzer::VideoAnalyzer.new(blob).metadata
# # => { width: 640.0, height: 480.0, duration: 5.0, angle: 0, display_aspect_ratio: [4, 3], audio: true, video: true }
#
# When a video's angle is 90 or 270 degrees, its width and height are automatically swapped for convenience.
# When a video's angle is 90, -90, 270 or -270 degrees, its width and height are automatically swapped for convenience.
#
# This analyzer requires the {FFmpeg}[https://www.ffmpeg.org] system library, which is not provided by Rails.
class Analyzer::VideoAnalyzer < Analyzer
Expand Down Expand Up @@ -51,7 +51,11 @@ def duration
end

def angle
Integer(tags["rotate"]) if tags["rotate"]
if tags["rotate"]
Integer(tags["rotate"])
elsif side_data && side_data[0] && side_data[0]["rotation"]
Integer(side_data[0]["rotation"])
end
end

def display_aspect_ratio
Expand All @@ -66,7 +70,7 @@ def display_aspect_ratio
end

def rotated?
angle == 90 || angle == 270
angle == 90 || angle == 270 || angle == -90 || angle == -270
end

def audio?
Expand Down Expand Up @@ -95,11 +99,14 @@ def display_height_scale
@display_height_scale ||= Float(display_aspect_ratio.last) / display_aspect_ratio.first if display_aspect_ratio
end


def tags
@tags ||= video_stream["tags"] || {}
end

def side_data
@side_data ||= video_stream["side_data_list"] || {}
end

def video_stream
@video_stream ||= streams.detect { |stream| stream["codec_type"] == "video" } || {}
end
Expand Down
2 changes: 1 addition & 1 deletion activestorage/test/analyzer/video_analyzer_test.rb
Expand Up @@ -26,7 +26,7 @@ class ActiveStorage::Analyzer::VideoAnalyzerTest < ActiveSupport::TestCase
assert_equal 480, metadata[:width]
assert_equal 640, metadata[:height]
assert_equal [4, 3], metadata[:display_aspect_ratio]
assert_equal 90, metadata[:angle]
assert_includes [90, -90], metadata[:angle]
end

test "analyzing a video with rectangular samples" do
Expand Down