Class: MP4Info

Inherits:
Object
  • Object
show all
Defined in:
lib/mp4info.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io_stream) ⇒ MP4Info

Initialize a new MP4Info object from an IO object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/mp4info.rb', line 29

def initialize(io_stream)
  # Tag atoms
  @data_atoms = {
    "AART" => nil, "ALB" => nil, "ART" => nil, "CMT" => nil,
    "COVR" => nil, "CPIL" => nil, "CPRT" => nil, "DAY" => nil,
    "DISK" => nil, "GEN" => nil, "GNRE" => nil, "GRP" => nil,
    "NAM" => nil, "RTNG" => nil, "TMPO" => nil, "TOO" => nil,
    "TRKN" => nil, "WRT" => nil, "APID" => nil, "AKID" => nil,
    "ATID" => nil, "CNID" => nil, "GEID" => nil, "PLID" => nil,
    "TITL" => nil, "DSCP" => nil, "PERF" => nil, "AUTH" => nil
  }
  
  # Info atoms
  @info_atoms = {
    "VERSION" => nil, "BITRATE" => nil, "FREQUENCY" => nil, "MS" => nil,
    "SIZE" => nil, "SECS" => nil, "MM" => nil, "SS" => nil, "ENCRYPTED" => nil,
    "TIME" => nil, "COPYRIGHT" => nil, "LAYER" => nil
  }

  # Atoms that contain other atoms
  @container_atoms = {
    "ILST" => nil, "MDIA" => nil, "MINF" => nil, "MOOV" => nil,
    "STBL" => nil, "TRAK" => nil, "UDTA" => nil
  }
  
  # Non standard data atoms
  @other_atoms = {
    "MDAT" => :parse_mdat, "META" => :parse_meta,
    "MVHD" => :parse_mvhd, "STSD" => :parse_stsd,
    "MOOV" => :parse_moov, "UUID" => :parse_uuid
  }
  
  # Info/Tag aliases
  @aliases = {}
  
  # Just in case
  io_stream.binmode
  
  # Sanity check
  head = read_or_raise(io_stream, 8, "#{io_stream} does not appear to be an IO stream")
  raise "#{io_stream} does not appear to be an MP4 file" unless head[4..7].downcase == "ftyp"
  
  # Back to the beginning
  io_stream.rewind
  
  parse_container io_stream, 0, io_stream.stat.size
  
  @info_atoms["VERSION"] = 4
  @info_atoms["LAYER"] = 1 if @info_atoms["FREQUENCY"]
  if (@info_atoms["SIZE"] && @info_atoms["MS"])
    @info_atoms["BITRATE"] = ( 0.5 + @info_atoms["SIZE"] /
      ( ( @info_atoms["MM"] * 60 + @info_atoms["SS"] + (@info_atoms["MS"] * 1.0) / 1000 ) * 128 ) ).floor
  end
  @info_atoms["COPYRIGHT"] = true if @info_atoms["CPRT"]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(id) ⇒ Object

Dynamically get tags and info



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/mp4info.rb', line 91

def method_missing(id)
  field = id.to_s

  if (@data_atoms.has_key?(field))
    @data_atoms[field]
  elsif (@info_atoms.has_key?(field))
    @info_atoms[field]
  elsif (@aliases.has_key?(field))
    @aliases[field]
  else
    nil
  end
end

Class Method Details

.open(file_name) ⇒ Object

Get an MP4Info object from a file name



86
87
88
# File 'lib/mp4info.rb', line 86

def MP4Info.open(file_name)
  MP4Info.new(File.new(file_name))
end