id3lib-ruby 0.3.1 → 0.4.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 +6 -0
- data/Rakefile +16 -8
- data/ext/Rakefile +21 -0
- data/ext/generate_info.rb +114 -0
- data/ext/id3lib_api.i +179 -0
- data/ext/id3lib_api_wrap.cxx +123 -99
- data/lib/id3lib.rb +31 -24
- data/test/test_writing.rb +11 -4
- data/usage.rb +40 -0
- metadata +9 -3
data/CHANGES
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= id3lib-ruby changes
|
2
2
|
|
3
|
+
=== 0.4.0 (r41)
|
4
|
+
|
5
|
+
* Fixed Unicode problems (bug 4768).
|
6
|
+
* Renamed ID3Lib::API methods to be more like the id3lib method names.
|
7
|
+
For example, the GetType() method is now named get_type instead of type.
|
8
|
+
|
3
9
|
=== 0.3.1 (r32)
|
4
10
|
|
5
11
|
* Added check and messages for -lstdc++ and -lz to extconf.rb.
|
data/Rakefile
CHANGED
@@ -10,15 +10,22 @@ require 'rake/testtask'
|
|
10
10
|
require 'rake/rdoctask'
|
11
11
|
|
12
12
|
|
13
|
-
PKG_VERSION = '0.
|
13
|
+
PKG_VERSION = '0.4.0'
|
14
14
|
|
15
|
-
|
15
|
+
FILES_COMMON = FileList[
|
16
16
|
'lib/**/*.rb',
|
17
17
|
'test/test_*.rb',
|
18
18
|
'test/data/*.mp3',
|
19
19
|
'test/data/cover.jpg',
|
20
20
|
'Rakefile',
|
21
|
-
'
|
21
|
+
'*.rb'
|
22
|
+
]
|
23
|
+
|
24
|
+
FILES_EXT = FileList[
|
25
|
+
'ext/*.rb',
|
26
|
+
'ext/*.cxx',
|
27
|
+
'ext/*.i',
|
28
|
+
'ext/Rakefile'
|
22
29
|
]
|
23
30
|
|
24
31
|
|
@@ -42,7 +49,7 @@ Rake::TestTask.new do |t|
|
|
42
49
|
end
|
43
50
|
|
44
51
|
|
45
|
-
RDOC_OPTS = ['--line-numbers', '--main', 'README']
|
52
|
+
RDOC_OPTS = ['--inline-source', '--line-numbers', '--main', 'README']
|
46
53
|
|
47
54
|
desc "Generate RDOC documentation."
|
48
55
|
Rake::RDocTask.new :rdoc do |rdoc|
|
@@ -63,7 +70,7 @@ if defined? Gem
|
|
63
70
|
'id3lib-ruby provides a Ruby interface to the id3lib C++ library for ' +
|
64
71
|
'easily editing ID3 tags (v1 and v2) like with pyid3lib.'
|
65
72
|
s.requirements << 'id3lib C++ library'
|
66
|
-
s.files =
|
73
|
+
s.files = FILES_COMMON + FILES_EXT
|
67
74
|
s.extensions = ['ext/extconf.rb']
|
68
75
|
s.test_files = FileList['test/test_*.rb']
|
69
76
|
s.has_rdoc = true
|
@@ -81,7 +88,7 @@ if defined? Gem
|
|
81
88
|
end
|
82
89
|
|
83
90
|
spec_mswin32 = spec.clone
|
84
|
-
spec_mswin32.files =
|
91
|
+
spec_mswin32.files = FILES_COMMON + FileList['ext/mswin32/id3lib_api.so']
|
85
92
|
spec_mswin32.extensions = []
|
86
93
|
spec_mswin32.require_paths = ['lib', 'ext/mswin32']
|
87
94
|
spec_mswin32.platform = Gem::Platform::WIN32
|
@@ -99,14 +106,15 @@ end # defined? Gem
|
|
99
106
|
task :web => [:web_doc] do
|
100
107
|
puts "# Now execute the following:"
|
101
108
|
puts "scp web/* robinstocker@rubyforge.org:/var/www/gforge-projects/id3lib-ruby/"
|
102
|
-
puts "scp -r web/doc robinstocker@rubyforge.org:/var/www/gforge-projects/id3lib-ruby/
|
109
|
+
puts "scp -r web/doc robinstocker@rubyforge.org:/var/www/gforge-projects/id3lib-ruby/"
|
103
110
|
end
|
104
111
|
|
105
112
|
desc "Generate RDOC documentation on web."
|
106
113
|
Rake::RDocTask.new :web_doc do |rdoc|
|
107
114
|
rdoc.rdoc_dir = 'web/doc'
|
108
115
|
rdoc.title = 'id3lib-ruby'
|
109
|
-
rdoc.options
|
116
|
+
rdoc.options = RDOC_OPTS.clone
|
117
|
+
rdoc.options << '--main' << 'ID3Lib::Tag'
|
110
118
|
rdoc.rdoc_files.include('README', 'TODO', 'CHANGES')
|
111
119
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
112
120
|
end
|
data/ext/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
require 'rake/clean'
|
3
|
+
|
4
|
+
|
5
|
+
CLEAN.include '*.o', 'Makefile', 'mkmf.log'
|
6
|
+
CLOBBER.include 'id3lib_api.so', 'id3lib_api.bundle'
|
7
|
+
|
8
|
+
task :default => ['id3lib_api.bundle']
|
9
|
+
task :swig => ['id3lib_api_wrap.cxx']
|
10
|
+
|
11
|
+
file 'id3lib_api.bundle' => ['id3lib_api_wrap.cxx', 'Makefile'] do
|
12
|
+
sh "make"
|
13
|
+
end
|
14
|
+
|
15
|
+
file 'id3lib_api_wrap.cxx' => ['id3lib_api.i'] do
|
16
|
+
sh "swig -c++ -ruby -feature id3lib_api id3lib_api.i"
|
17
|
+
end
|
18
|
+
|
19
|
+
file 'Makefile' do
|
20
|
+
ruby "extconf.rb"
|
21
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
|
3
|
+
file = ARGV.first || '/usr/local/include/id3/globals.h'
|
4
|
+
|
5
|
+
data = IO.read(file)
|
6
|
+
|
7
|
+
fields = []
|
8
|
+
frames = []
|
9
|
+
genres = []
|
10
|
+
|
11
|
+
data.scan(/ID3_ENUM\((\w+)\)\s+\{\s+(.+?)\s+\}/m) do |name, enum|
|
12
|
+
case name
|
13
|
+
when 'ID3_FieldID'
|
14
|
+
id = 0
|
15
|
+
enum.scan(/([^\s,]+)(?: = (\d+),|,)\s*\/\*\*< ([^*]+)\s+\*\//m) do |field, newid, description|
|
16
|
+
id = newid.to_i if newid
|
17
|
+
field.sub!('ID3FN_', '')
|
18
|
+
field.downcase!
|
19
|
+
fields << [id, field.to_sym, description]
|
20
|
+
id += 1
|
21
|
+
end
|
22
|
+
when 'ID3_FrameID'
|
23
|
+
id = 0
|
24
|
+
enum.scan(/\/\* (\S+) \*\/ [^\s,]+(?: = (\d+),|,)\s*\/\*\*< ([^*]+)\s+\*\//m) do |frame, newid, description|
|
25
|
+
id = newid.to_i if newid
|
26
|
+
if frame == '????'
|
27
|
+
frame = :____
|
28
|
+
else
|
29
|
+
frame = frame.to_sym
|
30
|
+
end
|
31
|
+
possible_fields =
|
32
|
+
case frame
|
33
|
+
when :____ : []
|
34
|
+
when :AENC : [:owner, :data]
|
35
|
+
when :APIC : [:textenc, :mimetype, :picturetype, :description, :data]
|
36
|
+
when :ASPI, :COMR, :EQUA, :ETCO, :LINK,
|
37
|
+
:MCDI, :MLLT, :OWNE, :POSS, :RBUF,
|
38
|
+
:RVA2, :RVAD, :RVRB, :SEEK
|
39
|
+
[:data]
|
40
|
+
when :COMM : [:textenc, :language, :description, :text]
|
41
|
+
when :ENCR : [:owner, :id, :data]
|
42
|
+
when :EQU2 : [:id, :text]
|
43
|
+
when :GEOB : [:textenc, :mimetype, :filename, :description, :data]
|
44
|
+
when :GRID : [:owner, :id, :data]
|
45
|
+
when :IPLS : [:textenc, :text]
|
46
|
+
when :PRIV : [:owner, :data]
|
47
|
+
when :PCNT : [:counter]
|
48
|
+
when :POPM : [:email, :rating, :counter]
|
49
|
+
when :SIGN : [:id, :data]
|
50
|
+
when :SYLT : [:textenc, :language, :timestampformat, :contenttype, :description, :data]
|
51
|
+
when :SYTC : [:timestampformat, :data]
|
52
|
+
when :UFID : [:owner, :data]
|
53
|
+
when :USER : [:textenc, :language, :text]
|
54
|
+
when :USLT : [:textenc, :language, :description, :text]
|
55
|
+
when :WCOM, :WCOP, :WOAF, :WOAR, :WOAS, :WORS, :WPAY, :WPUB : [:text]
|
56
|
+
when :WXXX : [:textenc, :description, :url]
|
57
|
+
else [:textenc, :text]
|
58
|
+
end
|
59
|
+
frames << [id, frame, description, possible_fields]
|
60
|
+
id += 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
data.scan(/(ID3_v1_genre_description).+?\{(.+?)\}/m) do |name, list|
|
66
|
+
id = 0
|
67
|
+
list.scan(/"(.+?)"/) do |genre|
|
68
|
+
genres << genre.first
|
69
|
+
id += 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def indent level, text
|
75
|
+
puts ' ' * level + text
|
76
|
+
end
|
77
|
+
|
78
|
+
indent 4, "Frames = ["
|
79
|
+
frames.each do |f|
|
80
|
+
comment = case f[1]
|
81
|
+
when :____ : "# Special frames"
|
82
|
+
when :TALB : "# Text information frames"
|
83
|
+
when :UFID : "# Special frames again"
|
84
|
+
when :WCOM : "# URL link frames"
|
85
|
+
end
|
86
|
+
indent 6, comment if comment
|
87
|
+
indent 6, f.inspect + ","
|
88
|
+
end
|
89
|
+
indent 4, "]"
|
90
|
+
|
91
|
+
indent 4, "FramesByID = {"
|
92
|
+
frames.each do |f|
|
93
|
+
indent 6, f[1].inspect + " => Frames[" + f[0].to_s + "],"
|
94
|
+
end
|
95
|
+
indent 4, "}"
|
96
|
+
|
97
|
+
indent 4, "Fields = ["
|
98
|
+
fields.each do |f|
|
99
|
+
indent 6, f.inspect + ","
|
100
|
+
end
|
101
|
+
indent 4, "]"
|
102
|
+
|
103
|
+
indent 4, "FieldsByID = {"
|
104
|
+
fields.each do |f|
|
105
|
+
indent 6, f[1].inspect.ljust(16) + " => Fields[" + f[0].to_s + "],"
|
106
|
+
end
|
107
|
+
indent 4, "}"
|
108
|
+
|
109
|
+
indent 4, "Genres = ["
|
110
|
+
genres.each_slice(4) do |gs|
|
111
|
+
indent 6, "# Winamp extensions" if gs.first == "Folk"
|
112
|
+
indent 6, gs.map{ |g| g.inspect }.join(", ") + ","
|
113
|
+
end
|
114
|
+
indent 4, "]"
|
data/ext/id3lib_api.i
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
%module "ID3Lib::API"
|
2
|
+
%{
|
3
|
+
#include <id3/tag.h>
|
4
|
+
%}
|
5
|
+
|
6
|
+
|
7
|
+
enum ID3_FrameID;
|
8
|
+
enum ID3_FieldID;
|
9
|
+
enum ID3_FieldType;
|
10
|
+
enum ID3_TextEnc;
|
11
|
+
enum ID3_TagType;
|
12
|
+
|
13
|
+
typedef unsigned int flags_t;
|
14
|
+
|
15
|
+
|
16
|
+
%rename (Tag) ID3_Tag;
|
17
|
+
class ID3_Tag
|
18
|
+
{
|
19
|
+
public:
|
20
|
+
|
21
|
+
ID3_Tag(const char *name = NULL);
|
22
|
+
~ID3_Tag();
|
23
|
+
|
24
|
+
%rename (has_tag_type) HasTagType;
|
25
|
+
bool HasTagType(ID3_TagType type) const;
|
26
|
+
|
27
|
+
%rename (link) Link;
|
28
|
+
size_t Link(const char *filename, flags_t flags = ID3TT_ALL);
|
29
|
+
|
30
|
+
%rename (update) Update;
|
31
|
+
flags_t Update(flags_t flags = ID3TT_ALL);
|
32
|
+
|
33
|
+
%rename (strip) Strip;
|
34
|
+
flags_t Strip(flags_t flags = ID3TT_ALL);
|
35
|
+
|
36
|
+
%rename (clear) Clear;
|
37
|
+
void Clear();
|
38
|
+
|
39
|
+
%rename (remove_frame) RemoveFrame;
|
40
|
+
ID3_Frame * RemoveFrame(const ID3_Frame *frame);
|
41
|
+
|
42
|
+
%rename (add_frame) AddFrame;
|
43
|
+
void AddFrame(const ID3_Frame *frame);
|
44
|
+
|
45
|
+
%rename (get_filename) GetFileName;
|
46
|
+
const char * GetFileName() const;
|
47
|
+
|
48
|
+
%rename (set_padding) SetPadding;
|
49
|
+
bool SetPadding(bool padding);
|
50
|
+
|
51
|
+
%rename (size) Size;
|
52
|
+
size_t Size() const;
|
53
|
+
|
54
|
+
%rename (find) Find;
|
55
|
+
ID3_Frame * Find(ID3_FrameID name) const;
|
56
|
+
|
57
|
+
%rename (iterator_new) CreateIterator;
|
58
|
+
ID3_Tag::Iterator * CreateIterator();
|
59
|
+
|
60
|
+
// Needed because SWIG does not support nested classes yet.
|
61
|
+
%extend
|
62
|
+
{
|
63
|
+
ID3_Frame * iterator_next_frame(ID3_Tag::Iterator *iterator)
|
64
|
+
{
|
65
|
+
return iterator->GetNext();
|
66
|
+
}
|
67
|
+
}
|
68
|
+
};
|
69
|
+
|
70
|
+
|
71
|
+
%rename (Frame) ID3_Frame;
|
72
|
+
class ID3_Frame
|
73
|
+
{
|
74
|
+
public:
|
75
|
+
|
76
|
+
ID3_Frame(ID3_FrameID id = ID3FID_NOFRAME);
|
77
|
+
~ID3_Frame();
|
78
|
+
|
79
|
+
%rename (get_field) GetField;
|
80
|
+
ID3_Field * GetField(ID3_FieldID name) const;
|
81
|
+
|
82
|
+
%rename (get_id) GetID;
|
83
|
+
ID3_FrameID GetID() const;
|
84
|
+
};
|
85
|
+
|
86
|
+
|
87
|
+
%rename (Field) ID3_Field;
|
88
|
+
class ID3_Field
|
89
|
+
{
|
90
|
+
public:
|
91
|
+
|
92
|
+
// Getters
|
93
|
+
|
94
|
+
%rename (get_type) GetType;
|
95
|
+
ID3_FieldType GetType() const;
|
96
|
+
|
97
|
+
%rename (get_encoding) GetEncoding;
|
98
|
+
ID3_TextEnc GetEncoding() const;
|
99
|
+
|
100
|
+
%rename (get_integer) Get;
|
101
|
+
unsigned long Get() const;
|
102
|
+
|
103
|
+
%rename (get_ascii) GetRawText;
|
104
|
+
const char * GetRawText() const;
|
105
|
+
|
106
|
+
%extend
|
107
|
+
{
|
108
|
+
VALUE get_binary()
|
109
|
+
{
|
110
|
+
return rb_str_new((const char *)self->GetRawBinary(), self->Size());
|
111
|
+
}
|
112
|
+
|
113
|
+
VALUE get_unicode()
|
114
|
+
{
|
115
|
+
const char *string = (const char *)self->GetRawUnicodeText();
|
116
|
+
if (string == NULL) return rb_str_new("", 0);
|
117
|
+
long size = self->Size();
|
118
|
+
if (size >= 2 && string[size-2] == '\0' && string[size-1] == '\0') {
|
119
|
+
// id3lib seems to be inconsistent: the Unicode strings
|
120
|
+
// don't always end in 0x0000. If they do, we don't want these
|
121
|
+
// trailing bytes.
|
122
|
+
size -= 2;
|
123
|
+
}
|
124
|
+
return rb_str_new(string, size);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
// Setters
|
129
|
+
|
130
|
+
%rename (set_encoding) SetEncoding(ID3_TextEnc);
|
131
|
+
bool SetEncoding(ID3_TextEnc enc);
|
132
|
+
|
133
|
+
%rename (set_integer) Set(unsigned long);
|
134
|
+
void Set(unsigned long i);
|
135
|
+
|
136
|
+
%rename (set_ascii) Set(const char *);
|
137
|
+
size_t Set(const char *string);
|
138
|
+
|
139
|
+
%extend
|
140
|
+
{
|
141
|
+
size_t set_binary(VALUE data)
|
142
|
+
{
|
143
|
+
StringValue(data);
|
144
|
+
return self->Set((const unsigned char *)RSTRING(data)->ptr,
|
145
|
+
RSTRING(data)->len);
|
146
|
+
}
|
147
|
+
|
148
|
+
size_t set_unicode(VALUE data)
|
149
|
+
{
|
150
|
+
StringValue(data);
|
151
|
+
|
152
|
+
long len;
|
153
|
+
unicode_t *unicode;
|
154
|
+
|
155
|
+
len = RSTRING(data)->len / sizeof(unicode_t);
|
156
|
+
unicode = (unicode_t *)malloc(sizeof(unicode_t) * (len+1));
|
157
|
+
|
158
|
+
if (unicode == NULL) {
|
159
|
+
rb_raise(rb_eNoMemError, "Couldn't allocate memory for Unicode data.");
|
160
|
+
}
|
161
|
+
|
162
|
+
memcpy(unicode, RSTRING(data)->ptr, sizeof(unicode_t) * len);
|
163
|
+
// Unicode strings need 0x0000 at the end.
|
164
|
+
unicode[len] = 0;
|
165
|
+
size_t retval = self->Set(unicode);
|
166
|
+
|
167
|
+
// Free Unicode! ;)
|
168
|
+
free(unicode);
|
169
|
+
return retval;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
protected:
|
174
|
+
|
175
|
+
ID3_Field();
|
176
|
+
~ID3_Field();
|
177
|
+
};
|
178
|
+
|
179
|
+
// vim: set filetype=cpp sw=4 ts=4 noexpandtab:
|
data/ext/id3lib_api_wrap.cxx
CHANGED
@@ -1795,8 +1795,8 @@ SWIG_AsVal_bool (VALUE obj, bool *val)
|
|
1795
1795
|
}
|
1796
1796
|
|
1797
1797
|
SWIGINTERN ID3_Frame *ID3_Tag_iterator_next_frame(ID3_Tag *self,ID3_Tag::Iterator *iterator){
|
1798
|
-
|
1799
|
-
|
1798
|
+
return iterator->GetNext();
|
1799
|
+
}
|
1800
1800
|
|
1801
1801
|
SWIGINTERNINLINE VALUE
|
1802
1802
|
SWIG_From_int (int value)
|
@@ -1804,49 +1804,48 @@ SWIG_From_int (int value)
|
|
1804
1804
|
return SWIG_From_long (value);
|
1805
1805
|
}
|
1806
1806
|
|
1807
|
-
SWIGINTERN VALUE
|
1808
|
-
|
1809
|
-
|
1810
|
-
SWIGINTERN VALUE
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
}
|
1807
|
+
SWIGINTERN VALUE ID3_Field_get_binary(ID3_Field *self){
|
1808
|
+
return rb_str_new((const char *)self->GetRawBinary(), self->Size());
|
1809
|
+
}
|
1810
|
+
SWIGINTERN VALUE ID3_Field_get_unicode(ID3_Field *self){
|
1811
|
+
const char *string = (const char *)self->GetRawUnicodeText();
|
1812
|
+
if (string == NULL) return rb_str_new("", 0);
|
1813
|
+
long size = self->Size();
|
1814
|
+
if (size >= 2 && string[size-2] == '\0' && string[size-1] == '\0') {
|
1815
|
+
// id3lib seems to be inconsistent: the Unicode strings
|
1816
|
+
// don't always end in 0x0000. If they do, we don't want these
|
1817
|
+
// trailing bytes.
|
1818
|
+
size -= 2;
|
1819
|
+
}
|
1820
|
+
return rb_str_new(string, size);
|
1821
|
+
}
|
1823
1822
|
SWIGINTERN size_t ID3_Field_set_binary(ID3_Field *self,VALUE data){
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1823
|
+
StringValue(data);
|
1824
|
+
return self->Set((const unsigned char *)RSTRING(data)->ptr,
|
1825
|
+
RSTRING(data)->len);
|
1826
|
+
}
|
1828
1827
|
SWIGINTERN size_t ID3_Field_set_unicode(ID3_Field *self,VALUE data){
|
1829
|
-
|
1828
|
+
StringValue(data);
|
1830
1829
|
|
1831
|
-
|
1832
|
-
|
1830
|
+
long len;
|
1831
|
+
unicode_t *unicode;
|
1833
1832
|
|
1834
|
-
|
1835
|
-
|
1833
|
+
len = RSTRING(data)->len / sizeof(unicode_t);
|
1834
|
+
unicode = (unicode_t *)malloc(sizeof(unicode_t) * (len+1));
|
1836
1835
|
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1836
|
+
if (unicode == NULL) {
|
1837
|
+
rb_raise(rb_eNoMemError, "Couldn't allocate memory for Unicode data.");
|
1838
|
+
}
|
1839
|
+
|
1840
|
+
memcpy(unicode, RSTRING(data)->ptr, sizeof(unicode_t) * len);
|
1841
|
+
// Unicode strings need 0x0000 at the end.
|
1842
|
+
unicode[len] = 0;
|
1843
|
+
size_t retval = self->Set(unicode);
|
1844
|
+
|
1845
|
+
// Free Unicode! ;)
|
1846
|
+
free(unicode);
|
1847
|
+
return retval;
|
1848
|
+
}
|
1850
1849
|
swig_class cTag;
|
1851
1850
|
|
1852
1851
|
SWIGINTERN VALUE
|
@@ -2379,7 +2378,7 @@ fail:
|
|
2379
2378
|
|
2380
2379
|
|
2381
2380
|
SWIGINTERN VALUE
|
2382
|
-
|
2381
|
+
_wrap_Tag_get_filename(int argc, VALUE *argv, VALUE self) {
|
2383
2382
|
ID3_Tag *arg1 = (ID3_Tag *) 0 ;
|
2384
2383
|
char *result = 0 ;
|
2385
2384
|
void *argp1 = 0 ;
|
@@ -2639,7 +2638,7 @@ free_ID3_Frame(ID3_Frame *arg1) {
|
|
2639
2638
|
}
|
2640
2639
|
|
2641
2640
|
SWIGINTERN VALUE
|
2642
|
-
|
2641
|
+
_wrap_Frame_get_field(int argc, VALUE *argv, VALUE self) {
|
2643
2642
|
ID3_Frame *arg1 = (ID3_Frame *) 0 ;
|
2644
2643
|
ID3_FieldID arg2 ;
|
2645
2644
|
ID3_Field *result = 0 ;
|
@@ -2671,7 +2670,7 @@ fail:
|
|
2671
2670
|
|
2672
2671
|
|
2673
2672
|
SWIGINTERN VALUE
|
2674
|
-
|
2673
|
+
_wrap_Frame_get_id(int argc, VALUE *argv, VALUE self) {
|
2675
2674
|
ID3_Frame *arg1 = (ID3_Frame *) 0 ;
|
2676
2675
|
ID3_FrameID result;
|
2677
2676
|
void *argp1 = 0 ;
|
@@ -2697,7 +2696,7 @@ fail:
|
|
2697
2696
|
swig_class cField;
|
2698
2697
|
|
2699
2698
|
SWIGINTERN VALUE
|
2700
|
-
|
2699
|
+
_wrap_Field_get_type(int argc, VALUE *argv, VALUE self) {
|
2701
2700
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2702
2701
|
ID3_FieldType result;
|
2703
2702
|
void *argp1 = 0 ;
|
@@ -2721,9 +2720,9 @@ fail:
|
|
2721
2720
|
|
2722
2721
|
|
2723
2722
|
SWIGINTERN VALUE
|
2724
|
-
|
2723
|
+
_wrap_Field_get_encoding(int argc, VALUE *argv, VALUE self) {
|
2725
2724
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2726
|
-
|
2725
|
+
ID3_TextEnc result;
|
2727
2726
|
void *argp1 = 0 ;
|
2728
2727
|
int res1 = 0 ;
|
2729
2728
|
VALUE vresult = Qnil;
|
@@ -2733,11 +2732,11 @@ _wrap_Field_integer(int argc, VALUE *argv, VALUE self) {
|
|
2733
2732
|
}
|
2734
2733
|
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
|
2735
2734
|
if (!SWIG_IsOK(res1)) {
|
2736
|
-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "
|
2735
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GetEncoding" "', argument " "1"" of type '" "ID3_Field const *""'");
|
2737
2736
|
}
|
2738
2737
|
arg1 = reinterpret_cast< ID3_Field * >(argp1);
|
2739
|
-
result = (
|
2740
|
-
vresult =
|
2738
|
+
result = (ID3_TextEnc)((ID3_Field const *)arg1)->GetEncoding();
|
2739
|
+
vresult = SWIG_From_int(static_cast< int >(result));
|
2741
2740
|
return vresult;
|
2742
2741
|
fail:
|
2743
2742
|
return Qnil;
|
@@ -2745,9 +2744,9 @@ fail:
|
|
2745
2744
|
|
2746
2745
|
|
2747
2746
|
SWIGINTERN VALUE
|
2748
|
-
|
2747
|
+
_wrap_Field_get_integer(int argc, VALUE *argv, VALUE self) {
|
2749
2748
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2750
|
-
|
2749
|
+
unsigned long result;
|
2751
2750
|
void *argp1 = 0 ;
|
2752
2751
|
int res1 = 0 ;
|
2753
2752
|
VALUE vresult = Qnil;
|
@@ -2757,11 +2756,11 @@ _wrap_Field_binary(int argc, VALUE *argv, VALUE self) {
|
|
2757
2756
|
}
|
2758
2757
|
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
|
2759
2758
|
if (!SWIG_IsOK(res1)) {
|
2760
|
-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "
|
2759
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Get" "', argument " "1"" of type '" "ID3_Field const *""'");
|
2761
2760
|
}
|
2762
2761
|
arg1 = reinterpret_cast< ID3_Field * >(argp1);
|
2763
|
-
result = (
|
2764
|
-
vresult = result;
|
2762
|
+
result = (unsigned long)((ID3_Field const *)arg1)->Get();
|
2763
|
+
vresult = SWIG_From_unsigned_SS_long(static_cast< unsigned long >(result));
|
2765
2764
|
return vresult;
|
2766
2765
|
fail:
|
2767
2766
|
return Qnil;
|
@@ -2769,7 +2768,7 @@ fail:
|
|
2769
2768
|
|
2770
2769
|
|
2771
2770
|
SWIGINTERN VALUE
|
2772
|
-
|
2771
|
+
_wrap_Field_get_ascii(int argc, VALUE *argv, VALUE self) {
|
2773
2772
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2774
2773
|
char *result = 0 ;
|
2775
2774
|
void *argp1 = 0 ;
|
@@ -2793,7 +2792,7 @@ fail:
|
|
2793
2792
|
|
2794
2793
|
|
2795
2794
|
SWIGINTERN VALUE
|
2796
|
-
|
2795
|
+
_wrap_Field_get_binary(int argc, VALUE *argv, VALUE self) {
|
2797
2796
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2798
2797
|
VALUE result;
|
2799
2798
|
void *argp1 = 0 ;
|
@@ -2805,10 +2804,10 @@ _wrap_Field_unicode(int argc, VALUE *argv, VALUE self) {
|
|
2805
2804
|
}
|
2806
2805
|
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
|
2807
2806
|
if (!SWIG_IsOK(res1)) {
|
2808
|
-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "
|
2807
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_binary" "', argument " "1"" of type '" "ID3_Field *""'");
|
2809
2808
|
}
|
2810
2809
|
arg1 = reinterpret_cast< ID3_Field * >(argp1);
|
2811
|
-
result = (VALUE)
|
2810
|
+
result = (VALUE)ID3_Field_get_binary(arg1);
|
2812
2811
|
vresult = result;
|
2813
2812
|
return vresult;
|
2814
2813
|
fail:
|
@@ -2817,55 +2816,85 @@ fail:
|
|
2817
2816
|
|
2818
2817
|
|
2819
2818
|
SWIGINTERN VALUE
|
2820
|
-
|
2819
|
+
_wrap_Field_get_unicode(int argc, VALUE *argv, VALUE self) {
|
2821
2820
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2822
|
-
|
2821
|
+
VALUE result;
|
2823
2822
|
void *argp1 = 0 ;
|
2824
2823
|
int res1 = 0 ;
|
2825
|
-
|
2824
|
+
VALUE vresult = Qnil;
|
2825
|
+
|
2826
|
+
if ((argc < 0) || (argc > 0)) {
|
2827
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
|
2828
|
+
}
|
2829
|
+
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
|
2830
|
+
if (!SWIG_IsOK(res1)) {
|
2831
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_unicode" "', argument " "1"" of type '" "ID3_Field *""'");
|
2832
|
+
}
|
2833
|
+
arg1 = reinterpret_cast< ID3_Field * >(argp1);
|
2834
|
+
result = (VALUE)ID3_Field_get_unicode(arg1);
|
2835
|
+
vresult = result;
|
2836
|
+
return vresult;
|
2837
|
+
fail:
|
2838
|
+
return Qnil;
|
2839
|
+
}
|
2840
|
+
|
2841
|
+
|
2842
|
+
SWIGINTERN VALUE
|
2843
|
+
_wrap_Field_set_encoding(int argc, VALUE *argv, VALUE self) {
|
2844
|
+
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2845
|
+
ID3_TextEnc arg2 ;
|
2846
|
+
bool result;
|
2847
|
+
void *argp1 = 0 ;
|
2848
|
+
int res1 = 0 ;
|
2849
|
+
int val2 ;
|
2826
2850
|
int ecode2 = 0 ;
|
2851
|
+
VALUE vresult = Qnil;
|
2827
2852
|
|
2828
2853
|
if ((argc < 1) || (argc > 1)) {
|
2829
2854
|
rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
|
2830
2855
|
}
|
2831
2856
|
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
|
2832
2857
|
if (!SWIG_IsOK(res1)) {
|
2833
|
-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "
|
2858
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SetEncoding" "', argument " "1"" of type '" "ID3_Field *""'");
|
2834
2859
|
}
|
2835
2860
|
arg1 = reinterpret_cast< ID3_Field * >(argp1);
|
2836
|
-
ecode2 =
|
2861
|
+
ecode2 = SWIG_AsVal_int(argv[0], &val2);
|
2837
2862
|
if (!SWIG_IsOK(ecode2)) {
|
2838
|
-
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "
|
2863
|
+
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SetEncoding" "', argument " "2"" of type '" "ID3_TextEnc""'");
|
2839
2864
|
}
|
2840
|
-
arg2 = static_cast<
|
2841
|
-
(arg1)->
|
2842
|
-
|
2865
|
+
arg2 = static_cast< ID3_TextEnc >(val2);
|
2866
|
+
result = (bool)(arg1)->SetEncoding(arg2);
|
2867
|
+
vresult = SWIG_From_bool(static_cast< bool >(result));
|
2868
|
+
return vresult;
|
2843
2869
|
fail:
|
2844
2870
|
return Qnil;
|
2845
2871
|
}
|
2846
2872
|
|
2847
2873
|
|
2848
2874
|
SWIGINTERN VALUE
|
2849
|
-
|
2875
|
+
_wrap_Field_set_integer(int argc, VALUE *argv, VALUE self) {
|
2850
2876
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2851
|
-
|
2852
|
-
size_t result;
|
2877
|
+
unsigned long arg2 ;
|
2853
2878
|
void *argp1 = 0 ;
|
2854
2879
|
int res1 = 0 ;
|
2855
|
-
|
2880
|
+
unsigned long val2 ;
|
2881
|
+
int ecode2 = 0 ;
|
2856
2882
|
|
2857
2883
|
if ((argc < 1) || (argc > 1)) {
|
2858
2884
|
rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
|
2859
2885
|
}
|
2860
2886
|
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
|
2861
2887
|
if (!SWIG_IsOK(res1)) {
|
2862
|
-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "
|
2888
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Set" "', argument " "1"" of type '" "ID3_Field *""'");
|
2863
2889
|
}
|
2864
2890
|
arg1 = reinterpret_cast< ID3_Field * >(argp1);
|
2865
|
-
|
2866
|
-
|
2867
|
-
|
2868
|
-
|
2891
|
+
ecode2 = SWIG_AsVal_unsigned_SS_long(argv[0], &val2);
|
2892
|
+
if (!SWIG_IsOK(ecode2)) {
|
2893
|
+
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Set" "', argument " "2"" of type '" "unsigned long""'");
|
2894
|
+
}
|
2895
|
+
arg2 = static_cast< unsigned long >(val2);
|
2896
|
+
(arg1)->Set(arg2);
|
2897
|
+
return Qnil;
|
2869
2898
|
fail:
|
2870
2899
|
return Qnil;
|
2871
2900
|
}
|
@@ -2907,14 +2936,12 @@ fail:
|
|
2907
2936
|
|
2908
2937
|
|
2909
2938
|
SWIGINTERN VALUE
|
2910
|
-
|
2939
|
+
_wrap_Field_set_binary(int argc, VALUE *argv, VALUE self) {
|
2911
2940
|
ID3_Field *arg1 = (ID3_Field *) 0 ;
|
2912
|
-
|
2913
|
-
|
2941
|
+
VALUE arg2 = (VALUE) 0 ;
|
2942
|
+
size_t result;
|
2914
2943
|
void *argp1 = 0 ;
|
2915
2944
|
int res1 = 0 ;
|
2916
|
-
int val2 ;
|
2917
|
-
int ecode2 = 0 ;
|
2918
2945
|
VALUE vresult = Qnil;
|
2919
2946
|
|
2920
2947
|
if ((argc < 1) || (argc > 1)) {
|
@@ -2922,16 +2949,12 @@ _wrap_Field_set_encoding(int argc, VALUE *argv, VALUE self) {
|
|
2922
2949
|
}
|
2923
2950
|
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
|
2924
2951
|
if (!SWIG_IsOK(res1)) {
|
2925
|
-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "
|
2952
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "set_binary" "', argument " "1"" of type '" "ID3_Field *""'");
|
2926
2953
|
}
|
2927
2954
|
arg1 = reinterpret_cast< ID3_Field * >(argp1);
|
2928
|
-
|
2929
|
-
|
2930
|
-
|
2931
|
-
}
|
2932
|
-
arg2 = static_cast< ID3_TextEnc >(val2);
|
2933
|
-
result = (bool)(arg1)->SetEncoding(arg2);
|
2934
|
-
vresult = SWIG_From_bool(static_cast< bool >(result));
|
2955
|
+
arg2 = argv[0];
|
2956
|
+
result = ID3_Field_set_binary(arg1,arg2);
|
2957
|
+
vresult = SWIG_From_size_t(static_cast< size_t >(result));
|
2935
2958
|
return vresult;
|
2936
2959
|
fail:
|
2937
2960
|
return Qnil;
|
@@ -3242,7 +3265,7 @@ SWIGEXPORT void Init_id3lib_api(void) {
|
|
3242
3265
|
rb_define_method(cTag.klass, "clear", VALUEFUNC(_wrap_Tag_clear), -1);
|
3243
3266
|
rb_define_method(cTag.klass, "remove_frame", VALUEFUNC(_wrap_Tag_remove_frame), -1);
|
3244
3267
|
rb_define_method(cTag.klass, "add_frame", VALUEFUNC(_wrap_Tag_add_frame), -1);
|
3245
|
-
rb_define_method(cTag.klass, "
|
3268
|
+
rb_define_method(cTag.klass, "get_filename", VALUEFUNC(_wrap_Tag_get_filename), -1);
|
3246
3269
|
rb_define_method(cTag.klass, "set_padding", VALUEFUNC(_wrap_Tag_set_padding), -1);
|
3247
3270
|
rb_define_method(cTag.klass, "size", VALUEFUNC(_wrap_Tag_size), -1);
|
3248
3271
|
rb_define_method(cTag.klass, "find", VALUEFUNC(_wrap_Tag_find), -1);
|
@@ -3256,8 +3279,8 @@ SWIGEXPORT void Init_id3lib_api(void) {
|
|
3256
3279
|
SWIG_TypeClientData(SWIGTYPE_p_ID3_Frame, (void *) &cFrame);
|
3257
3280
|
rb_define_alloc_func(cFrame.klass, _wrap_Frame_allocate);
|
3258
3281
|
rb_define_method(cFrame.klass, "initialize", VALUEFUNC(_wrap_new_Frame), -1);
|
3259
|
-
rb_define_method(cFrame.klass, "
|
3260
|
-
rb_define_method(cFrame.klass, "
|
3282
|
+
rb_define_method(cFrame.klass, "get_field", VALUEFUNC(_wrap_Frame_get_field), -1);
|
3283
|
+
rb_define_method(cFrame.klass, "get_id", VALUEFUNC(_wrap_Frame_get_id), -1);
|
3261
3284
|
cFrame.mark = 0;
|
3262
3285
|
cFrame.destroy = (void (*)(void *)) free_ID3_Frame;
|
3263
3286
|
cFrame.trackObjects = 0;
|
@@ -3265,15 +3288,16 @@ SWIGEXPORT void Init_id3lib_api(void) {
|
|
3265
3288
|
cField.klass = rb_define_class_under(mAPI, "Field", rb_cObject);
|
3266
3289
|
SWIG_TypeClientData(SWIGTYPE_p_ID3_Field, (void *) &cField);
|
3267
3290
|
rb_undef_alloc_func(cField.klass);
|
3268
|
-
rb_define_method(cField.klass, "
|
3269
|
-
rb_define_method(cField.klass, "
|
3270
|
-
rb_define_method(cField.klass, "
|
3271
|
-
rb_define_method(cField.klass, "
|
3272
|
-
rb_define_method(cField.klass, "
|
3291
|
+
rb_define_method(cField.klass, "get_type", VALUEFUNC(_wrap_Field_get_type), -1);
|
3292
|
+
rb_define_method(cField.klass, "get_encoding", VALUEFUNC(_wrap_Field_get_encoding), -1);
|
3293
|
+
rb_define_method(cField.klass, "get_integer", VALUEFUNC(_wrap_Field_get_integer), -1);
|
3294
|
+
rb_define_method(cField.klass, "get_ascii", VALUEFUNC(_wrap_Field_get_ascii), -1);
|
3295
|
+
rb_define_method(cField.klass, "get_binary", VALUEFUNC(_wrap_Field_get_binary), -1);
|
3296
|
+
rb_define_method(cField.klass, "get_unicode", VALUEFUNC(_wrap_Field_get_unicode), -1);
|
3297
|
+
rb_define_method(cField.klass, "set_encoding", VALUEFUNC(_wrap_Field_set_encoding), -1);
|
3273
3298
|
rb_define_method(cField.klass, "set_integer", VALUEFUNC(_wrap_Field_set_integer), -1);
|
3274
|
-
rb_define_method(cField.klass, "set_binary", VALUEFUNC(_wrap_Field_set_binary), -1);
|
3275
3299
|
rb_define_method(cField.klass, "set_ascii", VALUEFUNC(_wrap_Field_set_ascii), -1);
|
3276
|
-
rb_define_method(cField.klass, "
|
3300
|
+
rb_define_method(cField.klass, "set_binary", VALUEFUNC(_wrap_Field_set_binary), -1);
|
3277
3301
|
rb_define_method(cField.klass, "set_unicode", VALUEFUNC(_wrap_Field_set_unicode), -1);
|
3278
3302
|
cField.mark = 0;
|
3279
3303
|
cField.trackObjects = 0;
|
data/lib/id3lib.rb
CHANGED
@@ -327,25 +327,26 @@ module ID3Lib
|
|
327
327
|
|
328
328
|
def self.read(libframe)
|
329
329
|
frame = {}
|
330
|
-
info = Info.frame_num(libframe.
|
330
|
+
info = Info.frame_num(libframe.get_id)
|
331
331
|
frame[:id] = info[ID]
|
332
|
-
|
333
|
-
textenc = field(libframe, :textenc).integer
|
334
|
-
frame[:textenc] = textenc
|
335
|
-
end
|
332
|
+
|
336
333
|
info[FIELDS].each do |field_id|
|
337
|
-
next if field_id == :textenc
|
338
334
|
libfield = field(libframe, field_id)
|
339
|
-
frame[field_id] =
|
340
|
-
libfield.
|
341
|
-
|
342
|
-
|
343
|
-
when :
|
344
|
-
|
345
|
-
when :text
|
335
|
+
frame[field_id] =
|
336
|
+
case Info::FieldType[libfield.get_type]
|
337
|
+
when :integer
|
338
|
+
libfield.get_integer
|
339
|
+
when :binary
|
340
|
+
libfield.get_binary
|
341
|
+
when :text
|
342
|
+
if libfield.get_encoding > 0
|
343
|
+
libfield.get_unicode
|
344
|
+
else
|
345
|
+
libfield.get_ascii
|
346
|
+
end
|
346
347
|
end
|
347
|
-
end
|
348
348
|
end
|
349
|
+
|
349
350
|
frame
|
350
351
|
end
|
351
352
|
|
@@ -353,29 +354,35 @@ module ID3Lib
|
|
353
354
|
if textenc = frame[:textenc]
|
354
355
|
field(libframe, :textenc).set_integer(textenc)
|
355
356
|
end
|
357
|
+
|
356
358
|
frame.each do |field_id, value|
|
357
359
|
next if field_id == :textenc
|
358
360
|
unless Info.frame(frame[:id])[FIELDS].include?(field_id)
|
359
361
|
# Ignore invalid fields
|
360
362
|
next
|
361
363
|
end
|
364
|
+
|
362
365
|
libfield = field(libframe, field_id)
|
363
|
-
|
364
|
-
|
365
|
-
libfield.
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
366
|
+
case Info::FieldType[libfield.get_type]
|
367
|
+
when :integer
|
368
|
+
libfield.set_integer(value)
|
369
|
+
when :binary
|
370
|
+
libfield.set_binary(value)
|
371
|
+
when :text
|
372
|
+
if textenc and textenc > 0 and
|
373
|
+
[:text, :description, :filename].include?(field_id)
|
374
|
+
# Special treatment for Unicode
|
375
|
+
libfield.set_encoding(textenc)
|
376
|
+
libfield.set_unicode(value)
|
377
|
+
else
|
378
|
+
libfield.set_ascii(value)
|
372
379
|
end
|
373
380
|
end
|
374
381
|
end
|
375
382
|
end
|
376
383
|
|
377
384
|
def self.field(libframe, id)
|
378
|
-
libframe.
|
385
|
+
libframe.get_field(Info.field(id)[NUM])
|
379
386
|
end
|
380
387
|
|
381
388
|
end
|
data/test/test_writing.rb
CHANGED
@@ -172,12 +172,19 @@ class TestWriting < Test::Unit::TestCase
|
|
172
172
|
|
173
173
|
def test_unicode
|
174
174
|
nihao = "\x4f\x60\x59\x7d"
|
175
|
-
|
176
|
-
|
175
|
+
frame = {
|
176
|
+
:id => :COMM,
|
177
|
+
:text => nihao,
|
178
|
+
:description => nihao,
|
179
|
+
:language => "zho",
|
180
|
+
:textenc => 1
|
181
|
+
}
|
182
|
+
@tag.comment = nil
|
183
|
+
@tag << frame
|
177
184
|
@tag.update!(ID3Lib::V2)
|
178
|
-
assert_equal
|
185
|
+
assert_equal frame, @tag.frame(:COMM)
|
179
186
|
reload!(ID3Lib::V2)
|
180
|
-
assert_equal
|
187
|
+
assert_equal frame, @tag.frame(:COMM)
|
181
188
|
end
|
182
189
|
|
183
190
|
def test_unicode_invalid_data
|
data/usage.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'id3lib'
|
4
|
+
|
5
|
+
# Load a tag from a file
|
6
|
+
tag = ID3Lib::Tag.new('talk.mp3')
|
7
|
+
|
8
|
+
# Get and set text frames with convenience methods
|
9
|
+
tag.title #=> "Talk"
|
10
|
+
tag.album = 'X&Y'
|
11
|
+
tag.track = '5/13'
|
12
|
+
|
13
|
+
# Tag is a subclass of Array and each frame is a Hash
|
14
|
+
tag[0]
|
15
|
+
#=> { :id => :TPE1, :textenc => 0, :text => "Coldplay" }
|
16
|
+
|
17
|
+
# Get the number of frames
|
18
|
+
tag.length #=> 7
|
19
|
+
|
20
|
+
# Remove all comment frames
|
21
|
+
tag.delete_if{ |frame| frame[:id] == :COMM }
|
22
|
+
|
23
|
+
# Get info about APIC frame to see which fields are allowed
|
24
|
+
ID3Lib::Info.frame(:APIC)
|
25
|
+
#=> [ 2, :APIC, "Attached picture",
|
26
|
+
#=> [:textenc, :mimetype, :picturetype, :description, :data] ]
|
27
|
+
|
28
|
+
# Add an attached picture frame
|
29
|
+
cover = {
|
30
|
+
:id => :APIC,
|
31
|
+
:mimetype => 'image/jpeg',
|
32
|
+
:picturetype => 3,
|
33
|
+
:description => 'A pretty picture',
|
34
|
+
:textenc => 0,
|
35
|
+
:data => File.read('cover.jpg')
|
36
|
+
}
|
37
|
+
tag << cover
|
38
|
+
|
39
|
+
# Last but not least, apply changes
|
40
|
+
tag.update!
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.99
|
3
3
|
specification_version: 1
|
4
4
|
name: id3lib-ruby
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-06-
|
6
|
+
version: 0.4.0
|
7
|
+
date: 2006-06-27 00:00:00 +02:00
|
8
8
|
summary: id3lib-ruby provides a Ruby interface to the id3lib C++ library for easily editing ID3 tags (v1 and v2) like with pyid3lib.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
30
|
- Robin Stocker
|
30
31
|
files:
|
@@ -37,9 +38,13 @@ files:
|
|
37
38
|
- test/data/unicode.mp3
|
38
39
|
- test/data/cover.jpg
|
39
40
|
- Rakefile
|
41
|
+
- usage.rb
|
40
42
|
- setup.rb
|
41
43
|
- ext/extconf.rb
|
44
|
+
- ext/generate_info.rb
|
42
45
|
- ext/id3lib_api_wrap.cxx
|
46
|
+
- ext/id3lib_api.i
|
47
|
+
- ext/Rakefile
|
43
48
|
- README
|
44
49
|
- CHANGES
|
45
50
|
- TODO
|
@@ -47,6 +52,7 @@ test_files:
|
|
47
52
|
- test/test_writing.rb
|
48
53
|
- test/test_reading.rb
|
49
54
|
rdoc_options:
|
55
|
+
- --inline-source
|
50
56
|
- --line-numbers
|
51
57
|
- --main
|
52
58
|
- README
|