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/ogg/packets.rb
CHANGED
@@ -20,7 +20,7 @@ module WahWah
|
|
20
20
|
def each
|
21
21
|
@file_io.rewind
|
22
22
|
|
23
|
-
packet = +
|
23
|
+
packet = +""
|
24
24
|
pages = Ogg::Pages.new(@file_io)
|
25
25
|
|
26
26
|
pages.each do |page|
|
@@ -31,7 +31,7 @@ module WahWah
|
|
31
31
|
# So when segment length is less than 255 byte, it's the final segment.
|
32
32
|
if segment.length < 255
|
33
33
|
yield packet
|
34
|
-
packet = +
|
34
|
+
packet = +""
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/wahwah/ogg/page.rb
CHANGED
@@ -99,7 +99,7 @@ module WahWah
|
|
99
99
|
# lacing value.
|
100
100
|
class Page
|
101
101
|
HEADER_SIZE = 27
|
102
|
-
HEADER_FORMAT =
|
102
|
+
HEADER_FORMAT = "A4CxQx12C"
|
103
103
|
|
104
104
|
attr_reader :segments, :granule_position
|
105
105
|
|
@@ -109,12 +109,12 @@ module WahWah
|
|
109
109
|
|
110
110
|
return unless valid?
|
111
111
|
|
112
|
-
segment_table = file_io.read(page_segments).unpack(
|
112
|
+
segment_table = file_io.read(page_segments).unpack("C" * page_segments)
|
113
113
|
@segments = segment_table.map { |segment_length| file_io.read(segment_length) }
|
114
114
|
end
|
115
115
|
|
116
116
|
def valid?
|
117
|
-
@capture_pattern ==
|
117
|
+
@capture_pattern == "OggS" && @version == 0
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|
@@ -16,32 +16,32 @@ module WahWah
|
|
16
16
|
# 9) done.
|
17
17
|
module VorbisComment
|
18
18
|
COMMET_FIELD_MAPPING = {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
19
|
+
"TITLE" => :title,
|
20
|
+
"ALBUM" => :album,
|
21
|
+
"ALBUMARTIST" => :albumartist,
|
22
|
+
"TRACKNUMBER" => :track,
|
23
|
+
"ARTIST" => :artist,
|
24
|
+
"DATE" => :year,
|
25
|
+
"GENRE" => :genre,
|
26
|
+
"DISCNUMBER" => :disc,
|
27
|
+
"COMPOSER" => :composer
|
28
28
|
}
|
29
29
|
|
30
30
|
def parse_vorbis_comment(comment_content)
|
31
31
|
comment_content = StringIO.new(comment_content)
|
32
32
|
|
33
|
-
vendor_length = comment_content.read(4).
|
33
|
+
vendor_length = comment_content.read(4).unpack1("V")
|
34
34
|
comment_content.seek(vendor_length, IO::SEEK_CUR) # Skip vendor_string
|
35
35
|
|
36
|
-
comment_list_length = comment_content.read(4).
|
36
|
+
comment_list_length = comment_content.read(4).unpack1("V")
|
37
37
|
|
38
38
|
comment_list_length.times do
|
39
|
-
comment_length = comment_content.read(4).
|
39
|
+
comment_length = comment_content.read(4).unpack1("V")
|
40
40
|
comment = Helper.encode_to_utf8(comment_content.read(comment_length))
|
41
|
-
field_name, field_value = comment.split(
|
41
|
+
field_name, field_value = comment.split("=", 2)
|
42
42
|
attr_name = COMMET_FIELD_MAPPING[field_name&.upcase]
|
43
43
|
|
44
|
-
field_value = field_value.to_i if %i
|
44
|
+
field_value = field_value.to_i if %i[track disc].include? attr_name
|
45
45
|
|
46
46
|
instance_variable_set("@#{attr_name}", field_value) unless attr_name.nil?
|
47
47
|
end
|
@@ -20,10 +20,10 @@ module WahWah
|
|
20
20
|
# 8) [blocksize_0] = 2 exponent (read 4 bits as unsigned integer)
|
21
21
|
# 9) [blocksize_1] = 2 exponent (read 4 bits as unsigned integer)
|
22
22
|
# 10) [framing_flag] = read one bit
|
23
|
-
@sample_rate, bitrate = identification_packet[12, 12].unpack(
|
23
|
+
@sample_rate, bitrate = identification_packet[12, 12].unpack("Vx4V")
|
24
24
|
@bitrate = bitrate / 1000
|
25
25
|
|
26
|
-
comment_packet_id, comment_packet_body = [comment_packet[0..6], comment_packet[7
|
26
|
+
comment_packet_id, comment_packet_body = [comment_packet[0..6], comment_packet[7..]]
|
27
27
|
|
28
28
|
# Vorbis comment packet start with "\x03vorbis"
|
29
29
|
return unless comment_packet_id == "\x03vorbis"
|
data/lib/wahwah/ogg_tag.rb
CHANGED
@@ -17,50 +17,50 @@ module WahWah
|
|
17
17
|
:sample_rate
|
18
18
|
|
19
19
|
private
|
20
|
-
def packets
|
21
|
-
@packets ||= Ogg::Packets.new(@file_io)
|
22
|
-
end
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
def packets
|
22
|
+
@packets ||= Ogg::Packets.new(@file_io)
|
23
|
+
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
def pages
|
26
|
+
@pages ||= Ogg::Pages.new(@file_io)
|
27
|
+
end
|
31
28
|
|
32
|
-
|
29
|
+
def parse
|
30
|
+
identification_packet, comment_packet = packets.first(2)
|
31
|
+
return if identification_packet.nil? || comment_packet.nil?
|
33
32
|
|
34
|
-
|
35
|
-
when identification_packet.start_with?("\x01vorbis")
|
36
|
-
Ogg::VorbisTag.new(identification_packet, comment_packet)
|
37
|
-
when identification_packet.start_with?('OpusHead')
|
38
|
-
Ogg::OpusTag.new(identification_packet, comment_packet)
|
39
|
-
when identification_packet.start_with?("\x7FFLAC")
|
40
|
-
Ogg::FlacTag.new(identification_packet, comment_packet)
|
41
|
-
end
|
33
|
+
@overhead_packets_size = identification_packet.size + comment_packet.size
|
42
34
|
|
43
|
-
|
44
|
-
|
45
|
-
|
35
|
+
@tag = if identification_packet.start_with?("\x01vorbis")
|
36
|
+
Ogg::VorbisTag.new(identification_packet, comment_packet)
|
37
|
+
elsif identification_packet.start_with?("OpusHead")
|
38
|
+
Ogg::OpusTag.new(identification_packet, comment_packet)
|
39
|
+
elsif identification_packet.start_with?("\x7FFLAC")
|
40
|
+
Ogg::FlacTag.new(identification_packet, comment_packet)
|
46
41
|
end
|
47
42
|
|
48
|
-
|
49
|
-
|
43
|
+
@duration = parse_duration
|
44
|
+
@bitrate = parse_bitrate
|
45
|
+
@bit_depth = parse_bit_depth
|
46
|
+
end
|
50
47
|
|
51
|
-
|
52
|
-
|
48
|
+
def parse_duration
|
49
|
+
return @tag.duration if @tag.respond_to? :duration
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
last_page = pages.to_a.last
|
52
|
+
pre_skip = @tag.respond_to?(:pre_skip) ? @tag.pre_skip : 0
|
56
53
|
|
57
|
-
|
58
|
-
|
59
|
-
((file_size - @overhead_packets_size) * 8.0 / duration / 1000).round
|
60
|
-
end
|
54
|
+
(last_page.granule_position - pre_skip) / @tag.sample_rate.to_f
|
55
|
+
end
|
61
56
|
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
def parse_bitrate
|
58
|
+
return @tag.bitrate if @tag.respond_to? :bitrate
|
59
|
+
((file_size - @overhead_packets_size) * 8.0 / duration / 1000).round
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_bit_depth
|
63
|
+
@tag.bit_depth if @tag.respond_to? :bit_depth
|
64
|
+
end
|
65
65
|
end
|
66
66
|
end
|
data/lib/wahwah/riff/chunk.rb
CHANGED
@@ -19,7 +19,7 @@ module WahWah
|
|
19
19
|
prepend LazyRead
|
20
20
|
|
21
21
|
HEADER_SIZE = 8
|
22
|
-
HEADER_FORMAT =
|
22
|
+
HEADER_FORMAT = "A4V"
|
23
23
|
HEADER_TYPE_SIZE = 4
|
24
24
|
|
25
25
|
attr_reader :id, :type
|
@@ -28,11 +28,11 @@ module WahWah
|
|
28
28
|
@id, @size = @file_io.read(HEADER_SIZE)&.unpack(HEADER_FORMAT)
|
29
29
|
return unless valid?
|
30
30
|
|
31
|
-
@type = @file_io.read(HEADER_TYPE_SIZE).
|
31
|
+
@type = @file_io.read(HEADER_TYPE_SIZE).unpack1("A4") if have_type?
|
32
32
|
end
|
33
33
|
|
34
34
|
def size
|
35
|
-
@size
|
35
|
+
@size += 1 if @size.odd?
|
36
36
|
have_type? ? @size - HEADER_TYPE_SIZE : @size
|
37
37
|
end
|
38
38
|
|
@@ -41,9 +41,10 @@ module WahWah
|
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
|
45
|
+
def have_type?
|
46
|
+
%w[RIFF LIST].include? @id
|
47
|
+
end
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
data/lib/wahwah/riff_tag.rb
CHANGED
@@ -17,7 +17,7 @@ module WahWah
|
|
17
17
|
TRCK: :track
|
18
18
|
}
|
19
19
|
|
20
|
-
CHANNEL_MODE_INDEX = %w
|
20
|
+
CHANNEL_MODE_INDEX = %w[Mono Stereo]
|
21
21
|
|
22
22
|
tag_delegate :@id3_tag,
|
23
23
|
:title,
|
@@ -39,102 +39,104 @@ module WahWah
|
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
42
|
-
def parse
|
43
|
-
top_chunk = Riff::Chunk.new(@file_io)
|
44
|
-
return unless top_chunk.valid?
|
45
42
|
|
46
|
-
|
43
|
+
def parse
|
44
|
+
top_chunk = Riff::Chunk.new(@file_io)
|
45
|
+
return unless top_chunk.valid?
|
47
46
|
|
48
|
-
|
49
|
-
# This additional field provides the form type of the field.
|
50
|
-
# For wav file, the value of the type field is 'WAVE'
|
51
|
-
return unless top_chunk.id == 'RIFF' && top_chunk.type == 'WAVE'
|
47
|
+
total_chunk_size = top_chunk.size + Riff::Chunk::HEADER_SIZE
|
52
48
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
49
|
+
# The top "RIFF" chunks include an additional field in the first four bytes of the data field.
|
50
|
+
# This additional field provides the form type of the field.
|
51
|
+
# For wav file, the value of the type field is 'WAVE'
|
52
|
+
return unless top_chunk.id == "RIFF" && top_chunk.type == "WAVE"
|
58
53
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
case sub_chunk.id
|
63
|
-
when 'fmt'
|
64
|
-
parse_fmt_chunk(sub_chunk)
|
65
|
-
when 'data'
|
66
|
-
parse_data_chunk(sub_chunk)
|
67
|
-
when 'LIST'
|
68
|
-
parse_list_chunk(sub_chunk)
|
69
|
-
when 'id3', 'ID3'
|
70
|
-
parse_id3_chunk(sub_chunk)
|
71
|
-
else
|
72
|
-
sub_chunk.skip
|
73
|
-
end
|
54
|
+
until total_chunk_size <= @file_io.pos || @file_io.eof?
|
55
|
+
sub_chunk = Riff::Chunk.new(@file_io)
|
56
|
+
parse_sub_chunk(sub_chunk)
|
74
57
|
end
|
58
|
+
end
|
75
59
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# The number of bytes for one sample including
|
91
|
-
# all channels.
|
92
|
-
#
|
93
|
-
# 2(little endian) BitsPerSample 8 bits = 8, 16 bits = 16, etc.
|
94
|
-
def parse_fmt_chunk(chunk)
|
95
|
-
_, @channel, @sample_rate, _, _, @bit_depth = chunk.data.unpack('vvVVvv')
|
96
|
-
@bitrate = @sample_rate * @channel * @bit_depth / 1000
|
60
|
+
def parse_sub_chunk(sub_chunk)
|
61
|
+
return unless sub_chunk.valid?
|
62
|
+
|
63
|
+
case sub_chunk.id
|
64
|
+
when "fmt"
|
65
|
+
parse_fmt_chunk(sub_chunk)
|
66
|
+
when "data"
|
67
|
+
parse_data_chunk(sub_chunk)
|
68
|
+
when "LIST"
|
69
|
+
parse_list_chunk(sub_chunk)
|
70
|
+
when "id3", "ID3"
|
71
|
+
parse_id3_chunk(sub_chunk)
|
72
|
+
else
|
73
|
+
sub_chunk.skip
|
97
74
|
end
|
75
|
+
end
|
98
76
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
77
|
+
# The fmt chunk data structure:
|
78
|
+
# Length Meaning Description
|
79
|
+
#
|
80
|
+
# 2(little endian) AudioFormat PCM = 1 (i.e. Linear quantization)
|
81
|
+
# Values other than 1 indicate some
|
82
|
+
# form of compression.
|
83
|
+
#
|
84
|
+
# 2(little endian) NumChannels Mono = 1, Stereo = 2, etc.
|
85
|
+
#
|
86
|
+
# 4(little endian) SampleRate 8000, 44100, etc.
|
87
|
+
#
|
88
|
+
# 4(little endian) ByteRate == SampleRate * NumChannels * BitsPerSample/8
|
89
|
+
#
|
90
|
+
# 2(little endian) BlockAlign == NumChannels * BitsPerSample/8
|
91
|
+
# The number of bytes for one sample including
|
92
|
+
# all channels.
|
93
|
+
#
|
94
|
+
# 2(little endian) BitsPerSample 8 bits = 8, 16 bits = 16, etc.
|
95
|
+
def parse_fmt_chunk(chunk)
|
96
|
+
_, @channel, @sample_rate, _, _, @bit_depth = chunk.data.unpack("vvVVvv")
|
97
|
+
@bitrate = @sample_rate * @channel * @bit_depth / 1000
|
98
|
+
end
|
103
99
|
|
104
|
-
|
105
|
-
|
100
|
+
def parse_data_chunk(chunk)
|
101
|
+
@duration = chunk.size * 8 / (@bitrate * 1000).to_f
|
102
|
+
chunk.skip
|
103
|
+
end
|
106
104
|
|
107
|
-
|
108
|
-
|
109
|
-
if chunk.type != 'INFO'
|
110
|
-
chunk.skip
|
111
|
-
else
|
112
|
-
until list_chunk_end_position <= @file_io.pos do
|
113
|
-
info_chunk = Riff::Chunk.new(@file_io)
|
105
|
+
def parse_list_chunk(chunk)
|
106
|
+
list_chunk_end_position = @file_io.pos + chunk.size
|
114
107
|
|
115
|
-
|
116
|
-
|
117
|
-
|
108
|
+
# RIFF can be tagged with metadata in the INFO chunk.
|
109
|
+
# And INFO chunk as a subchunk for LIST chunk.
|
110
|
+
if chunk.type != "INFO"
|
111
|
+
chunk.skip
|
112
|
+
else
|
113
|
+
until list_chunk_end_position <= @file_io.pos
|
114
|
+
info_chunk = Riff::Chunk.new(@file_io)
|
118
115
|
|
119
|
-
|
116
|
+
unless INFO_ID_MAPPING.key? info_chunk.id.to_sym
|
117
|
+
info_chunk.skip
|
118
|
+
next
|
120
119
|
end
|
120
|
+
|
121
|
+
update_attribute(info_chunk)
|
121
122
|
end
|
122
123
|
end
|
124
|
+
end
|
123
125
|
|
124
|
-
|
125
|
-
|
126
|
-
|
126
|
+
def parse_id3_chunk(chunk)
|
127
|
+
@id3_tag = ID3::V2.new(StringIO.new(chunk.data))
|
128
|
+
end
|
127
129
|
|
128
|
-
|
129
|
-
|
130
|
-
|
130
|
+
def update_attribute(chunk)
|
131
|
+
attr_name = INFO_ID_MAPPING[chunk.id.to_sym]
|
132
|
+
chunk_data = Helper.encode_to_utf8(chunk.data)
|
131
133
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
134
|
+
case attr_name
|
135
|
+
when :comment
|
136
|
+
@comments.push(chunk_data)
|
137
|
+
else
|
138
|
+
instance_variable_set("@#{attr_name}", chunk_data)
|
138
139
|
end
|
140
|
+
end
|
139
141
|
end
|
140
142
|
end
|
data/lib/wahwah/tag.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module WahWah
|
4
4
|
class Tag
|
5
|
-
INTEGER_ATTRIBUTES = %i
|
6
|
-
INSPECT_ATTRIBUTES = %i
|
5
|
+
INTEGER_ATTRIBUTES = %i[disc disc_total track track_total]
|
6
|
+
INSPECT_ATTRIBUTES = %i[title artist album albumartist composer track track_total genre year disc disc_total duration bitrate sample_rate bit_depth]
|
7
7
|
|
8
8
|
attr_reader(
|
9
9
|
:title,
|
@@ -48,8 +48,8 @@ module WahWah
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def inspect
|
51
|
-
inspect_id = ::Kernel.format
|
52
|
-
inspect_attributes_values = INSPECT_ATTRIBUTES.map { |attr_name| "#{attr_name}=#{
|
51
|
+
inspect_id = ::Kernel.format "%x", (object_id * 2)
|
52
|
+
inspect_attributes_values = INSPECT_ATTRIBUTES.map { |attr_name| "#{attr_name}=#{send(attr_name)}" }.join(" ")
|
53
53
|
|
54
54
|
"<#{self.class.name}:0x#{inspect_id} #{inspect_attributes_values}>"
|
55
55
|
end
|
@@ -63,8 +63,9 @@ module WahWah
|
|
63
63
|
end
|
64
64
|
|
65
65
|
private
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
|
67
|
+
def parse
|
68
|
+
raise WahWahNotImplementedError, "The parse method is not implemented"
|
69
|
+
end
|
69
70
|
end
|
70
71
|
end
|
data/lib/wahwah/version.rb
CHANGED
data/lib/wahwah.rb
CHANGED
@@ -1,62 +1,62 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
|
28
|
-
require
|
29
|
-
|
30
|
-
require
|
31
|
-
require
|
32
|
-
|
33
|
-
require
|
34
|
-
require
|
35
|
-
require
|
36
|
-
require
|
37
|
-
require
|
38
|
-
require
|
39
|
-
require
|
40
|
-
|
41
|
-
require
|
42
|
-
|
43
|
-
require
|
44
|
-
|
45
|
-
require
|
46
|
-
require
|
47
|
-
require
|
48
|
-
require
|
49
|
-
require
|
50
|
-
require
|
3
|
+
require "stringio"
|
4
|
+
require "forwardable"
|
5
|
+
require "zlib"
|
6
|
+
|
7
|
+
require "wahwah/version"
|
8
|
+
require "wahwah/errors"
|
9
|
+
require "wahwah/helper"
|
10
|
+
require "wahwah/tag_delegate"
|
11
|
+
require "wahwah/lazy_read"
|
12
|
+
require "wahwah/tag"
|
13
|
+
|
14
|
+
require "wahwah/id3/v1"
|
15
|
+
require "wahwah/id3/v2"
|
16
|
+
require "wahwah/id3/v2_header"
|
17
|
+
require "wahwah/id3/frame"
|
18
|
+
require "wahwah/id3/frame_body"
|
19
|
+
require "wahwah/id3/text_frame_body"
|
20
|
+
require "wahwah/id3/genre_frame_body"
|
21
|
+
require "wahwah/id3/comment_frame_body"
|
22
|
+
require "wahwah/id3/image_frame_body"
|
23
|
+
|
24
|
+
require "wahwah/mp3/mpeg_frame_header"
|
25
|
+
require "wahwah/mp3/xing_header"
|
26
|
+
require "wahwah/mp3/vbri_header"
|
27
|
+
|
28
|
+
require "wahwah/riff/chunk"
|
29
|
+
|
30
|
+
require "wahwah/flac/block"
|
31
|
+
require "wahwah/flac/streaminfo_block"
|
32
|
+
|
33
|
+
require "wahwah/ogg/page"
|
34
|
+
require "wahwah/ogg/pages"
|
35
|
+
require "wahwah/ogg/packets"
|
36
|
+
require "wahwah/ogg/vorbis_comment"
|
37
|
+
require "wahwah/ogg/vorbis_tag"
|
38
|
+
require "wahwah/ogg/opus_tag"
|
39
|
+
require "wahwah/ogg/flac_tag"
|
40
|
+
|
41
|
+
require "wahwah/asf/object"
|
42
|
+
|
43
|
+
require "wahwah/mp4/atom"
|
44
|
+
|
45
|
+
require "wahwah/mp3_tag"
|
46
|
+
require "wahwah/mp4_tag"
|
47
|
+
require "wahwah/ogg_tag"
|
48
|
+
require "wahwah/riff_tag"
|
49
|
+
require "wahwah/asf_tag"
|
50
|
+
require "wahwah/flac_tag"
|
51
51
|
|
52
52
|
module WahWah
|
53
53
|
FORMATE_MAPPING = {
|
54
|
-
Mp3Tag: [
|
55
|
-
OggTag: [
|
56
|
-
RiffTag: [
|
57
|
-
FlacTag: [
|
58
|
-
AsfTag: [
|
59
|
-
Mp4Tag: [
|
54
|
+
Mp3Tag: ["mp3"],
|
55
|
+
OggTag: ["ogg", "oga", "opus"],
|
56
|
+
RiffTag: ["wav"],
|
57
|
+
FlacTag: ["flac"],
|
58
|
+
AsfTag: ["wma"],
|
59
|
+
Mp4Tag: ["m4a"]
|
60
60
|
}.freeze
|
61
61
|
|
62
62
|
def self.open(file_path)
|
@@ -65,10 +65,10 @@ module WahWah
|
|
65
65
|
|
66
66
|
file_format = Helper.file_format(file_path)
|
67
67
|
|
68
|
-
raise WahWahArgumentError,
|
69
|
-
raise WahWahArgumentError,
|
70
|
-
raise WahWahArgumentError,
|
71
|
-
raise WahWahArgumentError,
|
68
|
+
raise WahWahArgumentError, "File is not exists" unless File.exist? file_path
|
69
|
+
raise WahWahArgumentError, "File is unreadable" unless File.readable? file_path
|
70
|
+
raise WahWahArgumentError, "File is empty" unless File.size(file_path) > 0
|
71
|
+
raise WahWahArgumentError, "No supported format found" unless support_formats.include? file_format
|
72
72
|
|
73
73
|
FORMATE_MAPPING.each do |tag, formats|
|
74
74
|
break const_get(tag).new(file_path) if formats.include?(file_format)
|