Skip to content

Commit 7de6670

Browse files
authored
Merge pull request rails#45837 from hahmed/ha/active-storage-fix-rotation-test-failing
FFmpeg (5.0+) has updated the tag where rotation info is retrieved from
2 parents 5b8421f + 206a826 commit 7de6670

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

activestorage/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
* Fix retrieving rotation value from FFmpeg on version 5.0+.
2+
3+
In FFmpeg version 5.0+ the rotation value has been removed from tags.
4+
Instead the value can be found in side_data_list. Along with
5+
this update it's possible to have values of -90, -270 to denote the video
6+
has been rotated.
7+
8+
*Haroon Ahmed*
9+
110
* Touch all corresponding model records after ActiveStorage::Blob is analyzed
211

312
This fixes a race condition where a record can be requested and have a cache entry built, before

activestorage/lib/active_storage/analyzer/video_analyzer.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module ActiveStorage
1616
# ActiveStorage::Analyzer::VideoAnalyzer.new(blob).metadata
1717
# # => { width: 640.0, height: 480.0, duration: 5.0, angle: 0, display_aspect_ratio: [4, 3], audio: true, video: true }
1818
#
19-
# When a video's angle is 90 or 270 degrees, its width and height are automatically swapped for convenience.
19+
# When a video's angle is 90, -90, 270 or -270 degrees, its width and height are automatically swapped for convenience.
2020
#
2121
# This analyzer requires the {FFmpeg}[https://www.ffmpeg.org] system library, which is not provided by Rails.
2222
class Analyzer::VideoAnalyzer < Analyzer
@@ -51,7 +51,11 @@ def duration
5151
end
5252

5353
def angle
54-
Integer(tags["rotate"]) if tags["rotate"]
54+
if tags["rotate"]
55+
Integer(tags["rotate"])
56+
elsif side_data && side_data[0] && side_data[0]["rotation"]
57+
Integer(side_data[0]["rotation"])
58+
end
5559
end
5660

5761
def display_aspect_ratio
@@ -66,7 +70,7 @@ def display_aspect_ratio
6670
end
6771

6872
def rotated?
69-
angle == 90 || angle == 270
73+
angle == 90 || angle == 270 || angle == -90 || angle == -270
7074
end
7175

7276
def audio?
@@ -95,11 +99,14 @@ def display_height_scale
9599
@display_height_scale ||= Float(display_aspect_ratio.last) / display_aspect_ratio.first if display_aspect_ratio
96100
end
97101

98-
99102
def tags
100103
@tags ||= video_stream["tags"] || {}
101104
end
102105

106+
def side_data
107+
@side_data ||= video_stream["side_data_list"] || {}
108+
end
109+
103110
def video_stream
104111
@video_stream ||= streams.detect { |stream| stream["codec_type"] == "video" } || {}
105112
end

activestorage/test/analyzer/video_analyzer_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ActiveStorage::Analyzer::VideoAnalyzerTest < ActiveSupport::TestCase
2626
assert_equal 480, metadata[:width]
2727
assert_equal 640, metadata[:height]
2828
assert_equal [4, 3], metadata[:display_aspect_ratio]
29-
assert_equal 90, metadata[:angle]
29+
assert_includes [90, -90], metadata[:angle]
3030
end
3131

3232
test "analyzing a video with rectangular samples" do

0 commit comments

Comments
 (0)