wahwah 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5677433a8471c7ed8ba480c0c7d42804e0ad3494edc88135728766b2778bc01
4
- data.tar.gz: 3163af32c9dc394f8da2b538a6356c111aeb85981b33ec6c42babbe4634de1c0
3
+ metadata.gz: e742f50b1a22c7cbbe63ba26506803720bbc44dbfe9943ac07a32e7efe048cbe
4
+ data.tar.gz: 47e1352b98217e34eb3e3fb3c258695a8f7cf2a4d579ce6baaeda1216703f4e8
5
5
  SHA512:
6
- metadata.gz: dc8742ff453a6f1826b2458b2daf78bdef6825dbb0ce4e208d11b5c1456ff998ab2f0ff33223393a9a2366e42fc39652930866c1316434859444f016529ad9bb
7
- data.tar.gz: 1c0a2099a2df566f755f12074ce5628ebaa831d01c679509965cff9b6b950aaa6af0e0c7bd5e6dd6dd770d3868595225645a6f79a32ba5e377eeb01a2ac4cc0c
6
+ metadata.gz: f5450f35d5478a3a434ac0e366589edb3999b40eb1f321e53086ccd1d3d20c5542ce63ac9d8d7b380379cafd719bbc97c33d2768d585c9a2b1d71218950f1b36
7
+ data.tar.gz: 86a134f7ac39a2430fcc2a62756a23354aa42825bf1a97ad4b7ba6b71f42bb72c20f3dda4a884db06e77faa84517c7fe5f4004e317939bd36d4c60369067c93e
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'stringio'
4
+ require 'forwardable'
5
+ require 'zlib'
6
+
3
7
  require 'wahwah/version'
4
8
  require 'wahwah/errors'
5
9
  require 'wahwah/helper'
6
10
  require 'wahwah/tag_delegate'
11
+ require 'wahwah/lazy_read'
7
12
  require 'wahwah/tag'
8
13
 
9
14
  require 'wahwah/id3/v1'
@@ -11,29 +11,24 @@ module WahWah
11
11
  # 8 bytes: Object size
12
12
  # variable-sized: Object data
13
13
  class Object
14
+ prepend LazyRead
15
+
14
16
  HEADER_SIZE = 24
15
17
  HEADER_FORMAT = 'a16Q<'
16
18
 
17
- attr_reader :size, :guid
19
+ attr_reader :guid
18
20
 
19
- def initialize(file_io)
20
- guid_bytes, @size = file_io.read(HEADER_SIZE)&.unpack(HEADER_FORMAT)
21
+ def initialize
22
+ guid_bytes, @size = @file_io.read(HEADER_SIZE)&.unpack(HEADER_FORMAT)
21
23
  return unless valid?
22
24
 
23
25
  @size = @size - HEADER_SIZE
24
26
  @guid = Helper.byte_string_to_guid(guid_bytes)
25
- @file_io = file_io
26
- @position = file_io.pos
27
27
  end
28
28
 
29
29
  def valid?
30
30
  !@size.nil? && @size >= HEADER_SIZE
31
31
  end
32
-
33
- def data
34
- @file_io.seek(@position)
35
- @file_io.read(size)
36
- end
37
32
  end
38
33
  end
39
34
  end
@@ -54,7 +54,7 @@ module WahWah
54
54
  when CONTENT_DESCRIPTION_OBJECT_GUID
55
55
  parse_content_description_object(sub_object)
56
56
  else
57
- @file_io.seek(sub_object.size, IO::SEEK_CUR)
57
+ sub_object.skip
58
58
  end
59
59
  end
60
60
 
@@ -187,7 +187,7 @@ module WahWah
187
187
 
188
188
  return unless stream_type_guid == AUDIO_MEDIA_OBJECT_GUID
189
189
 
190
- @sample_rate, bytes_per_second = object_data.read(type_specific_data_length).unpack('x4VV')
190
+ @sample_rate, bytes_per_second, @bit_depth = object_data.read(type_specific_data_length).unpack('x4VVx2v')
191
191
  @bitrate = (bytes_per_second * 8.0 / 1000).round
192
192
  end
193
193
 
@@ -3,13 +3,15 @@
3
3
  module WahWah
4
4
  module Flac
5
5
  class Block
6
+ prepend LazyRead
7
+
6
8
  HEADER_SIZE = 4
7
9
  HEADER_FORMAT = 'B*'
