Class: DashTimelineValidator::Segment
- Inherits:
-
Object
- Object
- DashTimelineValidator::Segment
- Defined in:
- lib/dash_timeline_validator/segment.rb
Class Method Summary collapse
- .check_segment_duration(context, current_segment, current_segment_number, download_init = true) ⇒ Object
- .process(context, ss) ⇒ Object
Class Method Details
.check_segment_duration(context, current_segment, current_segment_number, download_init = true) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/dash_timeline_validator/segment.rb', line 44 def self.check_segment_duration(context, current_segment, current_segment_number, download_init = true) init = context[:previous]["initialization"] media = context[:previous]["media"] base_path = context[:root]["base_path"] init_path = "#{DashTimelineValidator::Options::ANALYZER_FOLDER}/#{init}" DashTimelineValidator::DashFile.fetch_file("#{base_path}/#{init}", init_path) if download_init segment_file = media.gsub("$Number$", current_segment_number.to_s) segment_path = "#{DashTimelineValidator::Options::ANALYZER_FOLDER}/#{segment_file}" full_segment_path = "#{DashTimelineValidator::Options::ANALYZER_FOLDER}/#{segment_file}".gsub(".", "-complete.") DashTimelineValidator::DashFile.fetch_file("#{base_path}/#{segment_file}", segment_path) `cat #{init_path} #{segment_path} > #{full_segment_path}` duration = `mediainfo --Inform="General;%Duration%" #{full_segment_path}`.to_i File.delete segment_path File.delete full_segment_path mediainfo_duration = duration.to_f / 1000 * context[:previous]["timescale"].to_i if (mediainfo_duration != current_segment[:d]) return DashTimelineValidator::Report.report_warn("Mediainfo shows different duration for #{segment_file} compared to the advertised segment timeline item (#{(mediainfo_duration - current_segment[:d]).abs})") end end |
.process(context, ss) ⇒ Object
3 4 5 6 7 8 9 10 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 37 38 39 40 41 42 |
# File 'lib/dash_timeline_validator/segment.rb', line 3 def self.process(context, ss) mpd_type = context[:root]["mpd"]["type"] previous = context[:previous] previous["S"] = [] ss.each_with_index do |s, index| unless s.respond_to? "d" previous["S"].push(DashTimelineValidator::Report.report_error("Segment (#{index + 1}) doen't have mandatory value for 'd'")) error_exit(previous) end if mpd_type.eql? "dynamic" and !s.respond_to? "t" previous["S"].push(DashTimelineValidator::Report.report_warn("Segment <S d='#{s[:d]}' t='#{s[:t]}'/> doen't have a value for 't', it's necessary for MPD with 'dynamic' type")) end end timeline_segments = ss.map { |s| {d: s.d.to_i, t: s.respond_to?("t") ? s.t.to_i : 0, r: s.respond_to?("r") ? s.r.to_i : 0} } current_segment_number = context[:previous]["startNumber"].to_i timeline_segments.each_with_index do |current_segment, index| unless index.zero? previous_segment = timeline_segments[index - 1] current_segment_time = current_segment[:t] expected_segment_time = (previous_segment[:t] + (previous_segment[:d]) * (1 + previous_segment[:r])) drift = (expected_segment_time - current_segment_time).abs if drift > DashTimelineValidator::Options::ACCEPTABLE_DRIFT previous["S"].push(DashTimelineValidator::Report.report_warn("Timeline of <S d='#{current_segment[:d]}' t='#{current_segment[:t]}'/> was expected to be #{expected_segment_time}, but is #{current_segment_time} (drift = #{drift})")) end end if DashTimelineValidator::Options::VERIFY_SEGMENTS_DURATION (current_segment[:r].to_i + 1).times do |i| duration_report = check_segment_duration(context, current_segment, current_segment_number, i.zero?) previous["S"].push(duration_report) if duration_report current_segment_number += 1 end end end previous.delete("S") if previous["S"].empty? end |