class WahWah::Mp4Tag

Constants

META_ATOM_DECODE_BY_TYPE
META_ATOM_MAPPING

Private Instance Methods

parse() click to toggle source
# File lib/wahwah/mp4_tag.rb, line 45
def parse
  movie_atom = Mp4::Atom.find(@file_io, 'moov')
  return unless movie_atom.valid?

  parse_meta_list_atom movie_atom.find('udta', 'meta', 'ilst')
  parse_mvhd_atom movie_atom.find('mvhd')
  parse_stsd_atom movie_atom.find('trak', 'mdia', 'minf', 'stbl', 'stsd')
end
parse_image_data(image_data_atom) click to toggle source
# File lib/wahwah/mp4_tag.rb, line 129
def parse_image_data(image_data_atom)
  parse_meta_data_atom(image_data_atom)
end
parse_meta_data_atom(atom) click to toggle source
# File lib/wahwah/mp4_tag.rb, line 90
def parse_meta_data_atom(atom)
  data_type, data_value = atom.data.unpack('Nx4a*')
  META_ATOM_DECODE_BY_TYPE[data_type]&.call(data_value)
end
parse_meta_list_atom(atom) click to toggle source
# File lib/wahwah/mp4_tag.rb, line 54
def parse_meta_list_atom(atom)
  return unless atom.valid?

  # The metadata item list atom holds a list of actual metadata values that are present in the metadata atom.
  # The metadata items are formatted as a list of items.
  # The metadata item list atom is of type ‘ilst’ and contains a number of metadata items, each of which is an atom.
  # each metadata item atom contains a Value Atom, to hold the value of the metadata item
  atom.children.each do |child_atom|
    attr_name = META_ATOM_MAPPING[child_atom.type]

    # The value of the metadata item is expressed as immediate data in a value atom.
    # The value atom starts with two fields: a type indicator, and a locale indicator.
    # Both the type and locale indicators are four bytes long.
    # There may be multiple ‘value’ entries, using different type
    data_atom = child_atom.find('data')
    return unless data_atom.valid?

    (@images_data.push(data_atom); next) if attr_name == :image

    encoded_data_value = parse_meta_data_atom(data_atom)
    next if attr_name.nil? || encoded_data_value.nil?

    case attr_name
    when :comment
      @comments.push(encoded_data_value)
    when :track, :disc
      count, total_count = encoded_data_value.unpack('x2nn')

      instance_variable_set("@#{attr_name}", count) unless count.zero?
      instance_variable_set("@#{attr_name}_total", total_count) unless total_count.zero?
    else
      instance_variable_set("@#{attr_name}", encoded_data_value)
    end
  end
end
parse_mvhd_atom(atom) click to toggle source
# File lib/wahwah/mp4_tag.rb, line 95
def parse_mvhd_atom(atom)
  return unless atom.valid?

  atom_data = StringIO.new(atom.data)
  version = atom_data.read(1).unpack('c').first

  # Skip flags
  atom_data.seek(3, IO::SEEK_CUR)

  if version == 0
    # Skip creation and modification time
    atom_data.seek(8, IO::SEEK_CUR)

    time_scale, duration = atom_data.read(8).unpack('l>l>')
  elsif version == 1
    # Skip creation and modification time
    atom_data.seek(16, IO::SEEK_CUR)

    time_scale, duration = atom_data.read(12).unpack('l>q>')
  end

  @duration = (duration / time_scale.to_f).round
end
parse_stsd_atom(atom) click to toggle source
# File lib/wahwah/mp4_tag.rb, line 119
def parse_stsd_atom(atom)
  return unless atom.valid?

  mp4a_atom = atom.find('mp4a')
  esds_atom = atom.find('esds')

  @sample_rate = mp4a_atom.data.unpack('x22I>').first if mp4a_atom.valid?
  @bitrate = esds_atom.data.unpack('x26I>').first / 1000 if esds_atom.valid?
end