id3tag 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +7 -0
  3. data/Gemfile +9 -9
  4. data/Gemfile.lock +36 -14
  5. data/README.md +73 -0
  6. data/Rakefile +3 -2
  7. data/VERSION +1 -1
  8. data/id3tag.gemspec +75 -19
  9. data/lib/id3tag.rb +34 -0
  10. data/lib/id3tag/audio_file.rb +90 -0
  11. data/lib/id3tag/frame_id_advisor.rb +50 -0
  12. data/lib/id3tag/frames/util/genre_names.rb +140 -0
  13. data/lib/id3tag/frames/v1/comments_frame.rb +24 -0
  14. data/lib/id3tag/frames/v1/genre_frame.rb +19 -0
  15. data/lib/id3tag/frames/v1/text_frame.rb +27 -0
  16. data/lib/id3tag/frames/v1/track_nr_frame.rb +18 -0
  17. data/lib/id3tag/frames/v2/basic_frame.rb +26 -0
  18. data/lib/id3tag/frames/v2/comments_frame.rb +44 -0
  19. data/lib/id3tag/frames/v2/frame_fabricator.rb +36 -0
  20. data/lib/id3tag/frames/v2/genre_frame.rb +34 -0
  21. data/lib/id3tag/frames/v2/genre_frame/genre_parser.rb +36 -0
  22. data/lib/id3tag/frames/v2/genre_frame/genre_parser_24.rb +15 -0
  23. data/lib/id3tag/frames/v2/genre_frame/genre_parser_pre_24.rb +39 -0
  24. data/lib/id3tag/frames/v2/text_frame.rb +37 -0
  25. data/lib/id3tag/frames/v2/unique_file_id_frame.rb +25 -0
  26. data/lib/id3tag/id3_v1_frame_parser.rb +87 -0
  27. data/lib/id3tag/id3_v2_frame_parser.rb +72 -0
  28. data/lib/id3tag/id3_v2_tag_header.rb +61 -0
  29. data/lib/id3tag/number_util.rb +14 -0
  30. data/lib/id3tag/string_util.rb +7 -0
  31. data/lib/id3tag/synchsafe_integer.rb +28 -0
  32. data/lib/id3tag/tag.rb +121 -0
  33. data/spec/fixtures/id3v1_and_v2.mp3 +0 -0
  34. data/spec/fixtures/id3v1_with_track_nr.mp3 +0 -0
  35. data/spec/fixtures/id3v1_without_track_nr.mp3 +0 -0
  36. data/spec/fixtures/id3v2.mp3 +0 -0
  37. data/spec/lib/id3tag/audio_file_spec.rb +40 -0
  38. data/spec/lib/id3tag/frames/util/genre_name_by_id_finder_spec.rb +18 -0
  39. data/spec/lib/id3tag/frames/v1/comments_frame_spec.rb +31 -0
  40. data/spec/lib/id3tag/frames/v1/genre_frame_spec.rb +20 -0
  41. data/spec/lib/id3tag/frames/v1/text_frame_spec.rb +14 -0
  42. data/spec/lib/id3tag/frames/v1/track_nr_frame_spec.rb +19 -0
  43. data/spec/lib/id3tag/frames/v2/basic_frame_spec.rb +25 -0
  44. data/spec/lib/id3tag/frames/v2/comments_frame_spec.rb +45 -0
  45. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_24_spec.rb +26 -0
  46. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_pre_24_spec.rb +48 -0
  47. data/spec/lib/id3tag/frames/v2/genre_frame_spec.rb +44 -0
  48. data/spec/lib/id3tag/frames/v2/text_frame_spec.rb +59 -0
  49. data/spec/lib/id3tag/frames/v2/unique_file_id_frame_spec.rb +31 -0
  50. data/spec/lib/id3tag/id3_v1_frame_parser_spec.rb +67 -0
  51. data/spec/lib/id3tag/id3_v2_frame_parser_spec.rb +18 -0
  52. data/spec/lib/id3tag/id3_v2_tag_header_spec.rb +60 -0
  53. data/spec/lib/id3tag/id3tag_spec.rb +17 -0
  54. data/spec/lib/id3tag/number_util_spec.rb +24 -0
  55. data/spec/lib/id3tag/string_util_spec.rb +21 -0
  56. data/spec/lib/id3tag/synchsafe_integer_spec.rb +14 -0
  57. data/spec/lib/id3tag/tag_spec.rb +84 -0
  58. data/spec/spec_helper.rb +9 -1
  59. data/spec/support/mp3_fixtures.rb +4 -0
  60. metadata +102 -38
  61. data/README.rdoc +0 -19
  62. data/spec/id3tag_spec.rb +0 -7
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MmYzYTExMDI2NWEzZjk2N2RhMTE3OTlmMDE0MTI1ZDY2MDRkM2Q0Mg==
5
+ data.tar.gz: !binary |-
6
+ YTNmZTcwZGQzMTM3ZWEwNmE1NzJmMmQzYWFhMzI5MDQ0ZmFlN2NlYw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ OWEwOTQ5MzU4MDU3YWJjYzcyOTVhM2M5NDhlYzcxZDc2ZTNjMTViYmJjM2Zh
10
+ OTNlNWEyYzQzODcyOTY3ZGNiMDIzN2MyZGM2MjM2ZjQ1MDMxMDU0MWI5NDcw
11
+ NmNmZDM2NmUzZTJhNDE0OWVjZTcyNzYzMWFiMDFiZjQ2YTQ0ODQ=
12
+ data.tar.gz: !binary |-
13
+ ZTdkZDA0ZTdjOTMwNjE0OWE5Mzg1NGExMDQ4N2FkYTFlYWY0ZmY5OTg4NjFj
14
+ MDdmYWY0YzMxZjI4Njc5YWFjMWQzNmI2MmFiMDg5YTA3YTY0ZjljMWNjMGNl
15
+ OGI5OGYyOGY4ZDRiMzU0Y2ZmMTkxY2NhZjIyYmE3YWRmOWEyOTc=
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+ rvm:
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - jruby-19mode # JRuby in 1.9 mode
7
+ - rbx-19mode
data/Gemfile CHANGED
@@ -1,14 +1,14 @@
1
1
  source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
