class WahWah::ID3::Frame

Constants

ID_MAPPING
V3_HEADER_FLAGS_INDICATIONS

ID3v2.3 frame flags field is defined as follows.

%abc00000 %ijk00000

a - Tag alter preservation b - File alter preservation c - Read only i - Compression j - Encryption k - Grouping identity

V4_HEADER_FLAGS_INDICATIONS

ID3v2.4 frame flags field is defined as follows.

%0abc0000 %0h00kmnp

a - Tag alter preservation b - File alter preservation c - Read only h - Grouping identity k - Compression m - Encryption n - Unsynchronisation p - Data length indicator

Attributes

name[R]

Public Class Methods

new(version) click to toggle source
# File lib/wahwah/id3/frame.rb, line 83
def initialize(version)
  @version = version

  parse_frame_header

  # In ID3v2.3 when frame is compressed using zlib
  # with 4 bytes for 'decompressed size' appended to the frame header.
  #
  # In ID3v2.4 A 'Data Length Indicator' byte MUST be included in the frame
  # when frame is compressed, and 'Data Length Indicator'represented as a 32 bit
  # synchsafe integer
  #
  # So skip those 4 byte.
  if compressed? || data_length_indicator?
    @file_io.seek(4, IO::SEEK_CUR)
    @size = @size - 4
  end
end

Public Instance Methods

compressed?() click to toggle source
# File lib/wahwah/id3/frame.rb, line 106
def compressed?
  @flags.include? :compression
end
data_length_indicator?() click to toggle source
# File lib/wahwah/id3/frame.rb, line 110
def data_length_indicator?
  @flags.include? :data_length_indicator
end
valid?() click to toggle source
# File lib/wahwah/id3/frame.rb, line 102
def valid?
  @size > 0 && !@name.nil?
end
value() click to toggle source
# File lib/wahwah/id3/frame.rb, line 114
def value
  return unless @size > 0

  content = compressed? ? Zlib.inflate(data) : data
  frame_body = frame_body_class.new(content, @version)
  frame_body.value
end

Private Instance Methods

frame_body_class() click to toggle source
# File lib/wahwah/id3/frame.rb, line 161
def frame_body_class
  case @name
  when :comment
    CommentFrameBody
  when :genre
    GenreFrameBody
  when :image
    ImageFrameBody
  else
    TextFrameBody
  end
end
parse_flags(flags_bits) click to toggle source
# File lib/wahwah/id3/frame.rb, line 149
def parse_flags(flags_bits)
  return [] if flags_bits.nil?

  frame_flags_indications = @version == 4 ?
    V4_HEADER_FLAGS_INDICATIONS :
    V3_HEADER_FLAGS_INDICATIONS

  flags_bits.split('').map.with_index do |flag_bit, index|
    frame_flags_indications[index] if flag_bit == '1'
  end.compact
end
parse_frame_header() click to toggle source

ID3v2.2 frame header structure:

Frame ID $xx xx xx(tree characters) Size 3 * %xxxxxxxx

ID3v2.3 frame header structure:

Frame ID $xx xx xx xx (four characters) Size 4 * %xxxxxxxx Flags $xx xx

ID3v2.4 frame header structure:

Frame ID $xx xx xx xx (four characters) Size 4 * %0xxxxxxx Flags $xx xx

# File lib/wahwah/id3/frame.rb, line 139
def parse_frame_header
  header_size = @version == 2 ? 6 : 10
  header_formate = @version == 2 ? 'A3B24' : 'A4B32B16'
  id, size_bits, flags_bits = @file_io.read(header_size).unpack(header_formate)

  @name = ID_MAPPING[id.to_sym]
  @size = Helper.id3_size_caculate(size_bits, has_zero_bit: @version == 4)
  @flags = parse_flags(flags_bits)
end