8
10
  BLOCK_TYPE_INDEX = %w(STREAMINFO PADDING APPLICATION SEEKTABLE VORBIS_COMMENT CUESHEET PICTURE)
9
11
 
10
- attr_reader :size, :type
12
+ attr_reader :type
11
13
 
12
- def initialize(file_io)
14
+ def initialize
13
15
  # Block header structure:
14
16
  #
15
17
  # Length(bit) Meaning
@@ -30,14 +32,11 @@ module WahWah
30
32
  #
31
33
  # 24 Length (in bytes) of metadata to follow
32
34
  # (does not include the size of the METADATA_BLOCK_HEADER)
33
- header_bits = file_io.read(HEADER_SIZE).unpack(HEADER_FORMAT).first
35
+ header_bits = @file_io.read(HEADER_SIZE).unpack(HEADER_FORMAT).first
34
36
 
35
37
  @last_flag = header_bits[0]
36
38
  @type = BLOCK_TYPE_INDEX[header_bits[1..7].to_i(2)]
37
39
  @size = header_bits[8..-1].to_i(2)
38
-
39
- @file_io = file_io
40
- @position = file_io.pos
41
40
  end
42
41
 
43
42
  def valid?
@@ -47,11 +46,6 @@ module WahWah
47
46
  def is_last?
48
47
  @last_flag.to_i == 1
49
48
  end
50
-
51
- def data
52
- @file_io.seek(@position)
53
- @file_io.read(size)
54
- end
55
49
  end
56
50
  end
57
51
  end
@@ -40,11 +40,11 @@ module WahWah
40
40
  info_bits = block_data.unpack('x10B64').first
41
41
 
42
42
  @sample_rate = info_bits[0..19].to_i(2)
43
- bits_per_sample = info_bits[23..27].to_i(2) + 1
43
+ @bit_depth = info_bits[23..27].to_i(2) + 1
44
44
  total_samples = info_bits[28..-1].to_i(2)
45
45
 
46
46
  @duration = (total_samples.to_f / @sample_rate).round if @sample_rate > 0
47
- @bitrate = @sample_rate * bits_per_sample / 1000
47
+ @bitrate = @sample_rate * @bit_depth / 1000
48
48
  end
49
49
  end
50
50
  end
@@ -38,9 +38,9 @@ module WahWah
38
38
  when 'VORBIS_COMMENT'
39
39
  parse_vorbis_comment(block.data)
40
40
  when 'PICTURE'
41
- parse_picture_block(block.data)
41
+ @images_data.push(block); block.skip
42
42
  else
43
- @file_io.seek(block.size, IO::SEEK_CUR)
43
+ block.skip
44
44
  end
45
45
  end
46
46
 
@@ -69,8 +69,8 @@ module WahWah
69
69
  # 32 The length of the picture data in bytes.
70
70
  #
71
71
  # n*8 The binary picture data.
72
- def parse_picture_block(block_data)
73
- block_content = StringIO.new(block_data)
72
+ def parse_image_data(picture_block)
73
+ block_content = StringIO.new(picture_block.data)
74
74
 
75
75
  type_index, mime_type_length = block_content.read(8).unpack('NN')
76
76
  mime_type = Helper.encode_to_utf8(block_content.read(mime_type_length))
@@ -78,7 +78,7 @@ module WahWah
78
78
  data_length = block_content.read(description_length + 20).unpack("#{'x' * (description_length + 16)}N").first
79
79
  data = block_content.read(data_length)
80
80
 
81
- @images.push({ data: data, mime_type: mime_type, type: ID3::ImageFrameBody::TYPES[type_index] })
81
+ { data: data, mime_type: mime_type, type: ID3::ImageFrameBody::TYPES[type_index] }
82
82
  end
83
83
  end
84
84
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'zlib'
4
-
5
3
  module WahWah
6
4
  module ID3
7
5
  class Frame
