wahwah 0.1.0.pre.test → 0.1.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/.gitignore +8 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +22 -0
- data/README.md +35 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/wahwah.rb +3 -74
- data/lib/wahwah/version.rb +2 -4
- data/wahwah.gemspec +27 -0
- metadata +25 -96
- data/LICENSE +0 -21
- data/lib/wahwah/asf/object.rb +0 -39
- data/lib/wahwah/asf_tag.rb +0 -220
- data/lib/wahwah/errors.rb +0 -6
- data/lib/wahwah/flac/block.rb +0 -57
- data/lib/wahwah/flac/streaminfo_block.rb +0 -51
- data/lib/wahwah/flac_tag.rb +0 -84
- data/lib/wahwah/helper.rb +0 -37
- data/lib/wahwah/id3/comment_frame_body.rb +0 -21
- data/lib/wahwah/id3/frame.rb +0 -180
- data/lib/wahwah/id3/frame_body.rb +0 -36
- data/lib/wahwah/id3/genre_frame_body.rb +0 -15
- data/lib/wahwah/id3/image_frame_body.rb +0 -60
- data/lib/wahwah/id3/text_frame_body.rb +0 -16
- data/lib/wahwah/id3/v1.rb +0 -96
- data/lib/wahwah/id3/v2.rb +0 -60
- data/lib/wahwah/id3/v2_header.rb +0 -53
- data/lib/wahwah/mp3/mpeg_frame_header.rb +0 -141
- data/lib/wahwah/mp3/vbri_header.rb +0 -47
- data/lib/wahwah/mp3/xing_header.rb +0 -45
- data/lib/wahwah/mp3_tag.rb +0 -110
- data/lib/wahwah/mp4/atom.rb +0 -105
- data/lib/wahwah/mp4_tag.rb +0 -126
- data/lib/wahwah/ogg/flac_tag.rb +0 -37
- data/lib/wahwah/ogg/opus_tag.rb +0 -33
- data/lib/wahwah/ogg/packets.rb +0 -41
- data/lib/wahwah/ogg/page.rb +0 -121
- data/lib/wahwah/ogg/pages.rb +0 -24
- data/lib/wahwah/ogg/vorbis_comment.rb +0 -51
- data/lib/wahwah/ogg/vorbis_tag.rb +0 -35
- data/lib/wahwah/ogg_tag.rb +0 -66
- data/lib/wahwah/riff/chunk.rb +0 -54
- data/lib/wahwah/riff_tag.rb +0 -140
- data/lib/wahwah/tag.rb +0 -59
- data/lib/wahwah/tag_delegate.rb +0 -16
data/lib/wahwah/helper.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WahWah
|
4
|
-
module Helper
|
5
|
-
def self.encode_to_utf8(string, source_encoding: '')
|
6
|
-
encoded_string = source_encoding.empty? ?
|
7
|
-
string.force_encoding('utf-8') :
|
8
|
-
string.encode('utf-8', source_encoding, invalid: :replace, undef: :replace, replace: '')
|
9
|
-
|
10
|
-
encoded_string.valid_encoding? ? encoded_string.strip : ''
|
11
|
-
end
|
12
|
-
|
13
|
-
# ID3 size is encoded with four bytes where may the most significant
|
14
|
-
# bit (bit 7) is set to zero in every byte,
|
15
|
-
# making a total of 28 bits. The zeroed bits are ignored
|
16
|
-
def self.id3_size_caculate(bits_string, has_zero_bit: true)
|
17
|
-
if has_zero_bit
|
18
|
-
bits_string.scan(/.{8}/).map { |byte_string| byte_string[1..-1] }.join.to_i(2)
|
19
|
-
else
|
20
|
-
bits_string.to_i(2)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.split_with_terminator(string, terminator_size)
|
25
|
-
string.split(Regexp.new(('\x00' * terminator_size).b), 2)
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.file_format(file_path)
|
29
|
-
File.extname(file_path).downcase.delete('.')
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.byte_string_to_guid(byte_string)
|
33
|
-
guid = byte_string.unpack('NnnA*').pack('VvvA*').unpack('H*').first
|
34
|
-
[guid[0..7], guid[8..11], guid[12..15], guid[16..19], guid[20..-1]].join('-').upcase
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WahWah
|
4
|
-
module ID3
|
5
|
-
class CommentFrameBody < FrameBody
|
6
|
-
# Comment frame body structure:
|
7
|
-
#
|
8
|
-
# Text encoding $xx
|
9
|
-
# Language $xx xx xx
|
10
|
-
# Short content description <textstring> $00 (00)
|
11
|
-
# The actual text <textstring>
|
12
|
-
def parse
|
13
|
-
encoding_id, _language, reset_content = @content.unpack('CA3a*')
|
14
|
-
encoding = ENCODING_MAPPING[encoding_id]
|
15
|
-
_description, comment_text = Helper.split_with_terminator(reset_content, ENCODING_TERMINATOR_SIZE[encoding])
|
16
|
-
|
17
|
-
@value = Helper.encode_to_utf8(comment_text, source_encoding: encoding)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/wahwah/id3/frame.rb
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'zlib'
|
4
|
-
|
5
|
-
module WahWah
|
6
|
-
module ID3
|
7
|
-
class Frame
|
8
|
-
ID_MAPPING = {
|
9
|
-
# ID3v2.2 frame id
|
10
|
-
COM: :comment,
|
11
|
-
TRK: :track,
|
12
|
-
TYE: :year,
|
13
|
-
TAL: :album,
|
14
|
-
TP1: :artist,
|
15
|
-
TT2: :title,
|
16
|
-
TCO: :genre,
|
17
|
-
TPA: :disc,
|
18
|
-
TP2: :albumartist,
|
19
|
-
TCM: :composer,
|
20
|
-
PIC: :image,
|
21
|
-
|
22
|
-
# ID3v2.3 and ID3v2.4 frame id
|
23
|
-
COMM: :comment,
|
24
|
-
TRCK: :track,
|
25
|
-
TYER: :year,
|
26
|
-
TALB: :album,
|
27
|
-
TPE1: :artist,
|
28
|
-
TIT2: :title,
|
29
|
-
TCON: :genre,
|
30
|
-
TPOS: :disc,
|
31
|
-
TPE2: :albumartist,
|
32
|
-
TCOM: :composer,
|
33
|
-
APIC: :image,
|
34
|
-
|
35
|
-
# ID3v2.4 use TDRC replace TYER
|
36
|
-
TDRC: :year
|
37
|
-
}
|
38
|
-
|
39
|
-
# ID3v2.3 frame flags field is defined as follows.
|
40
|
-
#
|
41
|
-
# %abc00000 %ijk00000
|
42
|
-
#
|
43
|
-
# a - Tag alter preservation
|
44
|
-
# b - File alter preservation
|
45
|
-
# c - Read only
|
46
|
-
# i - Compression
|
47
|
-
# j - Encryption
|
48
|
-
# k - Grouping identity
|
49
|
-
V3_HEADER_FLAGS_INDICATIONS = Array.new(16).tap do |array|
|
50
|
-
array[0] = :tag_alter_preservation
|
51
|
-
array[1] = :file_alter_preservation
|
52
|
-
array[2] = :read_only
|
53
|
-
array[8] = :compression
|
54
|
-
array[9] = :encryption
|
55
|
-
array[10] = :grouping_identity
|
56
|
-
end
|
57
|
-
|
58
|
-
# ID3v2.4 frame flags field is defined as follows.
|
59
|
-
#
|
60
|
-
# %0abc0000 %0h00kmnp
|
61
|
-
#
|
62
|
-
# a - Tag alter preservation
|
63
|
-
# b - File alter preservation
|
64
|
-
# c - Read only
|
65
|
-
# h - Grouping identity
|
66
|
-
# k - Compression
|
67
|
-
# m - Encryption
|
68
|
-
# n - Unsynchronisation
|
69
|
-
# p - Data length indicator
|
70
|
-
V4_HEADER_FLAGS_INDICATIONS = Array.new(16).tap do |array|
|
71
|
-
array[1] = :tag_alter_preservation
|
72
|
-
array[2] = :file_alter_preservation
|
73
|
-
array[3] = :read_only
|
74
|
-
array[9] = :grouping_identity
|
75
|
-
array[12] = :compression
|
76
|
-
array[13] = :encryption
|
77
|
-
array[14] = :unsynchronisation
|
78
|
-
array[15] = :data_length_indicator
|
79
|
-
end
|
80
|
-
|
81
|
-
attr_reader :name, :value
|
82
|
-
|
83
|
-
def initialize(file_io, version)
|
84
|
-
@file_io = file_io
|
85
|
-
@version = version
|
86
|
-
|
87
|
-
parse_frame_header
|
88
|
-
|
89
|
-
# In ID3v2.3 when frame is compressed using zlib
|
90
|
-
# with 4 bytes for 'decompressed size' appended to the frame header.
|
91
|
-
#
|
92
|
-
# In ID3v2.4 A 'Data Length Indicator' byte MUST be included in the frame
|
93
|
-
# when frame is compressed, and 'Data Length Indicator'represented as a 32 bit
|
94
|
-
# synchsafe integer
|
95
|
-
#
|
96
|
-
# So skip those 4 byte.
|
97
|
-
if compressed? || data_length_indicator?
|
98
|
-
@file_io.seek(4, IO::SEEK_CUR)
|
99
|
-
@size = @size - 4
|
100
|
-
end
|
101
|
-
|
102
|
-
parse_body
|
103
|
-
end
|
104
|
-
|
105
|
-
def valid?
|
106
|
-
@size > 0 && !@name.nil?
|
107
|
-
end
|
108
|
-
|
109
|
-
def compressed?
|
110
|
-
@flags.include? :compression
|
111
|
-
end
|
112
|
-
|
113
|
-
def data_length_indicator?
|
114
|
-
@flags.include? :data_length_indicator
|
115
|
-
end
|
116
|
-
|
117
|
-
|
118
|
-
private
|
119
|
-
# ID3v2.2 frame header structure:
|
120
|
-
#
|
121
|
-
# Frame ID $xx xx xx(tree characters)
|
122
|
-
# Size 3 * %xxxxxxxx
|
123
|
-
#
|
124
|
-
# ID3v2.3 frame header structure:
|
125
|
-
#
|
126
|
-
# Frame ID $xx xx xx xx (four characters)
|
127
|
-
# Size 4 * %xxxxxxxx
|
128
|
-
# Flags $xx xx
|
129
|
-
#
|
130
|
-
# ID3v2.4 frame header structure:
|
131
|
-
#
|
132
|
-
# Frame ID $xx xx xx xx (four characters)
|
133
|
-
# Size 4 * %0xxxxxxx
|
134
|
-
# Flags $xx xx
|
135
|
-
def parse_frame_header
|
136
|
-
header_size = @version == 2 ? 6 : 10
|
137
|
-
header_formate = @version == 2 ? 'A3B24' : 'A4B32B16'
|
138
|
-
id, size_bits, flags_bits = @file_io.read(header_size).unpack(header_formate)
|
139
|
-
|
140
|
-
@name = ID_MAPPING[id.to_sym]
|
141
|
-
@size = Helper.id3_size_caculate(size_bits, has_zero_bit: @version == 4)
|
142
|
-
@flags = parse_flags(flags_bits)
|
143
|
-
end
|
144
|
-
|
145
|
-
def parse_flags(flags_bits)
|
146
|
-
return [] if flags_bits.nil?
|
147
|
-
|
148
|
-
frame_flags_indications = @version == 4 ?
|
149
|
-
V4_HEADER_FLAGS_INDICATIONS :
|
150
|
-
V3_HEADER_FLAGS_INDICATIONS
|
151
|
-
|
152
|
-
flags_bits.split('').map.with_index do |flag_bit, index|
|
153
|
-
frame_flags_indications[index] if flag_bit == '1'
|
154
|
-
end.compact
|
155
|
-
end
|
156
|
-
|
157
|
-
def parse_body
|
158
|
-
return unless @size > 0
|
159
|
-
(@file_io.seek(@size, IO::SEEK_CUR); return) if @name.nil?
|
160
|
-
|
161
|
-
content = compressed? ? Zlib.inflate(@file_io.read(@size)) : @file_io.read(@size)
|
162
|
-
frame_body = frame_body_class.new(content, @version)
|
163
|
-
@value = frame_body.value
|
164
|
-
end
|
165
|
-
|
166
|
-
def frame_body_class
|
167
|
-
case @name
|
168
|
-
when :comment
|
169
|
-
CommentFrameBody
|
170
|
-
when :genre
|
171
|
-
GenreFrameBody
|
172
|
-
when :image
|
173
|
-
ImageFrameBody
|
174
|
-
else
|
175
|
-
TextFrameBody
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WahWah
|
4
|
-
module ID3
|
5
|
-
class FrameBody
|
6
|
-
# Textual frames are marked with an encoding byte.
|
7
|
-
#
|
8
|
-
# $00 ISO-8859-1 [ISO-8859-1]. Terminated with $00.
|
9
|
-
# $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM.
|
10
|
-
# $02 UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
|
11
|
-
# $03 UTF-8 [UTF-8] encoded Unicode [UNICODE].
|
12
|
-
ENCODING_MAPPING = %w(ISO-8859-1 UTF-16 UTF-16BE UTF-8)
|
13
|
-
|
14
|
-
ENCODING_TERMINATOR_SIZE = {
|
15
|
-
'ISO-8859-1' => 1,
|
16
|
-
'UTF-16' => 2,
|
17
|
-
'UTF-16BE' => 2,
|
18
|
-
'UTF-8' => 1
|
19
|
-
}
|
20
|
-
|
21
|
-
|
22
|
-
attr_reader :value
|
23
|
-
|
24
|
-
def initialize(content, version)
|
25
|
-
@content = content
|
26
|
-
@version = version
|
27
|
-
|
28
|
-
parse
|
29
|
-
end
|
30
|
-
|
31
|
-
def parse
|
32
|
-
raise WahWahNotImplementedError, 'The parse method is not implemented'
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WahWah
|
4
|
-
module ID3
|
5
|
-
class GenreFrameBody < TextFrameBody
|
6
|
-
def parse
|
7
|
-
super
|
8
|
-
|
9
|
-
# If value is numeric value, or contain numeric value in parens
|
10
|
-
# can use as index for ID3v1 genre list
|
11
|
-
@value = ID3::V1::GENRES[$1.to_i] if @value =~ /^\((\d+)\)$/ || @value =~ /^(\d+)$/
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WahWah
|
4
|
-
module ID3
|
5
|
-
class ImageFrameBody < FrameBody
|
6
|
-
TYPES = %i(
|
7
|
-
other
|
8
|
-
file_icon
|
9
|
-
other_file_icon
|
10
|
-
cover_front
|
11
|
-
cover_back
|
12
|
-
leaflet
|
13
|
-
media
|
14
|
-
lead_artist
|
15
|
-
artist
|
16
|
-
conductor
|
17
|
-
band
|
18
|
-
composer
|
19
|
-
lyricist
|
20
|
-
recording_location
|
21
|
-
during_recording
|
22
|
-
during_performance
|
23
|
-
movie_screen_capture
|
24
|
-
bright_coloured_fish
|
25
|
-
illustration
|
26
|
-
band_logotype
|
27
|
-
publisher_logotype
|
28
|
-
)
|
29
|
-
|
30
|
-
def mime_type
|
31
|
-
mime_type = @mime_type.downcase.yield_self { |type| type == 'jpg' ? 'jpeg' : type }
|
32
|
-
@version > 2 ? mime_type : "image/#{mime_type}"
|
33
|
-
end
|
34
|
-
|
35
|
-
# ID3v2.2 image frame structure:
|
36
|
-
#
|
37
|
-
# Text encoding $xx
|
38
|
-
# Image format $xx xx xx
|
39
|
-
# Picture type $xx
|
40
|
-
# Description <text string according to encoding> $00 (00)
|
41
|
-
# Picture data <binary data>
|
42
|
-
#
|
43
|
-
# ID3v2.3 and ID3v2.4 image frame structure:
|
44
|
-
#
|
45
|
-
# Text encoding $xx
|
46
|
-
# MIME type <text string> $00
|
47
|
-
# Picture type $xx
|
48
|
-
# Description <text string according to encoding> $00 (00)
|
49
|
-
# Picture data <binary data>
|
50
|
-
def parse
|
51
|
-
frame_format = @version > 2 ? 'CZ*Ca*' : 'Ca3Ca*'
|
52
|
-
encoding_id, @mime_type, type_index, reset_content = @content.unpack(frame_format)
|
53
|
-
encoding = ENCODING_MAPPING[encoding_id]
|
54
|
-
_description, data = Helper.split_with_terminator(reset_content, ENCODING_TERMINATOR_SIZE[encoding])
|
55
|
-
|
56
|
-
@value = { data: data, mime_type: mime_type, type: TYPES[type_index] }
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WahWah
|
4
|
-
module ID3
|
5
|
-
class TextFrameBody < FrameBody
|
6
|
-
# Text frame boby structure:
|
7
|
-
#
|
8
|
-
# Text encoding $xx
|
9
|
-
# Information <text string according to encoding>
|
10
|
-
def parse
|
11
|
-
encoding_id, text = @content.unpack('Ca*')
|
12
|
-
@value = Helper.encode_to_utf8(text, source_encoding: ENCODING_MAPPING[encoding_id])
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/lib/wahwah/id3/v1.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WahWah
|
4
|
-
module ID3
|
5
|
-
class V1 < Tag
|
6
|
-
TAG_SIZE = 128
|
7
|
-
TAG_ID = 'TAG'
|
8
|
-
DEFAULT_ENCODING = 'iso-8859-1'
|
9
|
-
GENRES = [
|
10
|
-
# Standard Genres
|
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
|
-
|
24
|
-
# Winamp Extended Genres
|
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
|
-
|
35
|
-
# Added on WinAmp 1.91
|
36
|
-
'Merengue', 'Salsa', 'Thrash Metal', 'Anime', 'Jpop', 'Synthpop',
|
37
|
-
|
38
|
-
# Added on WinAmp 5.6
|
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
|
-
]
|
46
|
-
|
47
|
-
def size
|
48
|
-
TAG_SIZE
|
49
|
-
end
|
50
|
-
|
51
|
-
def version
|
52
|
-
'v1'
|
53
|
-
end
|
54
|
-
|
55
|
-
def valid?
|
56
|
-
@id == TAG_ID
|
57
|
-
end
|
58
|
-
|
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
|
-
|
74
|
-
@file_io.seek(-TAG_SIZE, IO::SEEK_END)
|
75
|
-
@id = Helper.encode_to_utf8(@file_io.read(3), source_encoding: DEFAULT_ENCODING)
|
76
|
-
|
77
|
-
return unless valid?
|
78
|
-
|
79
|
-
@title = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
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)
|
83
|
-
|
84
|
-
comment = @file_io.read(30)
|
85
|
-
|
86
|
-
if comment.getbyte(-2) == 0
|
87
|
-
@track = comment.getbyte(-1)
|
88
|
-
comment = comment.byteslice(0..-3)
|
89
|
-
end
|
90
|
-
|
91
|
-
@comments.push(Helper.encode_to_utf8(comment, source_encoding: DEFAULT_ENCODING))
|
92
|
-
@genre = GENRES[@file_io.getbyte] || ''
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|