Class: ID3::Tag2
- Inherits:
-
GenericTag
- Object
- ActiveSupport::OrderedHash
- RestrictedOrderedHash
- GenericTag
- ID3::Tag2
- Defined in:
- lib/id3/tag2.rb
Overview
Class Tag2 ID3 Version 2.x.y Tag
parses ID3v2 tags from a binary array
dumps ID3v2 tags into a binary array
allows to modify tag's contents
as per definition, the frames are in no fixed order
Instance Attribute Summary collapse
-
#flags ⇒ Object
readonly
Returns the value of attribute flags.
-
#rawflags ⇒ Object
readonly
Returns the value of attribute rawflags.
Attributes inherited from GenericTag
Attributes inherited from RestrictedOrderedHash
Instance Method Summary collapse
-
#[]=(framename, val) ⇒ Object
this is obviously half-baked..
- #dump ⇒ Object
-
#initialize ⇒ Tag2
constructor
A new instance of Tag2.
- #read_from_buffer(string) ⇒ Object
- #read_from_file(filename) ⇒ Object (also: #read)
Methods inherited from RestrictedOrderedHash
#delete, #lock, #old_delete, #old_store
Constructor Details
#initialize ⇒ Tag2
Returns a new instance of Tag2.
15 16 17 18 19 20 |
# File 'lib/id3/tag2.rb', line 15 def initialize super @rawflags = 0 @flags = {} @version = '2.3.0' # default version end |
Instance Attribute Details
#flags ⇒ Object (readonly)
Returns the value of attribute flags.
13 14 15 |
# File 'lib/id3/tag2.rb', line 13 def flags @flags end |
#rawflags ⇒ Object (readonly)
Returns the value of attribute rawflags.
13 14 15 |
# File 'lib/id3/tag2.rb', line 13 def rawflags @rawflags end |
Instance Method Details
#[]=(framename, val) ⇒ Object
this is obviously half-baked.. does not really work! We need SubClasses of ID3::Frame with specific handling
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/id3/tag2.rb', line 24 def []=(framename,val) # if this is a valid frame of known type, we return it's total length and a struct # if ID3::SUPPORTED_SYMBOLS[@version].has_value?(framename) frame = ID3::Frame.new( framename, @version) self[ framename ] = frame frame['text'] = val if frame.has_key?('text') return frame else return nil end end |
#dump ⇒ Object
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/id3/tag2.rb', line 236 def dump data = "" # dump all the frames self.each { |framename,framedata| data << framedata.dump } # add some padding perhaps 32 bytes (should be defined by the user!) # NOTE: I noticed that iTunes adds excessive amounts of padding data << ZEROBYTE * 32 # calculate the complete length of the data-section size = mungeSize(data.size) major,minor = @version.sub(/^2\.([0-9])\.([0-9])/, '\1 \2').split # prepend a valid ID3-v2.x header to the data block header = "ID3" << major.to_i << minor.to_i << @rawflags << size[0] << size[1] << size[2] << size[3] header + data end |
#read_from_buffer(string) ⇒ Object
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 |
# File 'lib/id3/tag2.rb', line 37 def read_from_buffer(string) has_tag = string =~ /^ID3/ if has_tag major = string.getbyte(ID3::ID3v2major) minor = string.getbyte(ID3::ID3v2minor) @version = "2." + major.to_s + '.' + minor.to_s @rawflags = string.getbyte(ID3::ID3v2flags) size = ID3::ID3v2headerSize + ID3.unmungeSize( string[ID3::ID3v2tagSize..ID3::ID3v2tagSize+4] ) return false if string.size < size @raw = string[0...size] # parse the raw flags: if (@rawflags & ID3::TAG_HEADER_FLAG_MASK[@version] != 0) # in this case we need to skip parsing the frame... and skip to the next one... wrong = @rawflags & ID3::TAG_HEADER_FLAG_MASK[@version] error = printf "ID3 version %s header flags 0x%X contain invalid flags 0x%X !\n", @version, @rawflags, wrong raise ArgumentError, error end @flags = Hash.new ID3::TAG_HEADER_FLAGS[@version].each{ |key,val| # only define the flags which are set.. @flags[key] = true if (@rawflags & val == 1) } else @raw = nil @version = nil return false end # # now parse all the frames # i = ID3::ID3v2headerSize; # we start parsing right after the ID3v2 header while (i < @raw.size) && (@raw.getbyte(i) != 0) len,frame = parse_frame_header(i) # this will create the correct frame if len != 0 i += len else break end end has_tag end |
#read_from_file(filename) ⇒ Object Also known as: read
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/id3/tag2.rb', line 83 def read_from_file(filename) f = File.open(filename, 'rb:BINARY') has_tag = (f.read(3) == "ID3") if has_tag major = f.get_byte minor = f.get_byte @version = "2." + major.to_s + '.' + minor.to_s @rawflags = f.get_byte size = ID3::ID3v2headerSize + unmungeSize(f.read(4)) # was read_bytes, which was a BUG!! f.seek(0) @raw = f.read(size) # parse the raw flags: if (@rawflags & ID3::TAG_HEADER_FLAG_MASK[@version] != 0) # in this case we need to skip parsing the frame... and skip to the next one... wrong = @rawflags & ID3::TAG_HEADER_FLAG_MASK[@version] error = printf "ID3 version %s header flags 0x%X contain invalid flags 0x%X !\n", @version, @rawflags, wrong raise ArgumentError, error end @flags = Hash.new ID3::TAG_HEADER_FLAGS[@version].each{ |key,val| # only define the flags which are set.. @flags[key] = true if (@rawflags & val == 1) } else @raw = nil @version = nil return false end f.close # # now parse all the frames # i = ID3::ID3v2headerSize; # we start parsing right after the ID3v2 header while (i < @raw.size) && (@raw.getbyte(i) != 0) len,frame = parse_frame_header(i) # this will create the correct frame if len != 0 i += len else break end end has_tag end |