2
 
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
8
3
  group :development do
9
- gem "rspec", "~> 2.8.0"
10
- gem "rdoc", "~> 3.12"
11
- gem "bundler", "~> 1.1.5"
4
+ gem "debugger", :require => false, :platforms => :mri
5
+ end
6
+
7
+ group :development, :test do
12
8
  gem "jeweler", "~> 1.8.4"
13
- gem "simplecov"
9
+ gem "rake"
10
+ gem "rdoc", "~> 3.12"
11
+ gem "rspec", "~> 2.13.0"
12
+ gem "simplecov", :require => false
13
+ gem 'coveralls', :require => false
14
14
  end
data/Gemfile.lock CHANGED
@@ -1,37 +1,59 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- diff-lcs (1.1.3)
4
+ colorize (0.5.8)
5
+ columnize (0.3.6)
6
+ coveralls (0.6.7)
7
+ colorize
8
+ multi_json (~> 1.3)
9
+ rest-client
10
+ simplecov (>= 0.7)
11
+ thor
12
+ debugger (1.5.0)
13
+ columnize (>= 0.3.1)
14
+ debugger-linecache (~> 1.2.0)
15
+ debugger-ruby_core_source (~> 1.2.0)
16
+ debugger-linecache (1.2.0)
17
+ debugger-ruby_core_source (1.2.0)
18
+ diff-lcs (1.2.2)
5
19
  git (1.2.5)
6
20
  jeweler (1.8.4)
7
21
  bundler (~> 1.0)
8
22
  git (>= 1.2.5)
9
23
  rake
10
24
  rdoc
11
- json (1.7.5)
12
- multi_json (1.5.0)
25
+ json (1.7.7)
26
+ json (1.7.7-java)
27
+ mime-types (1.23)
28
+ multi_json (1.6.1)
13
29
  rake (10.0.3)
14
- rdoc (3.12)
30
+ rdoc (3.12.2)
15
31
  json (~> 1.4)
