lctr_mp3 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/Rakefile.rb +3 -0
- data/lib/id3_frame_ids.rb +3 -0
- data/lib/lctr_mp3.rb +130 -0
- data/spec/.rspec +2 -0
- data/spec/lctr_mp3_spec.rb +56 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a05711ba481ec51af625f84b6b14cc13847ed5ee
|
4
|
+
data.tar.gz: 63f80a2d9d298894e1e484996a1770a4ead91627
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0818a79535cd47cacbd62c876ab950141a9cc461ff1bf21ab22eaae285d2caa37ae1f7a74e2f0b73b87ac7ff6c1090a26c4231f075a23e7022f81a96d948799d
|
7
|
+
data.tar.gz: 877fcbd87fcd69ad99453d3d0453c1cb290f007850ad482b2604cf3eaefbc4fe3e1ba6fb13f50b0303357ecae2cb7f865d4062c325240e377814f46a1e5a9005
|
data/Gemfile
ADDED
data/Rakefile.rb
ADDED
data/lib/lctr_mp3.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
#mp3 id3 tag reader
|
2
|
+
|
3
|
+
require_relative '../lib/id3_frame_ids.rb'
|
4
|
+
|
5
|
+
# This class represents the data held in an ID3 tag attached to an .mp3 music file. It is intended to be a container
|
6
|
+
# for the fields that are listed in attr_accessor and included in the file "id_frame_ids.rb" that should be held in the
|
7
|
+
# same directory. Upon calling the class with the name of an .mp3 file, the initialize method should pull all of the
|
8
|
+
# required data into the instance. This data can later be modified and exported to a tag.
|
9
|
+
#
|
10
|
+
# This currently works only for ID3 tags version 2.3.
|
11
|
+
#
|
12
|
+
# ID3 technical information taken from http://id3.org/id3v2.3.0.
|
13
|
+
#
|
14
|
+
# Author:: Neil Woodward
|
15
|
+
# License:: MIT
|
16
|
+
#
|
17
|
+
class ID3
|
18
|
+
|
19
|
+
attr_accessor :mp3_file, :song_title, :album_title, :artist, :track, :year, :song_length, :version, :flags, :path, :time
|
20
|
+
|
21
|
+
# This will read in all of the tag data when the instance is initialized.
|
22
|
+
def initialize(file)
|
23
|
+
@file = file
|
24
|
+
header = get_tag_header
|
25
|
+
tag_size = parse_header(header)
|
26
|
+
tag = get_tag(tag_size)
|
27
|
+
get_frames(tag)
|
28
|
+
set_file
|
29
|
+
set_flag(header[5])
|
30
|
+
end
|
31
|
+
|
32
|
+
# This reads the first 10 bytes of the tag, which contain the metadata of the tag.
|
33
|
+
def get_tag_header
|
34
|
+
header = Array.new
|
35
|
+
File.open(@file, "r") do |f|
|
36
|
+
f.each_byte.with_index do |ch, index|
|
37
|
+
case index
|
38
|
+
when 0..4
|
39
|
+
header << ch.chr
|
40
|
+
when 5
|
41
|
+
header << ch.to_s(2)[0..2]
|
42
|
+
when 6..9
|
43
|
+
if ch > 128
|
44
|
+
raise "Header error: reported tag size too large"
|
45
|
+
end
|
46
|
+
header << ch.to_s(2).rjust(7,"0")
|
47
|
+
end
|
48
|
+
return header if index > 10
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
# This will read the tag into memory and assign to the "tag" variable for later scraping.
|
55
|
+
def get_tag(size)
|
56
|
+
tag = ""
|
57
|
+
File.open(@file, "r") do |f|
|
58
|
+
f.each_byte.with_index do |ch,index|
|
59
|
+
tag << ch
|
60
|
+
|
61
|
+
return tag if index > size
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# This is the method that will parse the ID3 header, making sure that it is actually a good ID3 header.
|
67
|
+
def parse_header(header)
|
68
|
+
check_ID3(header)
|
69
|
+
check_ver(header)
|
70
|
+
return tag_size(header[6..9])
|
71
|
+
end
|
72
|
+
|
73
|
+
# This method verifies the header is indeed an ID3 header.
|
74
|
+
def check_ID3(header)
|
75
|
+
unless header[0..2].join == "ID3"
|
76
|
+
raise "No ID3 tag on the file"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# This method ensures that we have the correct ID3 version.
|
81
|
+
def check_ver(header)
|
82
|
+
if header[3..4].join(' ') == "\x03 \x00"
|
83
|
+
@version = "2.3"
|
84
|
+
else
|
85
|
+
raise "Incorrect ID3 version - require v2.3"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# This method converts the size bytes in the header into a decimal number representation of the header size.
|
90
|
+
def tag_size(header6_9)
|
91
|
+
header6_9.join.to_i(2)
|
92
|
+
end
|
93
|
+
|
94
|
+
# This method is used to search the tag for the desired frame tags, and identify the frame locations and sizes.
|
95
|
+
def get_frames(tag)
|
96
|
+
FRAMES.keys.each do |type|
|
97
|
+
|
98
|
+
if loc = (/#{type}/ =~ tag)
|
99
|
+
fr_size_arr = tag[loc+4,4].bytes
|
100
|
+
fr_size_str=""
|
101
|
+
|
102
|
+
fr_size_arr.each do |ch|
|
103
|
+
fr_size_str<<ch.to_s(2).rjust(8,"0")
|
104
|
+
end
|
105
|
+
|
106
|
+
fr_size = fr_size_str.to_i(2)
|
107
|
+
frm = tag[loc+10,fr_size].gsub(/\u0000/,"")
|
108
|
+
|
109
|
+
eval("self.#{FRAMES[type]} = frm")
|
110
|
+
|
111
|
+
else
|
112
|
+
eval("self.#{FRAMES[type]} = nil")
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
# Used to set the file name.
|
120
|
+
def set_file
|
121
|
+
@path = File.dirname(@file)
|
122
|
+
@mp3_file = File.basename(@file)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Used to set the flag bits.
|
126
|
+
def set_flag(flags)
|
127
|
+
@flags = flags
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
data/spec/.rspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#
|
2
|
+
#mp3 ID3 tag decoding code.
|
3
|
+
#
|
4
|
+
#N. Woodward, 18 Feb 2014
|
5
|
+
|
6
|
+
#require $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
|
8
|
+
require_relative '../lib/lctr_mp3.rb'
|
9
|
+
|
10
|
+
describe ID3 do
|
11
|
+
|
12
|
+
before (:each) do
|
13
|
+
@id3 = ID3.new('./test_mp3_tag.mp3')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should correctly identify the Artist" do
|
17
|
+
@id3.artist.should eq "Adele"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should correctly identify the album" do
|
21
|
+
@id3.album_title.should eq "21"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should correctly idenfity the song" do
|
25
|
+
@id3.song_title.should eq "Rumour Has It"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should correctly idenfity the track number" do
|
29
|
+
@id3.track.should eq "2/11"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should correctly idenfity the file name of the song" do
|
33
|
+
@id3.mp3_file.should eq "test_mp3_tag.mp3"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should correctly identify the path to the file" do
|
37
|
+
@id3.path.should eq "."
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should correctly identify the year of the song" do
|
41
|
+
@id3.year.should eq "2011"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should correctly identify the length of the song" do
|
45
|
+
@id3.time.should eq nil #didn't have that value set on this song
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should correctly identify the ID3 flags" do
|
49
|
+
@id3.flags.should eq "111" #this value set in tag with hex editor
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should correctly identify the ID3 tag version" do
|
53
|
+
@id3.version.should eq "2.3"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lctr_mp3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Neil Woodward
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-08 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A set of tools to manage .mp3 files, starting with reading ID3 tags.
|
14
|
+
email: drlctr@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- Gemfile
|
20
|
+
- Rakefile.rb
|
21
|
+
- lib/id3_frame_ids.rb
|
22
|
+
- lib/lctr_mp3.rb
|
23
|
+
- spec/.rspec
|
24
|
+
- spec/lctr_mp3_spec.rb
|
25
|
+
homepage: http://rubygems.org/gems/lctr_mp3_gem
|
26
|
+
licenses:
|
27
|
+
- MIT license (MIT)
|
28
|
+
metadata: {}
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubyforge_project:
|
45
|
+
rubygems_version: 2.2.1
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: mp3 / id3 management tools
|
49
|
+
test_files: []
|