aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage/lib/active_storage/analyzer
diff options
context:
space:
mode:
authorGeorge Claghorn <george@basecamp.com>2018-01-19 10:47:18 -0500
committerGeorge Claghorn <george@basecamp.com>2018-01-19 10:47:34 -0500
commit2450fc24e30121863403517b44dfdfa7cb25e33a (patch)
tree79219c87c1c317d0a6c99071959726f88fb65e1f /activestorage/lib/active_storage/analyzer
parentacbcef6094d61eb8c4820295620d170743a4bd71 (diff)
downloadrails-2450fc24e30121863403517b44dfdfa7cb25e33a.tar.gz
rails-2450fc24e30121863403517b44dfdfa7cb25e33a.tar.bz2
rails-2450fc24e30121863403517b44dfdfa7cb25e33a.zip
Preserve display aspect ratio for videos with rectangular samples
Diffstat (limited to 'activestorage/lib/active_storage/analyzer')
-rw-r--r--activestorage/lib/active_storage/analyzer/video_analyzer.rb50
1 files changed, 35 insertions, 15 deletions
diff --git a/activestorage/lib/active_storage/analyzer/video_analyzer.rb b/activestorage/lib/active_storage/analyzer/video_analyzer.rb
index aa532da201..f0d9baa199 100644
--- a/activestorage/lib/active_storage/analyzer/video_analyzer.rb
+++ b/activestorage/lib/active_storage/analyzer/video_analyzer.rb
@@ -9,12 +9,12 @@ module ActiveStorage
# * Height (pixels)
# * Duration (seconds)
# * Angle (degrees)
- # * Aspect ratio
+ # * Display aspect ratio
#
# Example:
#
# ActiveStorage::VideoAnalyzer.new(blob).metadata
- # # => { width: 640, height: 480, duration: 5.0, angle: 0, aspect_ratio: [4, 3] }
+ # # => { width: 640.0, height: 480.0, duration: 5.0, angle: 0, display_aspect_ratio: [4, 3] }
#
# When a video's angle is 90 or 270 degrees, its width and height are automatically swapped for convenience.
#
@@ -25,24 +25,24 @@ module ActiveStorage
end
def metadata
- { width: width, height: height, duration: duration, angle: angle, aspect_ratio: aspect_ratio }.compact
+ { width: width, height: height, duration: duration, angle: angle, display_aspect_ratio: display_aspect_ratio }.compact
end
private
def width
- rotated? ? raw_height : raw_width
+ if rotated?
+ computed_height || encoded_height
+ else
+ encoded_width
+ end
end
def height
- rotated? ? raw_width : raw_height
- end
-
- def raw_width
- Integer(video_stream["width"]) if video_stream["width"]
- end
-
- def raw_height
- Integer(video_stream["height"]) if video_stream["height"]
+ if rotated?
+ encoded_width
+ else
+ computed_height || encoded_height
+ end
end
def duration
@@ -53,16 +53,36 @@ module ActiveStorage
Integer(tags["rotate"]) if tags["rotate"]
end
- def aspect_ratio
+ def display_aspect_ratio
if descriptor = video_stream["display_aspect_ratio"]
- descriptor.split(":", 2).collect(&:to_i)
+ terms = descriptor.split(":", 2).collect(&:to_i)
+ terms if terms.count == 2 && terms.min >= 0
end
end
+
def rotated?
angle == 90 || angle == 270
end
+ def computed_height
+ if encoded_width && display_height_scale
+ encoded_width * display_height_scale
+ end
+ end
+
+ def encoded_width
+ @encoded_width ||= Float(video_stream["width"]) if video_stream["width"]
+ end
+
+ def encoded_height
+ @encoded_height ||= Float(video_stream["height"]) if video_stream["height"]
+ end
+
+ 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"] || {}