Class: Sh::TagReader

Inherits:
Object show all
Defined in:
lib/sh_tagreader.rb

Class Method Summary collapse

Class Method Details

.read(path) {|metadata| ... } ⇒ Object

Yields:

  • (metadata)


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
# File 'lib/sh_tagreader.rb', line 7

def self.read path
  # Ensure that the path is absolute
  @path = File.expand_path path
  
  # Use shared-mime-info to determine MIME types if
  # it is available.
  if try_require 'shared-mime-info'
    type = MIME.check(@path)
    @mime = type.to_s if type.media == 'audio'
  else
  	# Attempt to use the `file` command
  	begin
    	type = `file --mime-type -b "#{@path.gsub('"', '\\"')}"`.strip
    	@mime = type if type[0..5] == 'audio/'
    rescue Exception
    	@mime = nil
    end
    
    # As a fallback, guess MIME type from file extension.
  if not @mime or @mime.empty?
  @mime = {
    '.mp3' => 'audio/mpeg',
    '.m4a' => 'audio/mp4',
    '.flac' => 'audio/x-flac',
    '.ogg' => 'audio/ogg',
    '.wav' => 'audio/x-wav',
    '.wma' => 'audio/x-ms-wma'
  }[File.extname(@path)]
end
  end
  
   = {}
			
			# Choose appropriate method for MIME type
  begin
    case @mime
    when 'audio/mpeg'
       = TagReader.read_mp3 path
    when 'audio/mp4'
       = TagReader.read_m4a path
    when 'audio/ogg'
       = TagReader.read_ogg path
    when 'audio/x-flac'
       = TagReader.read_flac path
    when 'audio/x-ms-wma'
       = TagReader.read_wma path
    when 'audio/x-wav'
       = TagReader.read_wave path
    end
  rescue Exception
    Log.warning "Couldn't parse tags for " + path
  end
			
			# Report on our metadata findings
  yield  if block_given?
  return 
end

.read_flac(path) {|metadata| ... } ⇒ Object

Read metadata from FLAC file

Yields:

  • (metadata)


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/sh_tagreader.rb', line 153

def self.read_flac path
   = {}
  if try_require 'flacinfo'
    flac = FlacInfo.new(path)
    flac.comment.each do |comment|
      split = comment.split('=')
      key = split.first.downcase
      value = (split[1..-1]).join
      value = nil if value == '' or value.is_binary_data?
      case key
      when 'title'
        [:title] = value.to_u if value
      when 'artist'
        [:artist] = value.to_u if value
      when 'album'
        [:album] = value.to_u if value
      when 'year'
        [:year] = value.to_i
      when 'tracknumber'
        [:track_num] = value.to_i
      end
    end

    #TODO: Support METADATA_BLOCK_PICTURE
  else
    Log.info 'Please install the "flacinfo-rb" gem in order to read FLAC info'
  end
  yield  if block_given?
  return 
end

.read_m4a(path) {|metadata| ... } ⇒ Object

Read metadata from M4A file

Yields:

  • (metadata)


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/sh_tagreader.rb', line 95

def self.read_m4a path
   = {}
  if try_require 'mp4info'
    mp4 = MP4Info.open path
    [:title] = mp4.NAM.to_u if mp4.NAM
    [:artist] = mp4.ART.to_u if mp4.ART
    [:album] = mp4.ALB.to_u if mp4.ALB
    [:year] = mp4.DAY.to_i
    [:track_num] = mp4.TRKN.first.to_i
    [:duration] = mp4.SECS
    [:cover_art] = mp4.COVR if mp4.COVR
  else
    Log.info 'Please install the "MP4Info" gem in order to read M4A info'
  end
  yield  if block
  return 
end

.read_mp3(path) {|metadata| ... } ⇒ Object

Read metadata from MP3 file

Yields:

  • (metadata)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/sh_tagreader.rb', line 66

def self.read_mp3 path
   = {}
  if try_require 'mp3info'
    Mp3Info.open path do |mp3|
      t = mp3.tag
      [:title] = t.title.to_u if t.title
      [:artist] = t.artist.to_u if t.artist
      [:album] = t.album.to_u if t.album
      [:year] = t.year.to_i
      [:track_num] = t.tracknum.to_i
      [:duration] = mp3.length

      begin
        if mp3.tag2 and mp3.tag2['APIC']
          a = mp3.tag2['APIC'].last
          a = a[1..-1].sub(/[^\0]*\0/, "")[1..-1].sub(/[^\0]*\0/, "")
          [:cover_art] = a
        end
      rescue
      end
    end
  else
    Log.info 'Please install the "ruby-mp3info" gem in order to read MP3 info'
  end
  yield  if block_given?
  return 
end

.read_ogg(path) {|metadata| ... } ⇒ Object

Read metadata from Ogg Vorbis file

Yields:

  • (metadata)


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/sh_tagreader.rb', line 114

def self.read_ogg path
   = {}
  if try_require 'vorbis'
    Vorbis::Info.open path do |info|
      dur = info.duration
      [:duration] = dur if dur and dur > 0

      info.comments.each do |k, vs|
        if vs and vs.any?
          v = vs.first

          case k
          when 'TITLE'
            [:title] = v.to_u
          when 'ARTIST'
            [:artist] = v.to_u
          when 'ALBUM'
            [:album] = v.to_u
          when 'YEAR'
            [:year] = v.to_i
          when 'TRACKNUMBER'
            [:track_num] = v.to_i
          when 'COVERART'
            [:cover_art] = Base64.decode64(v)
          when 'METADATA_BLOCK_PICTURE'
            # TODO: Support this:
            # http://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE
          end
        end rescue Exception
      end
    end rescue Exception
  else
    Log.info 'Please install the "ruby-ogg" gem in order to read Vorbis info'
  end
  yield  if block_given?
  return 
end

.read_wave(path) {|metadata| ... } ⇒ Object

Read metadata from Wave file

Yields:

  • (metadata)


214
215
216
217
218
219
220
221
222
223
224
# File 'lib/sh_tagreader.rb', line 214

def self.read_wave path
   = {}
  if try_require 'waveinfo'
    wave = WaveInfo.new path
    [:duration] = wave.duration
  else
    Log.info 'Please install the "waveinfo" gem in order to read WAV info'
  end
  yield  if block_given?
  return 
end

.read_wma(path) {|metadata| ... } ⇒ Object

Read metadata from WMA file

Yields:

  • (metadata)


185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/sh_tagreader.rb', line 185

def self.read_wma path
   = {}
  if try_require 'wmainfo'
    wma = WmaInfo.new(path)
    wma.tags.each do |key, value|
      key = key.downcase
      value = nil if value == '' or value.is_binary_data?
      case key
      when 'title'
        [:title] = value.to_u if value
      when 'author'
        [:artist] = value.to_u if value
      when 'albumtitle'
        [:album] = value.to_u if value
      when 'year'
        [:year] = value.to_i
      when 'tracknumber'
        [:track_num] = value.to_i
      end
    end
    [:duration] = wma.info["playtime_seconds"]
  else
    Log.info 'Please install the "wmainfo-rb" gem in order to read WMA info'
  end
  yield  if block_given?
  return 
end