Module: FastlaneCore::VideoUtils
- Defined in:
- fastlane_core/lib/fastlane_core/video_utils.rb
Class Method Summary collapse
-
.read_video_duration_seconds(path) ⇒ Object
Pure Ruby MP4/QuickTime MOV container header parser reading mvhd to get duration in seconds.
-
.read_video_resolution(path) ⇒ Object
Pure Ruby MP4/QuickTime MOV container header parser, reading tkhd to get width/height.
Class Method Details
.read_video_duration_seconds(path) ⇒ Object
Pure Ruby MP4/QuickTime MOV container header parser reading mvhd to get duration in seconds. Note: Uses movie header (mvhd) time scale/duration, not per-track edit lists; adequate for gating. Input: path (String) to a local MP4/MOV file. Output: duration in seconds (Float), or nil on failure.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'fastlane_core/lib/fastlane_core/video_utils.rb', line 40 def self.read_video_duration_seconds(path) File.open(path, "rb") do |f| file_size = f.size while f.pos < file_size size, type = read_atom_header(f) break unless size && type return nil if size < 8 content = size - 8 if type == "moov" moov_end = f.pos + content duration = extract_duration_from_moov(f, moov_end) return duration if duration else skip(f, content) end end end nil rescue => e FastlaneCore::UI.verbose("Failed to parse duration for '#{path}': #{e.class} - #{e.}") nil end |
.read_video_resolution(path) ⇒ Object
Pure Ruby MP4/QuickTime MOV container header parser, reading tkhd to get width/height. Note: This reads container atoms/boxes only; it does NOT parse the video codec bitstream. Works regardless of codec as long as standard container headers exist. Input: path (String) to a local MP4/MOV file. Output: [width, height] (Array<Integer>) normalized to portrait (w <= h), or nil on failure.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'fastlane_core/lib/fastlane_core/video_utils.rb', line 13 def self.read_video_resolution(path) File.open(path, "rb") do |f| file_size = f.size while f.pos < file_size size, type = read_atom_header(f) break unless size && type return nil if size < 8 content = size - 8 if type == "moov" moov_end = f.pos + content resolution = extract_resolution_from_moov(f, moov_end) return resolution if resolution else skip(f, content) end end end nil rescue => e FastlaneCore::UI.verbose("Failed to parse resolution for '#{path}': #{e.class} - #{e.}") nil end |