wahwah 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/wahwah/asf/object.rb +2 -2
- data/lib/wahwah/asf_tag.rb +199 -198
- data/lib/wahwah/errors.rb +2 -1
- data/lib/wahwah/flac/block.rb +4 -4
- data/lib/wahwah/flac/streaminfo_block.rb +4 -4
- data/lib/wahwah/flac_tag.rb +65 -63
- data/lib/wahwah/helper.rb +8 -8
- data/lib/wahwah/id3/comment_frame_body.rb +1 -1
- data/lib/wahwah/id3/frame.rb +47 -46
- data/lib/wahwah/id3/frame_body.rb +6 -7
- data/lib/wahwah/id3/image_frame_body.rb +5 -5
- data/lib/wahwah/id3/text_frame_body.rb +1 -1
- data/lib/wahwah/id3/v1.rb +59 -58
- data/lib/wahwah/id3/v2.rb +41 -35
- data/lib/wahwah/id3/v2_header.rb +4 -4
- data/lib/wahwah/lazy_read.rb +5 -4
- data/lib/wahwah/mp3/mpeg_frame_header.rb +39 -37
- data/lib/wahwah/mp3/vbri_header.rb +2 -2
- data/lib/wahwah/mp3/xing_header.rb +4 -4
- data/lib/wahwah/mp3_tag.rb +51 -48
- data/lib/wahwah/mp4/atom.rb +25 -24
- data/lib/wahwah/mp4_tag.rb +101 -97
- data/lib/wahwah/ogg/flac_tag.rb +2 -2
- data/lib/wahwah/ogg/opus_tag.rb +3 -3
- data/lib/wahwah/ogg/packets.rb +2 -2
- data/lib/wahwah/ogg/page.rb +3 -3
- data/lib/wahwah/ogg/vorbis_comment.rb +14 -14
- data/lib/wahwah/ogg/vorbis_tag.rb +2 -2
- data/lib/wahwah/ogg_tag.rb +34 -34
- data/lib/wahwah/riff/chunk.rb +7 -6
- data/lib/wahwah/riff_tag.rb +81 -79
- data/lib/wahwah/tag.rb +8 -7
- data/lib/wahwah/version.rb +1 -1
- data/lib/wahwah.rb +58 -58
- metadata +13 -14
data/lib/wahwah/helper.rb
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
module WahWah
|
4
4
|
module Helper
|
5
|
-
def self.encode_to_utf8(string, source_encoding:
|
5
|
+
def self.encode_to_utf8(string, source_encoding: "")
|
6
6
|
encoded_string = source_encoding.empty? ?
|
7
|
-
string.force_encoding(
|
8
|
-
string.encode(
|
7
|
+
string.force_encoding("utf-8") :
|
8
|
+
string.encode("utf-8", source_encoding, invalid: :replace, undef: :replace, replace: "")
|
9
9
|
|
10
|
-
encoded_string.valid_encoding? ? encoded_string.strip :
|
10
|
+
encoded_string.valid_encoding? ? encoded_string.strip : ""
|
11
11
|
end
|
12
12
|
|
13
13
|
# ID3 size is encoded with four bytes where may the most significant
|
@@ -15,7 +15,7 @@ module WahWah
|
|
15
15
|
# making a total of 28 bits. The zeroed bits are ignored
|
16
16
|
def self.id3_size_caculate(bits_string, has_zero_bit: true)
|
17
17
|
if has_zero_bit
|
18
|
-
bits_string.scan(/.{8}/).map { |byte_string| byte_string[1
|
18
|
+
bits_string.scan(/.{8}/).map { |byte_string| byte_string[1..] }.join.to_i(2)
|
19
19
|
else
|
20
20
|
bits_string.to_i(2)
|
21
21
|
end
|
@@ -26,12 +26,12 @@ module WahWah
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.file_format(file_path)
|
29
|
-
File.extname(file_path).downcase.delete(
|
29
|
+
File.extname(file_path).downcase.delete(".")
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.byte_string_to_guid(byte_string)
|
33
|
-
guid = byte_string.unpack(
|
34
|
-
[guid[0..7], guid[8..11], guid[12..15], guid[16..19], guid[20
|
33
|
+
guid = byte_string.unpack("NnnA*").pack("VvvA*").unpack1("H*")
|
34
|
+
[guid[0..7], guid[8..11], guid[12..15], guid[16..19], guid[20..]].join("-").upcase
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -10,7 +10,7 @@ module WahWah
|
|
10
10
|
# Short content description <textstring> $00 (00)
|
11
11
|
# The actual text <textstring>
|
12
12
|
def parse
|
13
|
-
encoding_id, _language, reset_content = @content.unpack(
|
13
|
+
encoding_id, _language, reset_content = @content.unpack("CA3a*")
|
14
14
|
encoding = ENCODING_MAPPING[encoding_id]
|
15
15
|
_description, comment_text = Helper.split_with_terminator(reset_content, ENCODING_TERMINATOR_SIZE[encoding])
|
16
16
|
|
data/lib/wahwah/id3/frame.rb
CHANGED
@@ -95,7 +95,7 @@ module WahWah
|
|
95
95
|
# So skip those 4 byte.
|
96
96
|
if compressed? || data_length_indicator?
|
97
97
|
@file_io.seek(4, IO::SEEK_CUR)
|
98
|
-
@size
|
98
|
+
@size -= 4
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -120,56 +120,57 @@ module WahWah
|
|
120
120
|
end
|
121
121
|
|
122
122
|
private
|
123
|
-
# ID3v2.2 frame header structure:
|
124
|
-
#
|
125
|
-
# Frame ID $xx xx xx(tree characters)
|
126
|
-
# Size 3 * %xxxxxxxx
|
127
|
-
#
|
128
|
-
# ID3v2.3 frame header structure:
|
129
|
-
#
|
130
|
-
# Frame ID $xx xx xx xx (four characters)
|
131
|
-
# Size 4 * %xxxxxxxx
|
132
|
-
# Flags $xx xx
|
133
|
-
#
|
134
|
-
# ID3v2.4 frame header structure:
|
135
|
-
#
|
136
|
-
# Frame ID $xx xx xx xx (four characters)
|
137
|
-
# Size 4 * %0xxxxxxx
|
138
|
-
# Flags $xx xx
|
139
|
-
def parse_frame_header
|
140
|
-
header_size = @version == 2 ? 6 : 10
|
141
|
-
header_formate = @version == 2 ? 'A3B24' : 'A4B32B16'
|
142
|
-
id, size_bits, flags_bits = @file_io.read(header_size).unpack(header_formate)
|
143
|
-
|
144
|
-
@name = ID_MAPPING[id.to_sym]
|
145
|
-
@size = Helper.id3_size_caculate(size_bits, has_zero_bit: @version == 4)
|
146
|
-
@flags = parse_flags(flags_bits)
|
147
|
-
end
|
148
123
|
|
149
|
-
|
150
|
-
|
124
|
+
# ID3v2.2 frame header structure:
|
125
|
+
#
|
126
|
+
# Frame ID $xx xx xx(tree characters)
|
127
|
+
# Size 3 * %xxxxxxxx
|
128
|
+
#
|
129
|
+
# ID3v2.3 frame header structure:
|
130
|
+
#
|
131
|
+
# Frame ID $xx xx xx xx (four characters)
|
132
|
+
# Size 4 * %xxxxxxxx
|
133
|
+
# Flags $xx xx
|
134
|
+
#
|
135
|
+
# ID3v2.4 frame header structure:
|
136
|
+
#
|
137
|
+
# Frame ID $xx xx xx xx (four characters)
|
138
|
+
# Size 4 * %0xxxxxxx
|
139
|
+
# Flags $xx xx
|
140
|
+
def parse_frame_header
|
141
|
+
header_size = @version == 2 ? 6 : 10
|
142
|
+
header_formate = @version == 2 ? "A3B24" : "A4B32B16"
|
143
|
+
id, size_bits, flags_bits = @file_io.read(header_size).unpack(header_formate)
|
144
|
+
|
145
|
+
@name = ID_MAPPING[id.to_sym]
|
146
|
+
@size = Helper.id3_size_caculate(size_bits, has_zero_bit: @version == 4)
|
147
|
+
@flags = parse_flags(flags_bits)
|
148
|
+
end
|
149
|
+
|
150
|
+
def parse_flags(flags_bits)
|
151
|
+
return [] if flags_bits.nil?
|
151
152
|
|
152
|
-
|
153
|
-
|
154
|
-
|
153
|
+
frame_flags_indications = @version == 4 ?
|
154
|
+
V4_HEADER_FLAGS_INDICATIONS :
|
155
|
+
V3_HEADER_FLAGS_INDICATIONS
|
155
156
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
157
|
+
flags_bits.chars.map.with_index do |flag_bit, index|
|
158
|
+
frame_flags_indications[index] if flag_bit == "1"
|
159
|
+
end.compact
|
160
|
+
end
|
160
161
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
end
|
162
|
+
def frame_body_class
|
163
|
+
case @name
|
164
|
+
when :comment
|
165
|
+
CommentFrameBody
|
166
|
+
when :genre
|
167
|
+
GenreFrameBody
|
168
|
+
when :image
|
169
|
+
ImageFrameBody
|
170
|
+
else
|
171
|
+
TextFrameBody
|
172
172
|
end
|
173
|
+
end
|
173
174
|
end
|
174
175
|
end
|
175
176
|
end
|
@@ -9,16 +9,15 @@ module WahWah
|
|
9
9
|
# $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM.
|
10
10
|
# $02 UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
|
11
11
|
# $03 UTF-8 [UTF-8] encoded Unicode [UNICODE].
|
12
|
-
ENCODING_MAPPING = %w
|
12
|
+
ENCODING_MAPPING = %w[ISO-8859-1 UTF-16 UTF-16BE UTF-8]
|
13
13
|
|
14
14
|
ENCODING_TERMINATOR_SIZE = {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
"ISO-8859-1" => 1,
|
16
|
+
"UTF-16" => 2,
|
17
|
+
"UTF-16BE" => 2,
|
18
|
+
"UTF-8" => 1
|
19
19
|
}
|
20
20
|
|
21
|
-
|
22
21
|
attr_reader :value
|
23
22
|
|
24
23
|
def initialize(content, version)
|
@@ -29,7 +28,7 @@ module WahWah
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def parse
|
32
|
-
raise WahWahNotImplementedError,
|
31
|
+
raise WahWahNotImplementedError, "The parse method is not implemented"
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module WahWah
|
4
4
|
module ID3
|
5
5
|
class ImageFrameBody < FrameBody
|
6
|
-
TYPES = %i
|
6
|
+
TYPES = %i[
|
7
7
|
other
|
8
8
|
file_icon
|
9
9
|
other_file_icon
|
@@ -25,10 +25,10 @@ module WahWah
|
|
25
25
|
illustration
|
26
26
|
band_logotype
|
27
27
|
publisher_logotype
|
28
|
-
|
28
|
+
]
|
29
29
|
|
30
30
|
def mime_type
|
31
|
-
mime_type = @mime_type.downcase.yield_self { |type| type ==
|
31
|
+
mime_type = @mime_type.downcase.yield_self { |type| type == "jpg" ? "jpeg" : type }
|
32
32
|
@version > 2 ? mime_type : "image/#{mime_type}"
|
33
33
|
end
|
34
34
|
|
@@ -48,12 +48,12 @@ module WahWah
|
|
48
48
|
# Description <text string according to encoding> $00 (00)
|
49
49
|
# Picture data <binary data>
|
50
50
|
def parse
|
51
|
-
frame_format = @version > 2 ?
|
51
|
+
frame_format = @version > 2 ? "CZ*Ca*" : "Ca3Ca*"
|
52
52
|
encoding_id, @mime_type, type_index, reset_content = @content.unpack(frame_format)
|
53
53
|
encoding = ENCODING_MAPPING[encoding_id]
|
54
54
|
_description, data = Helper.split_with_terminator(reset_content, ENCODING_TERMINATOR_SIZE[encoding])
|
55
55
|
|
56
|
-
@value = {
|
56
|
+
@value = {data: data, mime_type: mime_type, type: TYPES[type_index]}
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -8,7 +8,7 @@ module WahWah
|
|
8
8
|
# Text encoding $xx
|
9
9
|
# Information <text string according to encoding>
|
10
10
|
def parse
|
11
|
-
encoding_id, text = @content.unpack(
|
11
|
+
encoding_id, text = @content.unpack("Ca*")
|
12
12
|
@value = Helper.encode_to_utf8(text, source_encoding: ENCODING_MAPPING[encoding_id])
|
13
13
|
end
|
14
14
|
end
|
data/lib/wahwah/id3/v1.rb
CHANGED
@@ -4,44 +4,44 @@ module WahWah
|
|
4
4
|
module ID3
|
5
5
|
class V1 < Tag
|
6
6
|
TAG_SIZE = 128
|
7
|
-
TAG_ID =
|
8
|
-
DEFAULT_ENCODING =
|
7
|
+
TAG_ID = "TAG"
|
8
|
+
DEFAULT_ENCODING = "iso-8859-1"
|
9
9
|
GENRES = [
|
10
10
|
# Standard Genres
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
11
|
+
"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge",
|
12
|
+
"Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop",
|
13
|
+
"R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative",
|
14
|
+
"Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop",
|
15
|
+
"Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid",
|
16
|
+
"House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
|
17
|
+
"Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic",
|
18
|
+
"Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream",
|
19
|
+
"Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk",
|
20
|
+
"Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes",
|
21
|
+
"Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro",
|
22
|
+
"Musical", "Rock & Roll", "Hard Rock",
|
23
23
|
|
24
24
|
# Winamp Extended Genres
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
"Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin",
|
26
|
+
"Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
|
27
|
+
"Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
|
28
|
+
"Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass",
|
29
|
+
"Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
|
30
|
+
"Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock",
|
31
|
+
"Drum Solo", "A capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House",
|
32
|
+
"Hardcore Techno", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat",
|
33
|
+
"Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Contemporary Christian", "Christian Rock",
|
34
34
|
|
35
35
|
# Added on WinAmp 1.91
|
36
|
-
|
36
|
+
"Merengue", "Salsa", "Thrash Metal", "Anime", "Jpop", "Synthpop",
|
37
37
|
|
38
38
|
# Added on WinAmp 5.6
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
"Abstract", "Art Rock", "Baroque", "Bhangra", "Big Beat", "Breakbeat", "Chillout",
|
40
|
+
"Downtempo", "Dub", "EBM", "Eclectic", "Electro", "Electroclash", "Emo",
|
41
|
+
"Experimental", "Garage", "Illbient", "Industro-Goth", "Jam Band", "Krautrock", "Leftfield",
|
42
|
+
"Lounge", "Math Rock", "New Romantic", "Nu-Breakz", "Post-Punk", "Post-Rock", "Psytrance",
|
43
|
+
"Shoegaze", "Space Rock", "Trop Rock", "World Music", "Neoclassical", "Audiobook", "Audio Theatre",
|
44
|
+
"Neue Deutsche Welle", "Podcast", "Indie Rock", "G-Funk", "Dubstep", "Garage Rock", "Psybient"
|
45
45
|
]
|
46
46
|
|
47
47
|
def size
|
@@ -49,7 +49,7 @@ module WahWah
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def version
|
52
|
-
|
52
|
+
"v1"
|
53
53
|
end
|
54
54
|
|
55
55
|
def valid?
|
@@ -57,40 +57,41 @@ module WahWah
|
|
57
57
|
end
|
58
58
|
|
59
59
|
private
|
60
|
-
# For ID3v1 info, see here https://en.wikipedia.org/wiki/ID3#ID3v1
|
61
|
-
#
|
62
|
-
# header 3 "TAG"
|
63
|
-
# title 30 30 characters of the title
|
64
|
-
# artist 30 30 characters of the artist name
|
65
|
-
# album 30 30 characters of the album name
|
66
|
-
# year 4 A four-digit year
|
67
|
-
# comment 28 or 30 The comment.
|
68
|
-
# zero-byte 1 If a track number is stored, this byte contains a binary 0.
|
69
|
-
# track 1 The number of the track on the album, or 0. Invalid, if previous byte is not a binary 0.
|
70
|
-
# genre 1 Index in a list of genres, or 255
|
71
|
-
def parse
|
72
|
-
return unless @file_io.size >= TAG_SIZE
|
73
60
|
|
74
|
-
|
75
|
-
|
61
|
+
# For ID3v1 info, see here https://en.wikipedia.org/wiki/ID3#ID3v1
|
62
|
+
#
|
63
|
+
# header 3 "TAG"
|
64
|
+
# title 30 30 characters of the title
|
65
|
+
# artist 30 30 characters of the artist name
|
66
|
+
# album 30 30 characters of the album name
|
67
|
+
# year 4 A four-digit year
|
68
|
+
# comment 28 or 30 The comment.
|
69
|
+
# zero-byte 1 If a track number is stored, this byte contains a binary 0.
|
70
|
+
# track 1 The number of the track on the album, or 0. Invalid, if previous byte is not a binary 0.
|
71
|
+
# genre 1 Index in a list of genres, or 255
|
72
|
+
def parse
|
73
|
+
return unless @file_io.size >= TAG_SIZE
|
76
74
|
|
77
|
-
|
75
|
+
@file_io.seek(-TAG_SIZE, IO::SEEK_END)
|
76
|
+
@id = Helper.encode_to_utf8(@file_io.read(3), source_encoding: DEFAULT_ENCODING)
|
78
77
|
|
79
|
-
|
80
|
-
@artist = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
81
|
-
@album = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
82
|
-
@year = Helper.encode_to_utf8(@file_io.read(4), source_encoding: DEFAULT_ENCODING)
|
78
|
+
return unless valid?
|
83
79
|
|
84
|
-
|
80
|
+
@title = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
81
|
+
@artist = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
82
|
+
@album = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
83
|
+
@year = Helper.encode_to_utf8(@file_io.read(4), source_encoding: DEFAULT_ENCODING)
|
85
84
|
|
86
|
-
|
87
|
-
@track = comment.getbyte(-1)
|
88
|
-
comment = comment.byteslice(0..-3)
|
89
|
-
end
|
85
|
+
comment = @file_io.read(30)
|
90
86
|
|
91
|
-
|
92
|
-
@
|
87
|
+
if comment.getbyte(-2) == 0
|
88
|
+
@track = comment.getbyte(-1)
|
89
|
+
comment = comment.byteslice(0..-3)
|
93
90
|
end
|
91
|
+
|
92
|
+
@comments.push(Helper.encode_to_utf8(comment, source_encoding: DEFAULT_ENCODING))
|
93
|
+
@genre = GENRES[@file_io.getbyte] || ""
|
94
|
+
end
|
94
95
|
end
|
95
96
|
end
|
96
97
|
end
|
data/lib/wahwah/id3/v2.rb
CHANGED
@@ -12,50 +12,56 @@ module WahWah
|
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
|
-
def parse
|
16
|
-
@file_io.rewind
|
17
|
-
@header = V2Header.new(@file_io)
|
18
15
|
|
19
|
-
|
16
|
+
def parse
|
17
|
+
@file_io.rewind
|
18
|
+
@header = V2Header.new(@file_io)
|
20
19
|
|
21
|
-
|
22
|
-
frame = ID3::Frame.new(@file_io, major_version)
|
23
|
-
(frame.skip; next) unless frame.valid?
|
20
|
+
return unless valid?
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
end
|
22
|
+
until end_of_tag?
|
23
|
+
frame = ID3::Frame.new(@file_io, major_version)
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
case name
|
33
|
-
when :comment
|
34
|
-
# Because there may be more than one comment frame in each tag,
|
35
|
-
# so push it into a array.
|
36
|
-
@comments.push(frame.value)
|
37
|
-
when :image
|
38
|
-
# Because there may be more than one image frame in each tag,
|
39
|
-
# so push it into a array.
|
40
|
-
@images_data.push(frame); frame.skip
|
41
|
-
when :track, :disc
|
42
|
-
# Track and disc value may be extended with a "/" character
|
43
|
-
# and a numeric string containing the total numer.
|
44
|
-
count, total_count = frame.value.split('/', 2)
|
45
|
-
instance_variable_set("@#{name}", count)
|
46
|
-
instance_variable_set("@#{name}_total", total_count) unless total_count.nil?
|
47
|
-
else
|
48
|
-
instance_variable_set("@#{name}", frame.value)
|
25
|
+
unless frame.valid?
|
26
|
+
frame.skip
|
27
|
+
next
|
49
28
|
end
|
50
|
-
end
|
51
29
|
|
52
|
-
|
53
|
-
size <= @file_io.pos || file_size <= @file_io.pos
|
30
|
+
update_attribute(frame)
|
54
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_attribute(frame)
|
35
|
+
name = frame.name
|
55
36
|
|
56
|
-
|
57
|
-
|
37
|
+
case name
|
38
|
+
when :comment
|
39
|
+
# Because there may be more than one comment frame in each tag,
|
40
|
+
# so push it into a array.
|
41
|
+
@comments.push(frame.value)
|
42
|
+
when :image
|
43
|
+
# Because there may be more than one image frame in each tag,
|
44
|
+
# so push it into a array.
|
45
|
+
@images_data.push(frame)
|
46
|
+
frame.skip
|
47
|
+
when :track, :disc
|
48
|
+
# Track and disc value may be extended with a "/" character
|
49
|
+
# and a numeric string containing the total numer.
|
50
|
+
count, total_count = frame.value.split("/", 2)
|
51
|
+
instance_variable_set("@#{name}", count)
|
52
|
+
instance_variable_set("@#{name}_total", total_count) unless total_count.nil?
|
53
|
+
else
|
54
|
+
instance_variable_set("@#{name}", frame.value)
|
58
55
|
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def end_of_tag?
|
59
|
+
size <= @file_io.pos || file_size <= @file_io.pos
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_image_data(image_frame)
|
63
|
+
image_frame.value
|
64
|
+
end
|
59
65
|
end
|
60
66
|
end
|
61
67
|
end
|
data/lib/wahwah/id3/v2_header.rb
CHANGED
@@ -10,9 +10,9 @@ module WahWah
|
|
10
10
|
# ID3v2 flags %abc00000
|
11
11
|
# ID3v2 size 4 * %0xxxxxxx
|
12
12
|
class V2Header
|
13
|
-
TAG_ID =
|
13
|
+
TAG_ID = "ID3"
|
14
14
|
HEADER_SIZE = 10
|
15
|
-
HEADER_FORMAT =
|
15
|
+
HEADER_FORMAT = "A3CxB8B*"
|
16
16
|
|
17
17
|
attr_reader :major_version, :size
|
18
18
|
|
@@ -34,7 +34,7 @@ module WahWah
|
|
34
34
|
# Size of padding $xx xx xx xx
|
35
35
|
|
36
36
|
# Skip extended_header
|
37
|
-
extended_header_size = Helper.id3_size_caculate(file_io.read(4).
|
37
|
+
extended_header_size = Helper.id3_size_caculate(file_io.read(4).unpack1("B32"))
|
38
38
|
file_io.seek(extended_header_size - 4, IO::SEEK_CUR)
|
39
39
|
end
|
40
40
|
end
|
@@ -46,7 +46,7 @@ module WahWah
|
|
46
46
|
# The second bit in flags byte indicates whether or not the header
|
47
47
|
# is followed by an extended header.
|
48
48
|
def has_extended_header?
|
49
|
-
@flags[1] ==
|
49
|
+
@flags[1] == "1"
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|