16
- rspec (2.8.0)
17
- rspec-core (~> 2.8.0)
18
- rspec-expectations (~> 2.8.0)
19
- rspec-mocks (~> 2.8.0)
20
- rspec-core (2.8.0)
21
- rspec-expectations (2.8.0)
22
- diff-lcs (~> 1.1.2)
23
- rspec-mocks (2.8.0)
32
+ rest-client (1.6.7)
33
+ mime-types (>= 1.16)
34
+ rspec (2.13.0)
35
+ rspec-core (~> 2.13.0)
36
+ rspec-expectations (~> 2.13.0)
37
+ rspec-mocks (~> 2.13.0)
38
+ rspec-core (2.13.1)
39
+ rspec-expectations (2.13.0)
40
+ diff-lcs (>= 1.1.3, < 2.0)
41
+ rspec-mocks (2.13.0)
24
42
  simplecov (0.7.1)
25
43
  multi_json (~> 1.0)
26
44
  simplecov-html (~> 0.7.1)
27
45
  simplecov-html (0.7.1)
46
+ thor (0.18.1)
28
47
 
29
48
  PLATFORMS
49
+ java
30
50
  ruby
31
51
 
32
52
  DEPENDENCIES
33
- bundler (~> 1.1.5)
53
+ coveralls
54
+ debugger
34
55
  jeweler (~> 1.8.4)
56
+ rake
35
57
  rdoc (~> 3.12)
