Class: ActiveStorage::Analyzer::VideoAnalyzer
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Inherits: |
ActiveStorage::Analyzer
|
Defined in: | activestorage/lib/active_storage/analyzer/video_analyzer.rb |
Overview
Active Storage Video Analyzer
Extracts the following from a video blob:
-
Width (pixels)
-
Height (pixels)
-
Duration (seconds)
-
Angle (degrees)
-
Display aspect ratio
-
Audio (true if file has an audio channel, false if not)
-
Video (true if file has an video channel, false if not)
Example:
ActiveStorage::Analyzer::VideoAnalyzer.new(blob).
# => { 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, -90, 270 or -270 degrees, its width and height are automatically swapped for convenience.
This analyzer requires the FFmpeg system library, which is not provided by Rails.
Class Attribute Summary
::ActiveStorage::Analyzer
- Inherited
.analyze_later? | Implement this method in concrete subclasses. |
Class Method Summary
::ActiveStorage::Analyzer
- Inherited
Instance Attribute Summary
- #audio? ⇒ Boolean readonly private
- #rotated? ⇒ Boolean readonly private
- #video? ⇒ Boolean readonly private
::ActiveStorage::Analyzer
- Inherited
Instance Method Summary
- #metadata
- #angle private
- #audio_stream private
- #computed_height private
- #container private
- #display_aspect_ratio private
- #display_height_scale private
- #display_matrix private
- #duration private
- #encoded_height private
- #encoded_width private
- #ffprobe_path private
- #height private
- #probe private
- #probe_from(file) private
- #side_data private
- #streams private
- #tags private
- #video_stream private
- #width private
::ActiveStorage::Analyzer
- Inherited
#metadata | Override this method in a concrete subclass. |
#download_blob_to_tempfile | Downloads the blob to a tempfile on disk. |
#instrument, #logger, #tmpdir |
Constructor Details
This class inherits a constructor from ActiveStorage::Analyzer
Class Method Details
.accept?(blob) ⇒ Boolean
Instance Attribute Details
#audio? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 82
def audio? audio_stream.present? end
#rotated? ⇒ Boolean
(readonly, private)
[ GitHub ]
#video? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 86
def video? video_stream.present? end
Instance Method Details
#angle (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 55
def angle if ["rotate"] Integer( ["rotate"]) elsif display_matrix && display_matrix["rotation"] Integer(display_matrix["rotation"]) end end
#audio_stream (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 120
def audio_stream @audio_stream ||= streams.detect { |stream| stream["codec_type"] == "audio" } || {} end
#computed_height (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 90
def computed_height if encoded_width && display_height_scale encoded_width * display_height_scale end end
#container (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 128
def container probe["format"] || {} end
#display_aspect_ratio (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 67
def display_aspect_ratio if descriptor = video_stream["display_aspect_ratio"] if terms = descriptor.split(":", 2) numerator = Integer(terms[0]) denominator = Integer(terms[1]) [numerator, denominator] unless numerator == 0 end end end
#display_height_scale (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 104
def display_height_scale @display_height_scale ||= Float(display_aspect_ratio.last) / display_aspect_ratio.first if display_aspect_ratio end
#display_matrix (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 63
def display_matrix side_data.detect { |data| data["side_data_type"] == "Display Matrix" } end
#duration (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 50
def duration duration = video_stream["duration"] || container["duration"] Float(duration) if duration end
#encoded_height (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 100
def encoded_height @encoded_height ||= Float(video_stream["height"]) if video_stream["height"] end
#encoded_width (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 96
def encoded_width @encoded_width ||= Float(video_stream["width"]) if video_stream["width"] end
#ffprobe_path (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 153
def ffprobe_path ActiveStorage.paths[:ffprobe] || "ffprobe" end
#height (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 42
def height if rotated? encoded_width else computed_height || encoded_height end end
#metadata
[ GitHub ]#probe (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 132
def probe @probe ||= download_blob_to_tempfile { |file| probe_from(file) } end
#probe_from(file) (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 136
def probe_from(file) instrument(File.basename(ffprobe_path)) do IO.popen([ ffprobe_path, "-print_format", "json", "-show_streams", "-show_format", "-v", "error", file.path ]) do |output| JSON.parse(output.read) end end rescue Errno::ENOENT logger.info "Skipping video analysis because ffprobe isn't installed" {} end
#side_data (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 112
def side_data @side_data ||= video_stream["side_data_list"] || {} end
#streams (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 124
def streams probe["streams"] || [] end
#tags (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 108
def @tags ||= video_stream["tags"] || {} end
#video_stream (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 116
def video_stream @video_stream ||= streams.detect { |stream| stream["codec_type"] == "video" } || {} end
#width (private)
[ GitHub ]# File 'activestorage/lib/active_storage/analyzer/video_analyzer.rb', line 34
def width if rotated? computed_height || encoded_height else encoded_width end end