6
+ prepend LazyRead
7
+
8
8
  ID_MAPPING = {
9
9
  # ID3v2.2 frame id
10
10
  COM: :comment,
@@ -78,10 +78,9 @@ module WahWah
78
78
  array[15] = :data_length_indicator
79
79
  end
80
80
 
81
- attr_reader :name, :value
81
+ attr_reader :name
82
82
 
83
- def initialize(file_io, version)
84
- @file_io = file_io
83
+ def initialize(version)
85
84
  @version = version
86
85
 
87
86
  parse_frame_header
@@ -98,8 +97,6 @@ module WahWah
98
97
  @file_io.seek(4, IO::SEEK_CUR)
99
98
  @size = @size - 4
100
99
  end
101
-
102
- parse_body
103
100
  end
104
101
 
105
102
  def valid?
@@ -114,6 +111,13 @@ module WahWah
114
111
  @flags.include? :data_length_indicator
115
112
  end
116
113
 
114
+ def value
115
+ return unless @size > 0
116
+
117
+ content = compressed? ? Zlib.inflate(data) : data
118
+ frame_body = frame_body_class.new(content, @version)
119
+ frame_body.value
120
+ end
117
121
 
118
122
  private
119
123
  # ID3v2.2 frame header structure:
@@ -154,15 +158,6 @@ module WahWah
154
158
  end.compact
155
159
  end
156
160
 
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
161
  def frame_body_class
167
162
  case @name
168
163
  when :comment
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
4
-
5
3
  module WahWah
6
4
  module ID3
7
5
  class V2 < Tag
@@ -22,7 +20,7 @@ module WahWah
22
20
 
23
21
  until end_of_tag? do
24
22
  frame = ID3::Frame.new(@file_io, major_version)
25
- next unless frame.valid?
23
+ (frame.skip; next) unless frame.valid?
26
24
 
27
25
  update_attribute(frame)
28
26
  end
@@ -30,31 +28,34 @@ module WahWah
30
28
 
31
29
  def update_attribute(frame)
32
30
  name = frame.name
33
- value = frame.value
34
31
 
35
32
  case name
36
33
  when :comment
37
34
  # Because there may be more than one comment frame in each tag,
38
35
  # so push it into a array.
39
- @comments.push(value)
36
+ @comments.push(frame.value)
40
37
  when :image
41
38
  # Because there may be more than one image frame in each tag,
42
39
  # so push it into a array.
43
- @images.push(value)
40
+ @images_data.push(frame); frame.skip
44
41
  when :track, :disc
45
42
  # Track and disc value may be extended with a "/" character
46
43
  # and a numeric string containing the total numer.
47
- count, total_count = value.split('/', 2)
44
+ count, total_count = frame.value.split('/', 2)
48
45
  instance_variable_set("@#{name}", count)
49
46
  instance_variable_set("@#{name}_total", total_count) unless total_count.nil?
50
47
  else
51
- instance_variable_set("@#{name}", value)
48
+ instance_variable_set("@#{name}", frame.value)
52
49
  end
53
50
  end
54
51
 
55
52
  def end_of_tag?
56
53
  size <= @file_io.pos || file_size <= @file_io.pos
57
54
  end
55
+
56
+ def parse_image_data(image_frame)
57
+ image_frame.value
58
+ end
58
59
  end
59
60
  end
60
61
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WahWah
4
+ module LazyRead
5
+ def self.prepended(base)
6
+ base.class_eval do
7
+ attr_reader :size
8
+ end
9
+ end
10
+
11
+ def initialize(file_io, *arg)
12
+ @file_io = file_io
13
+ super(*arg)
14
+ @position = @file_io.pos
15
+ end
16
+
17
+ def data
18
+ @file_io.seek(@position)
19
+ @file_io.read(size)
20
+ end
21
+
22
+ def skip
23
+ @file_io.seek(size, IO::SEEK_CUR)
24
+ end
25
+ end
26
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
4
-
5
3
  module WahWah
6
4
  class Mp3Tag < Tag
7
5
  extend TagDelegate
@@ -3,13 +3,15 @@
3
3
  module WahWah
4
4
  module Mp4
5
5
  class Atom
6
+ prepend LazyRead
7
+
6
8
  VERSIONED_ATOMS = %w(meta stsd)
7
9
  FLAGGED_ATOMS = %w(stsd)
8
10
  HEADER_SIZE = 8
9
11
  HEADER_SIZE_FIELD_SIZE = 4
10
12
  EXTENDED_HEADER_SIZE = 8
11
13
 
12
- attr_reader :size, :type
14
+ attr_reader :type
13
15
 
14
16
  def self.find(file_io, *atom_path)
15
17
  file_io.rewind
@@ -39,25 +41,18 @@ module WahWah
39
41
  # Type:
40
42
  # A 32-bit integer that contains the type of the atom.
41
43
  # This can often be usefully treated as a four-character field with a mnemonic value .
42
- def initialize(file_io)
43
- @size, @type = file_io.read(HEADER_SIZE)&.unpack('Na4')
44
+ def initialize
45
+ @size, @type = @file_io.read(HEADER_SIZE)&.unpack('Na4')
44
46
  return unless valid?
45
47
 
46
48
  # If the size field of an atom is set to 1, the type field is followed by a 64-bit extended size field,
47
49
  # which contains the actual size of the atom as a 64-bit unsigned integer.
48
- @size = file_io.read(EXTENDED_HEADER_SIZE).unpack('Q>').first - EXTENDED_HEADER_SIZE if @size == 1
50
+ @size = @file_io.read(EXTENDED_HEADER_SIZE).unpack('Q>').first - EXTENDED_HEADER_SIZE if @size == 1
49
51
 
50
52
  # If the size field of an atom is set to 0, which is allowed only for a top-level atom,
51
53
  # designates the last atom in the file and indicates that the atom extends to the end of the file.
52
- @size = file_io.size if @size == 0
54
+ @size = @file_io.size if @size == 0
53
55
  @size = @size - HEADER_SIZE
54
- @file_io = file_io
55
- @position = file_io.pos
56
- end
57
-
58
- def data
59
- @file_io.seek(@position)
60
- @file_io.read(size)
61
56
  end
62
57
 
63
58
  def valid?
@@ -59,7 +59,7 @@ module WahWah
59
59
  # The metadata item list atom is of type ‘ilst’ and contains a number of metadata items, each of which is an atom.
60
60
  # each metadata item atom contains a Value Atom, to hold the value of the metadata item
61
61
  atom.children.each do |child_atom|
62
- attribute_name = META_ATOM_MAPPING[child_atom.type]
62
+ attr_name = META_ATOM_MAPPING[child_atom.type]
63
63
 
64
64
  # The value of the metadata item is expressed as immediate data in a value atom.
65
65
  # The value atom starts with two fields: a type indicator, and a locale indicator.
@@ -68,27 +68,30 @@ module WahWah
68
68
  data_atom = child_atom.find('data')
69
69
  return unless data_atom.valid?
70
70
 
71
- data_type, data_value = data_atom.data.unpack('Nx4a*')
72
- encoded_data_value = META_ATOM_DECODE_BY_TYPE[data_type]&.call(data_value)
71
+ (@images_data.push(data_atom); next) if attr_name == :image
73
72
 
74
- next if attribute_name.nil? || encoded_data_value.nil?
73
+ encoded_data_value = parse_meta_data_atom(data_atom)
74
+ next if attr_name.nil? || encoded_data_value.nil?
75
75
 
76
- case attribute_name
77
- when :image
78
- @images.push(encoded_data_value)
76
+ case attr_name
79
77
  when :comment
80
78
  @comments.push(encoded_data_value)
81
79
  when :track, :disc
82
80
  count, total_count = encoded_data_value.unpack('x2nn')
83
81
 
84
- instance_variable_set("@#{attribute_name}", count) unless count.zero?
85
- instance_variable_set("@#{attribute_name}_total", total_count) unless total_count.zero?
82
+ instance_variable_set("@#{attr_name}", count) unless count.zero?
83
+ instance_variable_set("@#{attr_name}_total", total_count) unless total_count.zero?
86
84
  else
87
- instance_variable_set("@#{attribute_name}", encoded_data_value)
85
+ instance_variable_set("@#{attr_name}", encoded_data_value)
88
86
  end
89
87
  end
90
88
  end
91
89
 
90
+ def parse_meta_data_atom(atom)
91
+ data_type, data_value = atom.data.unpack('Nx4a*')
92
+ META_ATOM_DECODE_BY_TYPE[data_type]&.call(data_value)
93
+ end
94
+
92
95
  def parse_mvhd_atom(atom)
93
96
  return unless atom.valid?
94
97
 
@@ -122,5 +125,9 @@ module WahWah
122
125
  @sample_rate = mp4a_atom.data.unpack('x22I>').first if mp4a_atom.valid?
123
126
  @bitrate = esds_atom.data.unpack('x26I>').first / 1000 if esds_atom.valid?
124
127
  end
128
+
129
+ def parse_image_data(image_data_atom)
130
+ parse_meta_data_atom(image_data_atom)
131
+ end
125
132
  end
126
133
  end
@@ -6,7 +6,7 @@ module WahWah
6
6
  include VorbisComment
7
7
  include Flac::StreaminfoBlock
8
8
 
9
- attr_reader :bitrate, :duration, :sample_rate, *COMMET_FIELD_MAPPING.values
9
+ attr_reader :bitrate, :duration, :sample_rate, :bit_depth, *COMMET_FIELD_MAPPING.values
10
10
 
11
11
  def initialize(identification_packet, comment_packet)
12
12
  # Identification packet structure:
@@ -39,7 +39,7 @@ module WahWah
39
39
  comment_length = comment_content.read(4).unpack('V').first
40
40
  comment = Helper.encode_to_utf8(comment_content.read(comment_length))
41
41
  field_name, field_value = comment.split('=', 2)
42
- attr_name = COMMET_FIELD_MAPPING[field_name]
42
+ attr_name = COMMET_FIELD_MAPPING[field_name&.upcase]
43
43
 
44
44
  field_value = field_value.to_i if %i(track disc).include? attr_name
45
45
 
@@ -24,6 +24,10 @@ module WahWah
24
24
  @bitrate ||= parse_bitrate
25
25
  end
26
26
 
27
+ def bit_depth
28
+ @bit_depth ||= parse_bit_depth
29
+ end
30
+
27
31
  private
28
32
  def packets
29
33
  @packets ||= Ogg::Packets.new(@file_io)
@@ -62,5 +66,9 @@ module WahWah
62
66
  return @tag.bitrate if @tag.respond_to? :bitrate
63
67
  ((file_size - @overhead_packets_size) * 8.0 / duration / 1000).round
64
68
  end
69
+
70
+ def parse_bit_depth
71
+ @tag.bit_depth if @tag.respond_to? :bit_depth
72
+ end
65
73
  end
66
74
  end
@@ -16,19 +16,19 @@ module WahWah
16
16
  # 4 bytes: an ASCII identifier for this particular RIFF or LIST chunk (for RIFF in the typical case, these 4 bytes describe the content of the entire file, such as "AVI " or "WAVE").
17
17
  # rest of data: subchunks.
18
18
  class Chunk
19
+ prepend LazyRead
20
+
19
21
  HEADER_SIZE = 8
20
22
  HEADER_FORMAT = 'A4V'
21
23
  HEADER_TYPE_SIZE = 4
22
24
 
23
25
  attr_reader :id, :type
24
26
 
25
- def initialize(file_io)
26
- @id, @size = file_io.read(HEADER_SIZE)&.unpack(HEADER_FORMAT)
27
+ def initialize
28
+ @id, @size = @file_io.read(HEADER_SIZE)&.unpack(HEADER_FORMAT)
27
29
  return unless valid?
28
30
 
29
- @type = file_io.read(HEADER_TYPE_SIZE).unpack('A4').first if have_type?
30
- @file_io = file_io
31
- @position = file_io.pos
31
+ @type = @file_io.read(HEADER_TYPE_SIZE).unpack('A4').first if have_type?
32
32
  end
33
33
 
34
34
  def size
@@ -36,11 +36,6 @@ module WahWah
36
36
  have_type? ? @size - HEADER_TYPE_SIZE : @size
37
37
  end
38
38
 
39
- def data
40
- @file_io.seek(@position)
41
- @file_io.read(size)
42
- end
43
-
44
39
  def valid?
45
40
  !@id.empty? && !@size.nil? && @size > 0
46
41
  end
@@ -69,7 +69,7 @@ module WahWah
69
69
  when 'id3', 'ID3'
70
70
  parse_id3_chunk(sub_chunk)
71
71
  else
72
- @file_io.seek(sub_chunk.size, IO::SEEK_CUR)
72
+ sub_chunk.skip
73
73
  end
74
74
  end
75
75
 
@@ -92,13 +92,13 @@ module WahWah
92
92
  #
93
93
  # 2(little endian) BitsPerSample 8 bits = 8, 16 bits = 16, etc.
94
94
  def parse_fmt_chunk(chunk)
95
- _, @channel, @sample_rate, _, _, @bits_per_sample = chunk.data.unpack('vvVVvv')
96
- @bitrate = @sample_rate * @channel * @bits_per_sample / 1000
95
+ _, @channel, @sample_rate, _, _, @bit_depth = chunk.data.unpack('vvVVvv')
96
+ @bitrate = @sample_rate * @channel * @bit_depth / 1000
97
97
  end
98
98
 
99
99
  def parse_data_chunk(chunk)
100
100
  @duration = chunk.size * 8 / (@bitrate * 1000)
101
- @file_io.seek(chunk.size, IO::SEEK_CUR)
101
+ chunk.skip
102
102
  end
103
103
 
104
104
  def parse_list_chunk(chunk)
@@ -107,13 +107,13 @@ module WahWah
107
107
  # RIFF can be tagged with metadata in the INFO chunk.
108
108
  # And INFO chunk as a subchunk for LIST chunk.
109
109
  if chunk.type != 'INFO'
110
- @file_io.seek(chunk.size, IO::SEEK_CUR)
110
+ chunk.skip
111
111
  else
112
112
  until list_chunk_end_position <= @file_io.pos do
113
113
  info_chunk = Riff::Chunk.new(@file_io)
114
114
 
115
115
  unless INFO_ID_MAPPING.keys.include? info_chunk.id.to_sym
116
- @file_io.seek(info_chunk.size, IO::SEEK_CUR); next
116
+ info_chunk.skip; next
117
117
  end
118
118
 
119
119
  update_attribute(info_chunk)
@@ -126,14 +126,14 @@ module WahWah
126
126
  end
127
127
 
128
128
  def update_attribute(chunk)
129
- attribute_name = INFO_ID_MAPPING[chunk.id.to_sym]
129
+ attr_name = INFO_ID_MAPPING[chunk.id.to_sym]
130
130
  chunk_data = Helper.encode_to_utf8(chunk.data)
131
131
 
132
- case attribute_name
132
+ case attr_name
133
133
  when :comment
134
134
  @comments.push(chunk_data)
135
135
  else
136
- instance_variable_set("@#{attribute_name}", chunk_data)
136
+ instance_variable_set("@#{attr_name}", chunk_data)
137
137
  end
138
138
  end
139
139
  end
@@ -3,7 +3,7 @@
3
3
  module WahWah
4
4
  class Tag
5
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)
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,
@@ -18,10 +18,10 @@ module WahWah
18
18
  :year,
