class Bootstrap

Constants

ABST
AFRA

Top level

AFRT
ASRT

Inside ABST

MDAT
MOOF
MOOV

Attributes

boxes[R]

Public Class Methods

new(data) click to toggle source
# File lib/glued/bootstrap.rb, line 6
def initialize(data)
  @reader = F4VIO.new(data)
  @boxes = []
  scan
end

Public Instance Methods

fragments() click to toggle source
# File lib/glued/bootstrap.rb, line 27
def fragments
  @boxes.first.segment_run_tables.first.run_entry_table.first.fragments_per_segment
end
segments() click to toggle source
# File lib/glued/bootstrap.rb, line 23
def segments
  @boxes.first.segments
end

Private Instance Methods

get_afrt_box(header) click to toggle source
# File lib/glued/bootstrap.rb, line 124
def get_afrt_box(header)
  # 2.11.2.2 Fragment Run Table box
  raise "Unexpected fragment run table box header '#{header.type}' instead of '#{AFRT}'" unless header.type == AFRT

  b = RunTableBox.new
  b.header                        = header
  b.version                       = @reader.byte
  b.flags                         = @reader.int24
  b.time_scale                    = @reader.int32
  b.quality_segment_url_modifiers = @reader.byte_ar

  table = []
  runs = @reader.int32

  runs.times do
    f = FragmentRunEntry.new
    f.first_fragment = @reader.int32
    f.first_fragment_timestamp = @reader.int64
    f.fragment_duration = @reader.int32
    f.discontinuity_indicator = @reader.byte if f.fragment_duration == 0

    table << f
  end

  b.run_entry_table = table
  b
end
get_asrt_box(header) click to toggle source
# File lib/glued/bootstrap.rb, line 100
def get_asrt_box(header)
  # 2.11.2.1 Segment Run Table box
  raise "Unexpected segment run table box header '#{header.type}' instead of '#{ASRT}'" unless header.type == ASRT

  b = RunTableBox.new
  b.header                        = header
  b.version                       = @reader.byte
  b.flags                         = @reader.int24
  b.quality_segment_url_modifiers = @reader.byte_ar

  table = []
  runs = @reader.int32

  runs.times do
    first_segment = @reader.int32
    fragments_per_segment = @reader.int32

    table << SegmentRunEntry.new(first_segment, fragments_per_segment)
  end

  b.run_entry_table = table
  b
end
get_bootstrap_box(header) click to toggle source
# File lib/glued/bootstrap.rb, line 64
def get_bootstrap_box(header)
  # 2.11.2 Bootstrap Info box
  b                        = BootstrapBox.new
  b.header                 = header
  b.version                = @reader.byte
  b.flags                  = @reader.int24
  b.bootstrap_info_version = @reader.int32

  plu                      = @reader.byte
  b.profile                = plu >> 6
  b.live                   = (plu & 0x20) ? 1 : 0
  b.update                 = (plu & 0x01) ? 1 : 0

  b.time_scale             = @reader.int32
  b.current_media_time     = @reader.int64
  b.smpte_timecode_offset  = @reader.int64
  b.movie_identifier       = @reader.string
  b.servers                = @reader.byte_ar
  b.quality                = @reader.byte_ar
  b.drm_data               = @reader.string
  b.metadata               = @reader.string
  b.segments               = @reader.byte
  b.segment_run_tables     = []
  b.segments.times { b.segment_run_tables << get_asrt_box(get_box_info) }

  raise "There should be at least one segment entry" if b.segment_run_tables.empty?

  b.fragments               = @reader.byte
  b.fragment_run_tables     = []
  b.fragments.times { b.fragment_run_tables << get_afrt_box(get_box_info) }

  raise "There should be at least one fragment entry" if b.fragment_run_tables.empty?

  b
end
get_box_info() click to toggle source
# File lib/glued/bootstrap.rb, line 55
def get_box_info
  pos = @reader.pos
  size = @reader.int32
  type = @reader.fourCC
  size = @reader.int64 if size == 1 #For boxes over 4GB the size is moved here.

  Header.new(pos, size, type)
end
scan() click to toggle source
# File lib/glued/bootstrap.rb, line 33
def scan
  # Scan for 'boxes' in the stream see spec 1.3 F4V box format
  until (@reader.eof?) do
    box = get_box_info

    case box.type
    when ABST
      @boxes << get_bootstrap_box(box)
    when AFRA
      @boxes << box
    when MDAT
      @boxes << box
    else
      break;
    end
  end

  raise "Computer says no" if @boxes.empty?

  @boxes
end