lctr_mp3 0.0.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 +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: []
|