topspin/id3_tags

View on GitHub
lib/id3_tags.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'mimemagic'
require 'id3_tags/mp3'
require 'id3_tags/m4a'

# Provides two methods to read and write ID3 metadata from an MP3 or M4A file
module Id3Tags

  # Returns a Hash of ID3 attributes stored in the file located at +file_path+.
  #
  # @param [String] file_path Local path to an MP3 or M4A file
  # @return [Hash] the ID3 attributes stored in the file
  #
  # @example Read tags from an MP3 full of metadata
  #   Id3Tags.read_tags_from("all_id3.mp3")
  #
  #   # => {title: "Sample track", album: "Sample album", artist: Sample
  #         artist", :comment=>"Sample comments", genre: "Sample Genre",
  #         year: 1979, bitrate: 128, channels: 2, length: 38, samplerate:
  #         44100, bpm: 110, lyrics: "Sample lyrics line 1\rand line 2",
  #         composer: "Sample composer", grouping: "Sample group",
  #         album_artist: "Sample album artist", compilation: true, track:
  #         {number: 3, count: 12}, disk: {number: 1, count: 2}, cover_art:
  #         {mime_type: "image/png", data: "\x89PNG\r\n\x1A[...]"}}
  def self.read_tags_from(file_path)
    case mime_type_of(file_path)
      when 'audio/mpeg' then MPEG.new.read_tags_from(file_path)
      when 'audio/mp4' then M4A.new.read_tags_from(file_path)
      else {}
    end
  end

  # Stores the +attrs+ Hash of ID3 attributes into the file at +file_path+.
  #
  # @param [String] file_path Local path to an MP3 or M4A file
  # @param [Hash] attrs the ID3 attributes stored in the file
  # @return [Boolean] true (the file gets changed)
  #
  # @example Write ID3 tags to an MP3 file
  #   Id3Tags.write_tags_to("no_id3.mp3", {title: "Sample track", album:
  #        "Sample album", artist: Sample artist", :comment=>"Sample comments",
  #        genre: "Sample Genre", year: 1979, bitrate: 128, channels: 2,
  #        length: 38, samplerate: 44100, bpm: 110, lyrics: "Sample lyrics
  #        line 1\rand line 2", composer: "Sample composer", grouping: "Sample
  #        group", album_artist: "Sample album artist", compilation: true,
  #        track: {number: 3, count: 12}, disk: {number: 1, count: 2},
  #        cover_art: {mime_type: "image/png", data: "\x89PNG\r\n\x1A[...]"}}
  #
  #   # => true
  def self.write_tags_to(file_path, attrs = {})
    case mime_type_of(file_path)
      when 'audio/mpeg' then MPEG.new.write_tags_to(file_path, attrs)
      when 'audio/mp4' then M4A.new.write_tags_to(file_path, attrs)
      else false
    end
  end

  # Returns the MIME type of the file located at +file_path+.
  #
  # @param [String] file_path Local path to a file
  # @return [String] the MIME type of the file
  #
  # @example Return the MIME type of an M4A file with a wrong '.mp3' extension
  #   Id3Tags.mime_type_of("this_is_an_m4a.mp3")
  #
  #   # => "audio/mpeg"
  def self.mime_type_of(file_path)
    mime_type   = MimeMagic.by_magic File.open(file_path)
    mime_type ||= MimeMagic.by_path file_path
    mime_type &&= mime_type.type
  end
end