Module: FormatParser::ISOBaseMediaFileFormat::Utils
Constant Summary collapse
- IDENTITY_MATRIX =
Matrix.identity(3)
Instance Method Summary collapse
- #dimensions(box_tree) ⇒ Object
- #duration(box_tree) ⇒ Object
- #frame_rate(box_tree) ⇒ Object
- #video_codecs(box_tree) ⇒ Object
Instance Method Details
#dimensions(box_tree) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/parsers/iso_base_media_file_format/utils.rb', line 11 def dimensions(box_tree) moov_box = box_tree.find { |box| box.type == 'moov' } return unless moov_box movie_matrix = moov_box.first_child('mvhd')&.dig(:fields, :matrix) || IDENTITY_MATRIX extreme_coordinates = video_trak_boxes(box_tree).each_with_object({}) do |trak_box, extreme_coordinates| tkhd_box = trak_box.first_child('tkhd') next unless tkhd_box x = tkhd_box.fields[:width] y = tkhd_box.fields[:height] next unless x && y track_matrix = tkhd_box.fields[:matrix] || IDENTITY_MATRIX [[0, 0], [0, y], [x, 0], [x, y]].each do |coordinates| x, y = (Matrix[[*coordinates, 1]] * track_matrix * movie_matrix).to_a[0][0..1] extreme_coordinates[:min_x] = x if !extreme_coordinates[:min_x] || x < extreme_coordinates[:min_x] extreme_coordinates[:max_x] = x if !extreme_coordinates[:max_x] || x > extreme_coordinates[:max_x] extreme_coordinates[:min_y] = y if !extreme_coordinates[:min_y] || y < extreme_coordinates[:min_y] extreme_coordinates[:max_y] = y if !extreme_coordinates[:max_y] || y > extreme_coordinates[:max_y] end end unless extreme_coordinates.empty? [ extreme_coordinates[:max_x] - extreme_coordinates[:min_x], extreme_coordinates[:max_y] - extreme_coordinates[:min_y] ] end end |
#duration(box_tree) ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/parsers/iso_base_media_file_format/utils.rb', line 38 def duration(box_tree) mvhd_box = box_tree.find { |box| box.type == 'moov' }&.first_child('mvhd') return unless mvhd_box duration = mvhd_box.fields[:duration] timescale = mvhd_box.fields[:timescale]&.to_f duration / timescale if duration && timescale end |
#frame_rate(box_tree) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/parsers/iso_base_media_file_format/utils.rb', line 46 def frame_rate(box_tree) video_trak_boxes(box_tree).each do |trak_box| mdhd_box = trak_box.first_descendent_by_path(%w[mdia mdhd]) stts_box = trak_box.first_descendent_by_path(%w[mdia minf stbl stts]) next unless mdhd_box && stts_box timescale = mdhd_box.fields[:timescale]&.to_f sample_delta = stts_box.dig(:fields, :entries, 0, :sample_delta) next unless timescale && sample_delta return (timescale / sample_delta).truncate(2) end nil # TODO: Properly account for and represent variable frame-rates. end |
#video_codecs(box_tree) ⇒ Object
64 65 66 67 68 |
# File 'lib/parsers/iso_base_media_file_format/utils.rb', line 64 def video_codecs(box_tree) video_trak_boxes(box_tree).flat_map do |trak_box| trak_box.all_descendents_by_path(%w[mdia minf stbl stsd]).flat_map { |stsd_box| stsd_box.children.map(&:type) } end.compact.uniq end |