36
- rspec (~> 2.8.0)
58
+ rspec (~> 2.13.0)
37
59
  simplecov
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # ID3Tag
2
+ Native Ruby ID3 tag reader that aims for 100% covarage of ID3v2.x and ID3v1.x standards
3
+
4
+ ## Install
5
+
6
+ Make sure you are using ruby 1.9.2 or greater
7
+
8
+ Install ID3Tag at the command prompt:
9
+ ```
10
+ gem install id3tag
11
+ ```
12
+
13
+ Or add the gem to your Gemfile:
14
+ ```
15
+ gem 'id3tag'
16
+ ```
17
+
18
+ ## How to use
19
+
20
+ Require the libary and read basic metadata:
21
+ ```ruby
22
+ require "id3tag"
23
+
24
+ mp3_file = File.open('/path/to/your/favorite_song.mp3')
25
+ tag = ID3Tag.read(mp3_file)
26
+ puts "#{tag.artist} - #{tag.title}"
27
+ ```
28
+ `ID3Tag::Tag` class provides easy accessors to frames like `artist`, `title`, `album`, `year`, `comments`, `track_nr`, `genre` but you can read any frame by using `get_frame` or `get_frame_content`.
29
+
30
+ ```ruby
31
+ mp3s = Dir.entries("/some/dir").select { |filename| filename =~ /\.mp3/i }
32
+
33
+ mp3s.each do |file|
34
+ ID3Tag.read(File.open(file)) do |tag|
35
+ puts file
36
+ puts tag.artist
37
+ puts tag.title
38
+ puts tag.album
39
+ puts tag.year
40
+ puts tag.comments
41
+ puts tag.track_nr
42
+ puts tag.genre
43
+ puts "---"
44
+ puts tag.get_frame_content(:TIT2)
45
+ end
46
+ end
47
+ ```
48
+ You can inspect tag by calling `frame_ids` to see available frame ids or `frames` to return all frames
49
+
50
+ ## Features
51
+
52
+ * Can read v1.x, v2.2.x, v2.3.x, v2.4.x tags
53
+ * Supports UTF-8, UTF-16, UTF-16BE and ISO8859-1 encoding
54
+
55
+
56
+ ## Contributing to id3tag
57
+
58
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
59
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
60
+ * Fork the project.
61
+ * Start a feature/bugfix branch.
62
+ * Commit and push until you are happy with your contribution.
63
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
64
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
65
+
66
+ ## Code Status
67
+ [![Code Climate](https://codeclimate.com/github/krists/id3tag.png)](https://codeclimate.com/github/krists/id3tag) [![Build Status](https://travis-ci.org/krists/id3tag.png?branch=master)](https://travis-ci.org/krists/id3tag) [![Coverage Status](https://coveralls.io/repos/krists/id3tag/badge.png?branch=master)](https://coveralls.io/r/krists/id3tag)
68
+
69
+ ## Copyright
70
+
71
+ Copyright (c) 2013 Krists Ozols. See LICENSE.txt for
72
+ further details.
73
+
data/Rakefile CHANGED
@@ -17,10 +17,11 @@ Jeweler::Tasks.new do |gem|
17
17
  gem.name = "id3tag"
18
18
  gem.homepage = "http://github.com/krists/id3tag"
19
19
  gem.license = "MIT"
20
- gem.summary = %Q{Native Ruby ID3 tag reader/writer.}
21
- gem.description = %Q{Native Ruby ID3 tag reader/writer.}
20
+ gem.summary = %Q{Native Ruby ID3 tag reader that aims for 100% covarage of ID3v2.x and ID3v1.x standards}
21
+ gem.description = %Q{Native Ruby ID3 tag reader that aims for 100% covarage of ID3v2.x and ID3v1.x standards}
22
22
  gem.email = "krists@iesals.lv"
23
23
  gem.authors = ["Krists Ozols"]
24
+ gem.required_ruby_version = '>= 1.9.2'
24
25
  # dependencies defined in Gemfile
25
26
  end
26
27
  Jeweler::RubygemsDotOrgTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.1.0
data/id3tag.gemspec CHANGED
@@ -5,59 +5,115 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "id3tag"
8
- s.version = "0.0.0"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Krists Ozols"]
12
- s.date = "2012-12-25"
13
- s.description = "Native Ruby ID3 tag reader/writer."
12
+ s.date = "2013-05-01"
13
+ s.description = "Native Ruby ID3 tag reader that aims for 100% covarage of ID3v2.x and ID3v1.x standards"
14
14
  s.email = "krists@iesals.lv"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
- "README.rdoc"
17
+ "README.md"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
21
  ".rspec",
22
+ ".travis.yml",
22
23
  "Gemfile",
23
24
  "Gemfile.lock",
24
25
  "LICENSE.txt",
25
- "README.rdoc",
26
+ "README.md",
26
27
  "Rakefile",
27
28
  "VERSION",
28
29
  "id3tag.gemspec",
29
30
  "lib/id3tag.rb",
30
- "spec/id3tag_spec.rb",
31
- "spec/spec_helper.rb"
31
+ "lib/id3tag/audio_file.rb",
32
+ "lib/id3tag/frame_id_advisor.rb",
33
+ "lib/id3tag/frames/util/genre_names.rb",
34
+ "lib/id3tag/frames/v1/comments_frame.rb",
35
+ "lib/id3tag/frames/v1/genre_frame.rb",
36
+ "lib/id3tag/frames/v1/text_frame.rb",
37
+ "lib/id3tag/frames/v1/track_nr_frame.rb",
38
+ "lib/id3tag/frames/v2/basic_frame.rb",
39
+ "lib/id3tag/frames/v2/comments_frame.rb",
40
+ "lib/id3tag/frames/v2/frame_fabricator.rb",
41
+ "lib/id3tag/frames/v2/genre_frame.rb",
42
+ "lib/id3tag/frames/v2/genre_frame/genre_parser.rb",
43
+ "lib/id3tag/frames/v2/genre_frame/genre_parser_24.rb",
44
+ "lib/id3tag/frames/v2/genre_frame/genre_parser_pre_24.rb",
45
+ "lib/id3tag/frames/v2/text_frame.rb",
46
+ "lib/id3tag/frames/v2/unique_file_id_frame.rb",
47
+ "lib/id3tag/id3_v1_frame_parser.rb",
48
+ "lib/id3tag/id3_v2_frame_parser.rb",
49
+ "lib/id3tag/id3_v2_tag_header.rb",
50
+ "lib/id3tag/number_util.rb",
51
+ "lib/id3tag/string_util.rb",
52
+ "lib/id3tag/synchsafe_integer.rb",
53
+ "lib/id3tag/tag.rb",
54
+ "spec/fixtures/id3v1_and_v2.mp3",
55
+ "spec/fixtures/id3v1_with_track_nr.mp3",
56
+ "spec/fixtures/id3v1_without_track_nr.mp3",
57
+ "spec/fixtures/id3v2.mp3",
58
+ "spec/lib/id3tag/audio_file_spec.rb",
59
+ "spec/lib/id3tag/frames/util/genre_name_by_id_finder_spec.rb",
60
+ "spec/lib/id3tag/frames/v1/comments_frame_spec.rb",
61
+ "spec/lib/id3tag/frames/v1/genre_frame_spec.rb",
62
+ "spec/lib/id3tag/frames/v1/text_frame_spec.rb",
63
+ "spec/lib/id3tag/frames/v1/track_nr_frame_spec.rb",
64
+ "spec/lib/id3tag/frames/v2/basic_frame_spec.rb",
65
+ "spec/lib/id3tag/frames/v2/comments_frame_spec.rb",
66
+ "spec/lib/id3tag/frames/v2/genre_frame/genre_parser_24_spec.rb",
67
+ "spec/lib/id3tag/frames/v2/genre_frame/genre_parser_pre_24_spec.rb",
68
+ "spec/lib/id3tag/frames/v2/genre_frame_spec.rb",
69
+ "spec/lib/id3tag/frames/v2/text_frame_spec.rb",
70
+ "spec/lib/id3tag/frames/v2/unique_file_id_frame_spec.rb",
71
+ "spec/lib/id3tag/id3_v1_frame_parser_spec.rb",
72
+ "spec/lib/id3tag/id3_v2_frame_parser_spec.rb",
73
+ "spec/lib/id3tag/id3_v2_tag_header_spec.rb",
74
+ "spec/lib/id3tag/id3tag_spec.rb",
75
+ "spec/lib/id3tag/number_util_spec.rb",
76
+ "spec/lib/id3tag/string_util_spec.rb",
77
+ "spec/lib/id3tag/synchsafe_integer_spec.rb",
78
+ "spec/lib/id3tag/tag_spec.rb",
79
+ "spec/spec_helper.rb",
80
+ "spec/support/mp3_fixtures.rb"
32
81
  ]
33
82
  s.homepage = "http://github.com/krists/id3tag"
34
83
  s.licenses = ["MIT"]
35
84
  s.require_paths = ["lib"]
36
- s.rubygems_version = "1.8.24"
37
- s.summary = "Native Ruby ID3 tag reader/writer."
85
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
86
+ s.rubygems_version = "2.0.3"
87
+ s.summary = "Native Ruby ID3 tag reader that aims for 100% covarage of ID3v2.x and ID3v1.x standards"
38
88
 
39
89
  if s.respond_to? :specification_version then
40
- s.specification_version = 3
90
+ s.specification_version = 4
41
91
 
42
92
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
44
- s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
45
- s.add_development_dependency(%q<bundler>, ["~> 1.1.5"])
93
+ s.add_development_dependency(%q<debugger>, [">= 0"])
46
94
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
95
+ s.add_development_dependency(%q<rake>, [">= 0"])
96
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
97
+ s.add_development_dependency(%q<rspec>, ["~> 2.13.0"])
47
98
  s.add_development_dependency(%q<simplecov>, [">= 0"])
99
+ s.add_development_dependency(%q<coveralls>, [">= 0"])
48
100
  else
49
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
50
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
51
- s.add_dependency(%q<bundler>, ["~> 1.1.5"])
101
+ s.add_dependency(%q<debugger>, [">= 0"])
52
102
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
103
+ s.add_dependency(%q<rake>, [">= 0"])
104
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
105
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
53
106
  s.add_dependency(%q<simplecov>, [">= 0"])
107
+ s.add_dependency(%q<coveralls>, [">= 0"])
54
108
  end
55
109
  else
56
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
57
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
58
- s.add_dependency(%q<bundler>, ["~> 1.1.5"])
110
+ s.add_dependency(%q<debugger>, [">= 0"])
59
111
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
112
+ s.add_dependency(%q<rake>, [">= 0"])
113
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
114
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
60
115
  s.add_dependency(%q<simplecov>, [">= 0"])
116
+ s.add_dependency(%q<coveralls>, [">= 0"])
61
117
  end
62
118
  end
63
119
 
data/lib/id3tag.rb CHANGED
@@ -0,0 +1,34 @@
1
+ require "set"
2
+ require "stringio"
3
+
4
+ require "id3tag/synchsafe_integer"
5
+ require "id3tag/audio_file"
6
+ require "id3tag/id3_v2_tag_header"
7
+ require "id3tag/number_util"
8
+ require "id3tag/string_util"
9
+ require "id3tag/id3_v1_frame_parser"
10
+ require "id3tag/id3_v2_frame_parser"
11
+ require "id3tag/frame_id_advisor"
12
+ require "id3tag/tag"
13
+ require "id3tag/frames/util/genre_names"
14
+ require "id3tag/frames/v1/text_frame"
15
+ require "id3tag/frames/v1/genre_frame"
16
+ require "id3tag/frames/v1/comments_frame"
17
+ require "id3tag/frames/v1/track_nr_frame"
18
+ require "id3tag/frames/v2/basic_frame"
19
+ require "id3tag/frames/v2/text_frame"
20
+ require "id3tag/frames/v2/unique_file_id_frame"
21
+ require "id3tag/frames/v2/comments_frame"
22
+ require "id3tag/frames/v2/genre_frame"
23
+ require "id3tag/frames/v2/genre_frame/genre_parser"
24
+ require "id3tag/frames/v2/genre_frame/genre_parser_pre_24"
25
+ require "id3tag/frames/v2/genre_frame/genre_parser_24"
26
+ require "id3tag/frames/v2/frame_fabricator"
27
+
28
+ module ID3Tag
29
+ def self.read(source, version = nil)
30
+ tag = Tag.read(source, version)
31
+ yield tag if block_given?
32
+ tag
33
+ end
34
+ end
@@ -0,0 +1,90 @@
1
+ module ID3Tag
2
+ class AudioFile
3
+ ID3V1_TAG_SIZE = 128
4
+ ID3V2_TAG_HEADER_SIZE = 10
5
+ IDV1_TAG_IDENTIFIER = "TAG"
6
+ IDV2_TAG_IDENTIFIER = "ID3"
7
+
8
+ def initialize(file)
9
+ @file = file
10
+ end
11
+
12
+ def v1_tag_present?
13
+ @file.seek(-ID3V1_TAG_SIZE, IO::SEEK_END)
14
+ @file.read(3) == IDV1_TAG_IDENTIFIER
15
+ end
16
+
17
+ def v2_tag_present?
18
+ @file.rewind
19
+ @file.read(3) == IDV2_TAG_IDENTIFIER
20
+ end
21
+
22
+ def v1_tag_body
23
+ @file.seek(-ID3V1_TAG_SIZE + IDV1_TAG_IDENTIFIER.size, IO::SEEK_END)
24
+ @file.read
25
+ end
26
+
27
+ def v2_tag_body
28
+ @file.seek(v2_tag_frame_and_padding_position)
29
+ @file.read(v2_tag_frame_and_padding_size)
30
+ end
31
+
32
+ def v2_tag_version
33
+ v2_tag_header.version_number
34
+ end
35
+
36
+ def v2_tag_major_version_number
37
+ v2_tag_header.major_version_number
38
+ end
39
+
40
+ def v2_tag_minor_version_number
41
+ v2_tag_header.minor_version_number
42
+ end
43
+
44
+ def greatest_tag_version
45
+ if v2_tag_present?
46
+ 2
47
+ elsif v1_tag_present?
48
+ 1
49
+ else
50
+ nil
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def v2_tag_frame_and_padding_position
57
+ ID3V2_TAG_HEADER_SIZE + v2_extended_header_size
58
+ end
59
+
60
+ def v2_tag_frame_and_padding_size
61
+ v2_tag_header.tag_size - v2_extended_header_size
62
+ end
63
+
64
+ def v2_extended_header_size
65
+ @v2_extended_header_size ||= get_v2_extended_header_size
66
+ end
67
+
68
+ def get_v2_extended_header_size
69
+ if v2_tag_header.extended_header?
70
+ SynchsafeInteger.decode(NumberUtil.convert_string_to_32bit_integer(v2_extended_header_size_bytes))
71
+ else
72
+ 0
73
+ end
74
+ end
75
+
76
+ def v2_extended_header_size_bytes
77
+ @file.seek(ID3V2_TAG_HEADER_SIZE)
78
+ @file.read(4)
79
+ end
80
+
81
+ def v2_tag_header
82
+ @v2_tag_header ||= get_v2_tag_header
83
+ end
84
+
85
+ def get_v2_tag_header
86
+ @file.rewind
87
+ ID3v2TagHeader.new(@file.read(ID3V2_TAG_HEADER_SIZE))
88
+ end
89
+ end
90
+ end