19
19
  :disc,
20
20
  :disc_total,
21
- :images,
22
21
  :duration,
23
22
  :bitrate,
24
23
  :sample_rate,
24
+ :bit_depth,
25
25
  :file_size
26
26
  )
27
27
 
@@ -35,7 +35,7 @@ module WahWah
35
35
  end
36
36
 
37
37
  @comments = []
38
- @images = []
38
+ @images_data = []
39
39
 
40
40
  parse if @file_size > 0
41
41
 
@@ -45,15 +45,24 @@ module WahWah
45
45
  end
46
46
  end
47
47
 
48
- def parse
49
- raise WahWahNotImplementedError, 'The parse method is not implemented'
50
- end
51
-
52
48
  def inspect
53
49
  inspect_id = ::Kernel.format '%x', (object_id * 2)
54
50
  inspect_attributes_values = INSPECT_ATTRIBUTES.map { |attr_name| "#{attr_name}=#{self.send(attr_name)}" }.join(' ')
55
51
 
56
52
  "<#{self.class.name}:0x#{inspect_id} #{inspect_attributes_values}>"
57
53
  end
54
+
55
+ def images
56
+ return @images_data if @images_data.empty?
57
+
58
+ @images_data.map do |data|
59
+ parse_image_data(data)
60
+ end
61
+ end
62
+
63
+ private
64
+ def parse
65
+ raise WahWahNotImplementedError, 'The parse method is not implemented'
66
+ end
58
67
  end
59
68
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WahWah
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wahwah
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - aidewoode
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-02 00:00:00.000000000 Z
11
+ date: 2020-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.1.17
97
+ - !ruby/object:Gem::Dependency
98
+ name: memory_profiler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.9.14
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.9.14
97
111
  description: WahWah is an audio metadata reader ruby gem, it supports many popular
98
112
  formats including mp3(ID3 v1, v2.2, v2.3, v2.4), m4a, ogg, oga, opus, wav, flac
99
113
  and wma.
@@ -121,6 +135,7 @@ files:
121
135
  - lib/wahwah/id3/v1.rb
122
136
  - lib/wahwah/id3/v2.rb
123
137
  - lib/wahwah/id3/v2_header.rb
138
+ - lib/wahwah/lazy_read.rb
124
139
  - lib/wahwah/mp3/mpeg_frame_header.rb
125
140
  - lib/wahwah/mp3/vbri_header.rb
126
141
  - lib/wahwah/mp3/xing_header.rb