taglib-ruby 0.2.1 → 0.3.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.
- data/CHANGES.md +7 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +9 -8
- data/README.md +22 -7
- data/Rakefile +9 -15
- data/docs/taglib/base.rb +31 -8
- data/docs/taglib/id3v1.rb +5 -0
- data/docs/taglib/mpeg.rb +8 -0
- data/docs/taglib/ogg.rb +77 -0
- data/docs/taglib/vorbis.rb +43 -0
- data/ext/taglib_base/includes.i +25 -1
- data/ext/taglib_base/taglib_base.i +46 -2
- data/ext/taglib_base/taglib_base_wrap.cxx +176 -185
- data/ext/taglib_id3v1/extconf.rb +4 -0
- data/ext/taglib_id3v1/taglib_id3v1.i +11 -0
- data/ext/taglib_id3v1/taglib_id3v1_wrap.cxx +3092 -0
- data/ext/taglib_id3v2/taglib_id3v2.i +0 -8
- data/ext/taglib_id3v2/taglib_id3v2_wrap.cxx +194 -248
- data/ext/taglib_mpeg/taglib_mpeg.i +16 -2
- data/ext/taglib_mpeg/taglib_mpeg_wrap.cxx +157 -149
- data/ext/taglib_ogg/extconf.rb +4 -0
- data/ext/taglib_ogg/taglib_ogg.i +36 -0
- data/ext/taglib_ogg/taglib_ogg_wrap.cxx +3613 -0
- data/ext/taglib_vorbis/extconf.rb +4 -0
- data/ext/taglib_vorbis/taglib_vorbis.i +48 -0
- data/ext/taglib_vorbis/taglib_vorbis_wrap.cxx +3056 -0
- data/ext/win.cmake +6 -0
- data/lib/taglib/id3v1.rb +1 -0
- data/lib/taglib/ogg.rb +1 -0
- data/lib/taglib/version.rb +2 -2
- data/lib/taglib/vorbis.rb +1 -0
- data/lib/taglib.rb +10 -0
- data/taglib-ruby.gemspec +35 -11
- data/tasks/ext.rake +79 -0
- data/tasks/swig.rake +43 -0
- data/test/data/Makefile +15 -0
- data/test/data/id3v1-create.cpp +31 -0
- data/test/data/id3v1.mp3 +0 -0
- data/test/data/vorbis-create.cpp +42 -0
- data/test/data/vorbis.oga +0 -0
- data/test/test_fileref_write.rb +38 -0
- data/test/test_id3v1_tag.rb +36 -0
- data/test/test_id3v2_frames.rb +5 -0
- data/test/test_id3v2_memory.rb +23 -0
- data/test/test_id3v2_relative_volume.rb +5 -0
- data/test/test_id3v2_tag.rb +5 -0
- data/test/test_id3v2_unicode.rb +5 -0
- data/test/test_id3v2_write.rb +6 -1
- data/test/test_mpeg_file.rb +18 -1
- data/test/test_vorbis_file.rb +44 -0
- data/test/test_vorbis_tag.rb +79 -0
- metadata +113 -137
- data/ext/Rakefile +0 -32
data/CHANGES.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
Changes in Releases of taglib-ruby
|
2
2
|
==================================
|
3
3
|
|
4
|
+
## 0.3.0 (2012-01-02)
|
5
|
+
|
6
|
+
* Add support for Ogg Vorbis
|
7
|
+
* Add support for ID3v1 (#2)
|
8
|
+
* Add #close to File classes for explicitly releasing resources
|
9
|
+
* Fix compilation on Windows
|
10
|
+
|
4
11
|
## 0.2.1 (2011-11-05)
|
5
12
|
|
6
13
|
* Fix compilation error due to missing typedef on some systems (#5)
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,35 +1,36 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
ffi (1.0.11)
|
4
5
|
git (1.2.5)
|
5
|
-
guard (0.
|
6
|
+
guard (0.9.3)
|
7
|
+
ffi (>= 0.5.0)
|
6
8
|
thor (~> 0.14.6)
|
7
|
-
guard-test (0.4.
|
9
|
+
guard-test (0.4.3)
|
8
10
|
guard (>= 0.4)
|
9
11
|
test-unit (~> 2.2)
|
10
12
|
jeweler (1.6.4)
|
11
13
|
bundler (~> 1.0)
|
12
14
|
git (>= 1.2.5)
|
13
15
|
rake
|
14
|
-
rake (0.9.2)
|
16
|
+
rake (0.9.2.2)
|
15
17
|
rake-compiler (0.7.9)
|
16
18
|
rake
|
17
|
-
rcov (0.9.11)
|
18
19
|
redcarpet (1.17.2)
|
19
20
|
shoulda (2.11.3)
|
20
|
-
test-unit (2.4.
|
21
|
+
test-unit (2.4.3)
|
21
22
|
thor (0.14.6)
|
22
|
-
yard (0.7.
|
23
|
+
yard (0.7.4)
|
23
24
|
|
24
25
|
PLATFORMS
|
25
26
|
ruby
|
27
|
+
x86-mingw32
|
26
28
|
|
27
29
|
DEPENDENCIES
|
28
30
|
bundler (~> 1.0.0)
|
29
31
|
guard-test (~> 0.4.0)
|
30
32
|
jeweler (~> 1.6.4)
|
31
33
|
rake-compiler (~> 0.7)
|
32
|
-
|
33
|
-
redcarpet
|
34
|
+
redcarpet (~> 1.0)
|
34
35
|
shoulda (~> 2.11)
|
35
36
|
yard (~> 0.7)
|
data/README.md
CHANGED
@@ -3,15 +3,24 @@ taglib-ruby
|
|
3
3
|
|
4
4
|
Ruby interface for the [TagLib C++ library][taglib].
|
5
5
|
|
6
|
-
In contrast to other libraries, this one wraps the full C++ API
|
7
|
-
|
8
|
-
|
6
|
+
In contrast to other libraries, this one wraps the full C++ API, not
|
7
|
+
only the minimal C API. This means that all tag data can be accessed,
|
8
|
+
e.g. cover art of ID3v2 or custom fields of Ogg Vorbis comments.
|
9
9
|
|
10
|
-
taglib-ruby is work in progress,
|
11
|
-
to do (contributors very welcome):
|
10
|
+
taglib-ruby is work in progress, but the following is already available:
|
12
11
|
|
13
|
-
*
|
14
|
-
*
|
12
|
+
* Reading/writing common tag data of all formats that TagLib supports
|
13
|
+
* Reading/writing ID3v1 and ID3v2 including ID3v2.4 and Unicode
|
14
|
+
* Reading/writing Ogg Vorbis comments
|
15
|
+
* Reading audio properties (e.g. bitrate) of the above formats
|
16
|
+
|
17
|
+
Some things are still left to do (contributors very welcome):
|
18
|
+
|
19
|
+
* Pre-compiled Gem for Windows:
|
20
|
+
* Unicode filename support
|
21
|
+
* More coverage of the library
|
22
|
+
|
23
|
+
[![flattr this project][flattr-img]][flattr-link]
|
15
24
|
|
16
25
|
Installation
|
17
26
|
------------
|
@@ -61,6 +70,9 @@ track.to_s #=> "7/10"
|
|
61
70
|
cover = tag.frame_list('APIC').first
|
62
71
|
cover.mime_type #=> "image/jpeg"
|
63
72
|
cover.picture #=> "\xFF\xD8\xFF\xE0\x00\x10JFIF..."
|
73
|
+
|
74
|
+
# Close file to release resources
|
75
|
+
file.close
|
64
76
|
```
|
65
77
|
|
66
78
|
And here's an example for writing one:
|
@@ -83,6 +95,7 @@ apic.picture = File.open("cover.jpg", 'rb'){ |f| f.read }
|
|
83
95
|
tag.add_frame(apic)
|
84
96
|
|
85
97
|
file.save
|
98
|
+
file.close
|
86
99
|
```
|
87
100
|
|
88
101
|
### Encoding
|
@@ -139,3 +152,5 @@ see LICENSE.txt for details.
|
|
139
152
|
Copyright (c) 2010, 2011 Robin Stocker.
|
140
153
|
|
141
154
|
[taglib]: http://developer.kde.org/~wheeler/taglib.html
|
155
|
+
[flattr-img]: http://api.flattr.com/button/flattr-badge-large.png
|
156
|
+
[flattr-link]: https://flattr.com/submit/auto?user_id=robinst&url=https://github.com/robinst/taglib-ruby&title=taglib-ruby&tags=github&category=software
|
data/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
+
require "rubygems/package_task"
|
4
5
|
require 'bundler'
|
5
6
|
begin
|
6
7
|
Bundler.setup(:default, :development)
|
@@ -13,7 +14,7 @@ require 'rake'
|
|
13
14
|
|
14
15
|
require 'jeweler'
|
15
16
|
require './lib/taglib/version.rb'
|
16
|
-
Jeweler::Tasks.new do |gem|
|
17
|
+
jeweler_tasks = Jeweler::Tasks.new do |gem|
|
17
18
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
18
19
|
gem.name = "taglib-ruby"
|
19
20
|
gem.summary = %Q{Ruby interface for the taglib C++ library}
|
@@ -31,16 +32,15 @@ not only the minimal C API. This means that all tags can be accessed.
|
|
31
32
|
gem.authors = ["Robin Stocker"]
|
32
33
|
gem.extensions = ['ext/taglib_base/extconf.rb',
|
33
34
|
'ext/taglib_mpeg/extconf.rb',
|
34
|
-
'ext/
|
35
|
+
'ext/taglib_id3v1/extconf.rb',
|
36
|
+
'ext/taglib_id3v2/extconf.rb',
|
37
|
+
'ext/taglib_ogg/extconf.rb',
|
38
|
+
'ext/taglib_vorbis/extconf.rb']
|
39
|
+
gem.extra_rdoc_files = ["README.md", "CHANGES.md", "LICENSE.txt"]
|
35
40
|
# dependencies defined in Gemfile
|
36
41
|
end
|
37
42
|
Jeweler::RubygemsDotOrgTasks.new
|
38
43
|
|
39
|
-
require 'rake/extensiontask'
|
40
|
-
Rake::ExtensionTask.new("taglib_base")
|
41
|
-
Rake::ExtensionTask.new("taglib_mpeg")
|
42
|
-
Rake::ExtensionTask.new("taglib_id3v2")
|
43
|
-
|
44
44
|
require 'rake/testtask'
|
45
45
|
Rake::TestTask.new(:test) do |test|
|
46
46
|
test.libs << 'lib' << 'test'
|
@@ -48,14 +48,6 @@ Rake::TestTask.new(:test) do |test|
|
|
48
48
|
test.verbose = true
|
49
49
|
end
|
50
50
|
|
51
|
-
require 'rcov/rcovtask'
|
52
|
-
Rcov::RcovTask.new do |test|
|
53
|
-
test.libs << 'test'
|
54
|
-
test.pattern = 'test/**/test_*.rb'
|
55
|
-
test.verbose = true
|
56
|
-
test.rcov_opts << '--exclude "gems/*"'
|
57
|
-
end
|
58
|
-
|
59
51
|
task :default => :test
|
60
52
|
|
61
53
|
require 'yard'
|
@@ -64,4 +56,6 @@ YARD::Rake::YardocTask.new do |t|
|
|
64
56
|
t.options = ['--title', "taglib-ruby #{version}"]
|
65
57
|
end
|
66
58
|
|
59
|
+
$gemspec = jeweler_tasks.jeweler.gemspec.dup
|
60
|
+
|
67
61
|
FileList['tasks/**/*.rake'].each { |task| import task }
|
data/docs/taglib/base.rb
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
# * Reading properties of MPEG files: {TagLib::MPEG::File}
|
8
8
|
# * Reading/writing ID3v2 tags: {TagLib::MPEG::File} and
|
9
9
|
# {TagLib::MPEG::File#id3v2_tag}
|
10
|
+
# * Reading/writing Ogg Vorbis tags: {TagLib::Ogg::Vorbis::File}.
|
10
11
|
#
|
11
12
|
# ## String Encodings
|
12
13
|
#
|
@@ -60,10 +61,36 @@ module TagLib
|
|
60
61
|
# @return [TagLib::Tag] the tag
|
61
62
|
def tag
|
62
63
|
end
|
64
|
+
|
65
|
+
# Closes the file and releases all objects that were read from the
|
66
|
+
# file.
|
67
|
+
#
|
68
|
+
# @see TagLib::File#close
|
69
|
+
#
|
70
|
+
# @return [void]
|
71
|
+
def close
|
72
|
+
end
|
63
73
|
end
|
64
74
|
|
65
75
|
# @abstract Base class for files, see subclasses.
|
66
76
|
class File
|
77
|
+
# Closes the file and releases all objects that were read from the
|
78
|
+
# file.
|
79
|
+
#
|
80
|
+
# After this method has been called, no other methods on this object
|
81
|
+
# may be called. So it's a good idea to always use it like this:
|
82
|
+
#
|
83
|
+
# file.close
|
84
|
+
# file = nil
|
85
|
+
#
|
86
|
+
# This method should always be called as soon as you're finished
|
87
|
+
# with a file. Otherwise the file will only be closed when GC is
|
88
|
+
# run, which may be much later. On Windows, this is especially
|
89
|
+
# important as the file is locked until it is closed.
|
90
|
+
#
|
91
|
+
# @return [void]
|
92
|
+
def close
|
93
|
+
end
|
67
94
|
end
|
68
95
|
|
69
96
|
# @abstract Base class for tags.
|
@@ -112,19 +139,15 @@ module TagLib
|
|
112
139
|
Accurate = 2
|
113
140
|
|
114
141
|
# @return [Integer] length of the file in seconds
|
115
|
-
|
116
|
-
end
|
142
|
+
attr_reader :length
|
117
143
|
|
118
144
|
# @return [Integer] bit rate in kb/s (kilobit per second)
|
119
|
-
|
120
|
-
end
|
145
|
+
attr_reader :bitrate
|
121
146
|
|
122
147
|
# @return [Integer] sample rate in Hz
|
123
|
-
|
124
|
-
end
|
148
|
+
attr_reader :sample_rate
|
125
149
|
|
126
150
|
# @return [Integer] number of channels
|
127
|
-
|
128
|
-
end
|
151
|
+
attr_reader :channels
|
129
152
|
end
|
130
153
|
end
|
data/docs/taglib/mpeg.rb
CHANGED
@@ -17,6 +17,14 @@ module TagLib::MPEG
|
|
17
17
|
def tag
|
18
18
|
end
|
19
19
|
|
20
|
+
# Returns the ID3v1 tag.
|
21
|
+
#
|
22
|
+
# @param create if a new tag should be created when none exists
|
23
|
+
# @return [TagLib::ID3v1::Tag]
|
24
|
+
# @return [nil] if not present
|
25
|
+
def id3v1_tag(create=false)
|
26
|
+
end
|
27
|
+
|
20
28
|
# Returns the ID3v2 tag.
|
21
29
|
#
|
22
30
|
# @param create if a new tag should be created when none exists
|
data/docs/taglib/ogg.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module TagLib::Ogg
|
2
|
+
|
3
|
+
# @abstract Base class for Ogg files, see subclasses.
|
4
|
+
class File < TagLib::File
|
5
|
+
end
|
6
|
+
|
7
|
+
# Xiph comments (aka VorbisComment), a metadata format used for Ogg
|
8
|
+
# Vorbis and other codecs.
|
9
|
+
#
|
10
|
+
# A Xiph comment is structured as a set of fields. Each field has a
|
11
|
+
# name and a value. Multiple fields with the same name are allowed, so
|
12
|
+
# you can also view it as a map from names to a list of values.
|
13
|
+
class XiphComment < TagLib::Tag
|
14
|
+
|
15
|
+
# Add a name-value pair to the comment.
|
16
|
+
#
|
17
|
+
# @param [String] name field name
|
18
|
+
# @param [String] value field value
|
19
|
+
# @param [Boolean] replace if true, all existing fields with the
|
20
|
+
# given name will be replaced
|
21
|
+
# @return [void]
|
22
|
+
def add_field(name, value, replace=true)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if the comment contains a field.
|
26
|
+
#
|
27
|
+
# @param [String] name field name
|
28
|
+
# @return [Boolean]
|
29
|
+
def contains?(name)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Count the number of fields.
|
33
|
+
#
|
34
|
+
# @return [Integer] the number of fields in the comment (name-value
|
35
|
+
# pairs)
|
36
|
+
def field_count
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get the contents of the comment as a hash, with the key being a
|
40
|
+
# field name String and the value a list of field values for that
|
41
|
+
# key. Example result:
|
42
|
+
#
|
43
|
+
# { 'TITLE' => ["Title"],
|
44
|
+
# 'GENRE' => ["Rock", "Pop"] }
|
45
|
+
#
|
46
|
+
# Note that the returned hash is read-only. Changing it will have no
|
47
|
+
# effect on the comment; use {#add_field} and {#remove_field} for
|
48
|
+
# that.
|
49
|
+
#
|
50
|
+
# @return [Hash<String, Array<String>>] a hash from field names to
|
51
|
+
# value lists
|
52
|
+
def field_list_map
|
53
|
+
end
|
54
|
+
|
55
|
+
# Remove one or more fields.
|
56
|
+
#
|
57
|
+
# @overload remove_field(name)
|
58
|
+
# Removes all fields with the given name.
|
59
|
+
#
|
60
|
+
# @param [String] name field name
|
61
|
+
#
|
62
|
+
# @overload remove_field(name, value)
|
63
|
+
# Removes the field with the given name and value.
|
64
|
+
#
|
65
|
+
# @param [String] name field name
|
66
|
+
# @param [String] value field value
|
67
|
+
#
|
68
|
+
# @return [void]
|
69
|
+
def remove_field
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [String] vendor ID of the encoder used
|
73
|
+
attr_reader :vendor_id
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module TagLib::Ogg::Vorbis
|
2
|
+
|
3
|
+
# The file class for `.ogg` and other `.oga` files.
|
4
|
+
class File < TagLib::Ogg::File
|
5
|
+
# Load an Ogg Vorbis file.
|
6
|
+
#
|
7
|
+
# @param [String] filename
|
8
|
+
# @param [Boolean] read_properties if audio properties should be
|
9
|
+
# read
|
10
|
+
def initialize(filename, read_properties=true)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the VorbisComment tag.
|
14
|
+
#
|
15
|
+
# @return [TagLib::Ogg::XiphComment]
|
16
|
+
def tag
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns audio properties.
|
20
|
+
#
|
21
|
+
# @return [TagLib::Ogg::Vorbis::Properties]
|
22
|
+
def audio_properties
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Ogg Vorbis audio properties.
|
27
|
+
class Properties < TagLib::AudioProperties
|
28
|
+
# @return [Integer] Vorbis version
|
29
|
+
attr_reader :vorbis_version
|
30
|
+
|
31
|
+
# @return [Integer] maximum bitrate from Vorbis identification
|
32
|
+
# header
|
33
|
+
attr_reader :bitrate_maximum
|
34
|
+
|
35
|
+
# @return [Integer] nominal bitrate from Vorbis identification
|
36
|
+
# header
|
37
|
+
attr_reader :bitrate_nominal
|
38
|
+
|
39
|
+
# @return [Integer] minimum bitrate from Vorbis identification
|
40
|
+
# header
|
41
|
+
attr_reader :bitrate_minimum
|
42
|
+
end
|
43
|
+
end
|
data/ext/taglib_base/includes.i
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
%trackobjects;
|
2
2
|
|
3
|
-
// Undefine
|
3
|
+
// Undefine macros we don't need for wrapping
|
4
4
|
#define TAGLIB_EXPORT
|
5
|
+
#define TAGLIB_IGNORE_MISSING_DESTRUCTOR
|
5
6
|
|
6
7
|
// Replaces the typemap from swigtype.swg and just adds the line
|
7
8
|
// SWIG_RubyUnlinkObjects. This is done to be safe in the case when a
|
@@ -15,6 +16,10 @@
|
|
15
16
|
}
|
16
17
|
|
17
18
|
%{
|
19
|
+
#include <taglib/tstring.h>
|
20
|
+
#include <taglib/tstringlist.h>
|
21
|
+
#include <taglib/tfile.h>
|
22
|
+
|
18
23
|
#if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
|
19
24
|
# include <ruby/encoding.h>
|
20
25
|
# define ASSOCIATE_UTF8_ENCODING(value) rb_enc_associate(value, rb_utf8_encoding());
|
@@ -68,6 +73,25 @@ TagLib::StringList ruby_array_to_taglib_string_list(VALUE ary) {
|
|
68
73
|
}
|
69
74
|
return result;
|
70
75
|
}
|
76
|
+
|
77
|
+
VALUE taglib_filename_to_ruby_string(TagLib::FileName filename) {
|
78
|
+
#ifdef _WIN32
|
79
|
+
const char *s = (const char *) filename;
|
80
|
+
return rb_tainted_str_new2(s);
|
81
|
+
#else
|
82
|
+
return rb_tainted_str_new2(filename);
|
83
|
+
#endif
|
84
|
+
}
|
85
|
+
|
86
|
+
TagLib::FileName ruby_string_to_taglib_filename(VALUE s) {
|
87
|
+
#ifdef _WIN32
|
88
|
+
const char *filename = StringValuePtr(s);
|
89
|
+
return TagLib::FileName(filename);
|
90
|
+
#else
|
91
|
+
return StringValuePtr(s);
|
92
|
+
#endif
|
93
|
+
}
|
94
|
+
|
71
95
|
%}
|
72
96
|
|
73
97
|
// vim: set filetype=cpp sw=2 ts=2 expandtab:
|