Parent

Class/Module Index [+]

Quicksearch

ID3v2

This class can be used to decode id3v2 tags from files, like .mp3 or .ape for example. It works like a hash, where key represents the tag name as 3 or 4 upper case letters (respectively related to 2.2 and 2.3+ tag) and value represented as array or raw value. Written version is always 2.3.

Constants

TAGS
TAG_MAPPING_2_2_to_2_3

Translate V2 to V3 tags

TEXT_ENCODINGS

See id3v2.4.0-structure document, at section 4.

WRITE_VERSION

Major version used when writing tags

Attributes

io_position[R]

this is the position in the file where the tag really ends

options[R]

:lang: for writing comments

:encoding: one of the string of TEXT_ENCODINGS, used as a source and destination encoding respectively for read and write tag2 values.

Public Class Methods

new(options = {}) click to toggle source

possible options are described above ('options' attribute) you can access this object like an hash, with [] and []= methods special cases are ["disc_number"] and ["disc_total"] mirroring TPOS attribute

# File lib/mp3info/id3v2.rb, line 179
def initialize(options = {})
  @options = { 
    :lang => "ENG",
    :encoding => "iso-8859-1"
  }

  @options.update(options)
  @text_encoding_index = TEXT_ENCODINGS.index(@options[:encoding])
  
  unless @text_encoding_index
    raise(ArgumentError, "bad id3v2 text encoding specified")
  end

  @hash = {}
  #TAGS.keys.each { |k| @hash[k] = nil }
  @hash_orig = {}
  super(@hash)
  @parsed = false
  @version_maj = @version_min = nil
end

Public Instance Methods

changed?() click to toggle source

does this tag has been changed ?

# File lib/mp3info/id3v2.rb, line 206
def changed?
  @hash_orig != @hash
end
from_io(io) click to toggle source

gets id3v2 tag information from io object (must support seek() method)

# File lib/mp3info/id3v2.rb, line 221
def from_io(io)
  @io = io
  original_pos = @io.pos
  @io.extend(Mp3Info::Mp3FileMethods)
  version_maj, version_min, flags = @io.read(3).unpack("CCB4")
  @unsync, ext_header, experimental, footer = (0..3).collect { |i| flags[i].chr == '1' }
  raise(ID3v2Error, "can't find version_maj ('#{version_maj}')") unless [2, 3, 4].include?(version_maj)
  @version_maj, @version_min = version_maj, version_min
  @tag_length = @io.get_syncsafe
  
  @parsed = true
  begin
    case @version_maj
      when 2
        read_id3v2_2_frames
      when 3, 4
        # seek past extended header if present
        @io.seek(@io.get_syncsafe - 4, IO::SEEK_CUR) if ext_header
        read_id3v2_3_frames
    end
  rescue ID3v2Error => e
    warn("warning: id3v2 tag not fully parsed: #{e.message}")
  end
  @io_position = @io.pos
  @tag_length = @io_position - original_pos

  @hash_orig = @hash.dup
  #no more reading
  @io = nil
end
parsed?() click to toggle source

does this tag has been correctly read ?

# File lib/mp3info/id3v2.rb, line 201
def parsed?
  @parsed
end
to_bin() click to toggle source

dump tag for writing. Version is always 2.#{WRITE_VERSION}.0.

# File lib/mp3info/id3v2.rb, line 253
def to_bin
  #TODO handle of @tag2[TLEN"]
  #TODO add of crc
  #TODO add restrictions tag

  tag = ""
  @hash.each do |k, v|
    next unless v
    next if v.respond_to?("empty?") and v.empty?
    
    # Automagically translate V2 to V3 tags
    k = TAG_MAPPING_2_2_to_2_3[k] if TAG_MAPPING_2_2_to_2_3.has_key?(k)

    # doesn't encode id3v2.2 tags, which have 3 characters
    next if k.size != 4 
    
    # Output one flag for each array element, or one only if it's not an array
    [v].flatten.each do |value|
      data = encode_tag(k, value.to_s, WRITE_VERSION)
      #data << "\x00"*2 #End of tag

      tag << k[0,4]   #4 characte max for a tag's key
      #tag << to_syncsafe(data.size) #+1 because of the language encoding byte
      size = data.size
      if RUBY_VERSION >= "1.9.0"
        size = data.dup.force_encoding("binary").size
      end
      tag << [size].pack("N") #+1 because of the language encoding byte
      tag << "\x00"*2 #flags
      tag << data
    end
  end

  tag_str = "ID3"
  #version_maj, version_min, unsync, ext_header, experimental, footer 
  tag_str << [ WRITE_VERSION, 0, "0000" ].pack("CCB4")
  tag_str << [to_syncsafe(tag.size)].pack("N")
  tag_str << tag
  puts "tag in binary format: #{tag_str.inspect}" if $DEBUG
  tag_str
end
version() click to toggle source

full version of this tag (like "2.3.0") or nil if tag was not correctly read

# File lib/mp3info/id3v2.rb, line 212
def version
  if @version_maj && @version_min
    "2.#{@version_maj}.#{@version_min}"
  else
    nil
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.