taglib-ruby 0.6.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -1
  3. data/{CHANGES.md → CHANGELOG.md} +46 -11
  4. data/README.md +61 -17
  5. data/Rakefile +12 -3
  6. data/docs/taglib/aiff.rb +95 -0
  7. data/docs/taglib/base.rb +30 -2
  8. data/docs/taglib/flac.rb +60 -4
  9. data/docs/taglib/id3v1.rb +29 -0
  10. data/docs/taglib/id3v2.rb +22 -3
  11. data/docs/taglib/mp4.rb +124 -13
  12. data/docs/taglib/mpeg.rb +30 -1
  13. data/docs/taglib/ogg.rb +47 -5
  14. data/docs/taglib/riff.rb +3 -0
  15. data/docs/taglib/vorbis.rb +1 -1
  16. data/docs/taglib/wav.rb +116 -0
  17. data/ext/extconf_common.rb +24 -3
  18. data/ext/taglib_aiff/extconf.rb +4 -0
  19. data/ext/taglib_aiff/taglib_aiff.i +84 -0
  20. data/ext/taglib_aiff/taglib_aiff_wrap.cxx +3111 -0
  21. data/ext/taglib_base/includes.i +34 -5
  22. data/ext/taglib_base/taglib_base.i +42 -2
  23. data/ext/taglib_base/taglib_base_wrap.cxx +226 -186
  24. data/ext/taglib_flac/taglib_flac.i +21 -18
  25. data/ext/taglib_flac/taglib_flac_wrap.cxx +519 -955
  26. data/ext/taglib_flac_picture/extconf.rb +4 -0
  27. data/ext/taglib_flac_picture/includes.i +15 -0
  28. data/ext/taglib_flac_picture/taglib_flac_picture.i +15 -0
  29. data/ext/taglib_flac_picture/taglib_flac_picture_wrap.cxx +3087 -0
  30. data/ext/taglib_id3v1/taglib_id3v1.i +19 -0
  31. data/ext/taglib_id3v1/taglib_id3v1_wrap.cxx +391 -193
  32. data/ext/taglib_id3v2/relativevolumeframe.i +4 -17
  33. data/ext/taglib_id3v2/taglib_id3v2.i +72 -2
  34. data/ext/taglib_id3v2/taglib_id3v2_wrap.cxx +3051 -1113
  35. data/ext/taglib_mp4/taglib_mp4.i +101 -20
  36. data/ext/taglib_mp4/taglib_mp4_wrap.cxx +1088 -282
  37. data/ext/taglib_mpeg/taglib_mpeg.i +11 -16
  38. data/ext/taglib_mpeg/taglib_mpeg_wrap.cxx +646 -317
  39. data/ext/taglib_ogg/taglib_ogg.i +11 -0
  40. data/ext/taglib_ogg/taglib_ogg_wrap.cxx +478 -192
  41. data/ext/taglib_vorbis/taglib_vorbis.i +8 -0
  42. data/ext/taglib_vorbis/taglib_vorbis_wrap.cxx +202 -156
  43. data/ext/taglib_wav/extconf.rb +4 -0
  44. data/ext/taglib_wav/taglib_wav.i +90 -0
  45. data/ext/taglib_wav/taglib_wav_wrap.cxx +3423 -0
  46. data/lib/taglib.rb +2 -0
  47. data/lib/taglib/aiff.rb +7 -0
  48. data/lib/taglib/mp4.rb +2 -1
  49. data/lib/taglib/version.rb +2 -2
  50. data/lib/taglib/wav.rb +11 -0
  51. data/taglib-ruby.gemspec +42 -8
  52. data/tasks/ext.rake +48 -20
  53. data/tasks/gemspec_check.rake +1 -1
  54. data/tasks/swig.rake +36 -2
  55. data/test/aiff_examples_test.rb +39 -0
  56. data/test/aiff_file_test.rb +103 -0
  57. data/test/aiff_file_write_test.rb +88 -0
  58. data/test/data/Makefile +8 -2
  59. data/test/data/aiff-sample.aiff +0 -0
  60. data/test/data/flac_nopic.flac +0 -0
  61. data/test/data/vorbis-create.cpp +20 -1
  62. data/test/data/vorbis.oga +0 -0
  63. data/test/data/wav-create.cpp +55 -0
  64. data/test/data/wav-dump.cpp +74 -0
  65. data/test/data/wav-sample.wav +0 -0
  66. data/test/file_test.rb +21 -0
  67. data/test/fileref_properties_test.rb +1 -1
  68. data/test/flac_file_test.rb +45 -30
  69. data/test/flac_picture_memory_test.rb +43 -0
  70. data/test/id3v1_genres_test.rb +23 -0
  71. data/test/id3v1_tag_test.rb +1 -0
  72. data/test/id3v2_frames_test.rb +64 -0
  73. data/test/id3v2_tag_test.rb +6 -6
  74. data/test/id3v2_unknown_frames_test.rb +30 -0
  75. data/test/id3v2_write_test.rb +10 -13
  76. data/test/mp4_file_test.rb +33 -4
  77. data/test/mp4_file_write_test.rb +5 -5
  78. data/test/mp4_items_test.rb +83 -29
  79. data/test/mpeg_file_test.rb +120 -7
  80. data/test/vorbis_file_test.rb +2 -2
  81. data/test/vorbis_tag_test.rb +61 -7
  82. data/test/wav_examples_test.rb +42 -0
  83. data/test/wav_file_test.rb +108 -0
  84. data/test/wav_file_write_test.rb +113 -0
  85. metadata +86 -56
@@ -0,0 +1,88 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class AIFFFileWriteTest < Test::Unit::TestCase
4
+
5
+ SAMPLE_FILE = "test/data/aiff-sample.aiff"
6
+ OUTPUT_FILE = "test/data/_output.aiff"
7
+ PICTURE_FILE = "test/data/globe_east_90.jpg"
8
+
9
+ def reloaded
10
+ TagLib::RIFF::AIFF::File.open(OUTPUT_FILE, false) do |file|
11
+ yield file
12
+ end
13
+ end
14
+
15
+ context "TagLib::RIFF::AIFF::File" do
16
+ setup do
17
+ FileUtils.cp SAMPLE_FILE, OUTPUT_FILE
18
+ @file = TagLib::RIFF::AIFF::File.new(OUTPUT_FILE, false)
19
+ end
20
+
21
+ should "be able to save the title" do
22
+ tag = @file.tag
23
+ assert_not_nil tag
24
+ tag.title = "New Title"
25
+ success = @file.save
26
+ assert success
27
+ @file.close
28
+ @file = nil
29
+
30
+ written_title = reloaded do |file|
31
+ file.tag.title
32
+ end
33
+ assert_equal "New Title", written_title
34
+ end
35
+
36
+ should "have one picture frame" do
37
+ assert_equal 1, @file.tag.frame_list('APIC').size
38
+ end
39
+
40
+ should "be able to remove all picture frames" do
41
+ @file.tag.remove_frames('APIC')
42
+ success = @file.save
43
+ assert success
44
+ @file.close
45
+ @file = nil
46
+
47
+ reloaded do |file|
48
+ assert_equal 0, file.tag.frame_list('APIC').size
49
+ end
50
+ end
51
+
52
+ should "be able to add a picture frame" do
53
+ picture_data = File.open(PICTURE_FILE, 'rb') { |f| f.read }
54
+
55
+ apic = TagLib::ID3v2::AttachedPictureFrame.new
56
+ apic.mime_type = "image/jpeg"
57
+ apic.description = "desc"
58
+ apic.text_encoding = TagLib::String::UTF8
59
+ apic.picture = picture_data
60
+ apic.type = TagLib::ID3v2::AttachedPictureFrame::BackCover
61
+
62
+ @file.tag.add_frame(apic)
63
+ success = @file.save
64
+ assert success
65
+ @file.close
66
+ @file = nil
67
+
68
+ reloaded do |file|
69
+ assert_equal 2, file.tag.frame_list('APIC').size
70
+ end
71
+
72
+ reloaded do |file|
73
+ written_apic = file.tag.frame_list("APIC")[1]
74
+ assert_equal "image/jpeg", written_apic.mime_type
75
+ assert_equal "desc", written_apic.description
76
+ assert_equal picture_data, written_apic.picture
77
+ end
78
+ end
79
+
80
+ teardown do
81
+ if @file
82
+ @file.close
83
+ @file = nil
84
+ end
85
+ FileUtils.rm OUTPUT_FILE
86
+ end
87
+ end
88
+ end
@@ -1,6 +1,6 @@
1
1
  .PHONY: all clean
2
2
 
3
- all:: add-relative-volume id3v1-create vorbis-create flac-create mp4-create
3
+ all:: add-relative-volume id3v1-create vorbis-create flac-create mp4-create wav-create wav-dump
4
4
 
5
5
  add-relative-volume: add-relative-volume.cpp
6
6
  g++ -o $@ $< -ltag -I/usr/include/taglib
@@ -17,5 +17,11 @@ flac-create: flac-create.cpp
17
17
  mp4-create: mp4-create.cpp
18
18
  g++ -o $@ $< -ltag -I/usr/include/taglib
19
19
 
20
+ wav-create: wav-create.cpp
21
+ g++ -o $@ $< -ltag -I/usr/include/taglib
22
+
23
+ wav-dump: wav-dump.cpp
24
+ g++ -o $@ $< -ltag -I/usr/include/taglib
25
+
20
26
  clean::
21
- -rm add-relative-volume id3v1-create vorbis-create flac-create mp4-create
27
+ -rm add-relative-volume id3v1-create vorbis-create flac-create mp4-create wav-create wav-dump
Binary file
@@ -4,11 +4,13 @@
4
4
  #include <taglib/taglib.h>
5
5
  #include <taglib/vorbisfile.h>
6
6
 
7
+ #include "get_picture_data.cpp"
8
+
7
9
  using namespace TagLib;
8
10
 
9
11
  int main(int argc, char **argv) {
10
12
  if (argc != 2) {
11
- std::cout << "usage: " << argv[0] << " file.mp3" << std::endl;
13
+ std::cout << "usage: " << argv[0] << " file.oga" << std::endl;
12
14
  exit(1);
13
15
  }
14
16
  char *filename = argv[1];
@@ -16,6 +18,9 @@ int main(int argc, char **argv) {
16
18
  Vorbis::File file(filename);
17
19
  Ogg::XiphComment *tag = file.tag();
18
20
 
21
+ tag->removeAllFields();
22
+ tag->removeAllPictures();
23
+
19
24
  tag->setTitle("Title");
20
25
  tag->setArtist("Artist");
21
26
  tag->setAlbum("Album");
@@ -36,6 +41,20 @@ int main(int argc, char **argv) {
36
41
  tag->addField("MULTIPLE", "A");
37
42
  tag->addField("MULTIPLE", "B", false);
38
43
 
44
+ ByteVector pictureData = getPictureData("globe_east_90.jpg");
45
+
46
+ FLAC::Picture picture;
47
+ picture.setType(FLAC::Picture::FrontCover);
48
+ picture.setMimeType("image/jpeg");
49
+ picture.setDescription("Globe");
50
+ picture.setWidth(90);
51
+ picture.setHeight(90);
52
+ picture.setColorDepth(24);
53
+ picture.setNumColors(0);
54
+ picture.setData(pictureData);
55
+
56
+ tag->addField("METADATA_BLOCK_PICTURE", picture.render().toBase64());
57
+
39
58
  file.save();
40
59
  }
41
60
 
Binary file
@@ -0,0 +1,55 @@
1
+ #include <taglib/taglib.h>
2
+ #include <taglib/wavfile.h>
3
+ #include <taglib/wavproperties.h>
4
+ #include <taglib/attachedpictureframe.h>
5
+
6
+ #include "get_picture_data.cpp"
7
+
8
+ using namespace TagLib;
9
+
10
+
11
+ int main(int argc, char **argv) {
12
+ if (argc != 2) {
13
+ std::cout << "usage: " << argv[0] << " file.wav" << std::endl;
14
+ exit(1);
15
+ }
16
+ char *filename = argv[1];
17
+
18
+ RIFF::WAV::File file(filename);
19
+ ID3v2::Tag *tag = file.tag();
20
+
21
+ tag->setArtist("WAV Dummy Artist Name");
22
+ tag->setAlbum("WAV Dummy Album Title");
23
+ tag->setTitle("WAV Dummy Track Title");
24
+ tag->setTrack(5);
25
+ tag->setYear(2014);
26
+ tag->setGenre("Jazz");
27
+ tag->setComment("WAV Dummy Comment");
28
+
29
+ tag->removeFrames("APIC");
30
+
31
+ ByteVector picture_data;
32
+ ID3v2::AttachedPictureFrame *apic;
33
+
34
+ picture_data = getPictureData("globe_east_540.jpg");
35
+ apic = new ID3v2::AttachedPictureFrame();
36
+ apic->setPicture(picture_data);
37
+ apic->setMimeType("image/jpeg");
38
+ apic->setType(ID3v2::AttachedPictureFrame::FrontCover);
39
+ apic->setDescription("WAV Dummy Front Cover-Art");
40
+ apic->setTextEncoding(String::UTF8);
41
+ tag->addFrame(apic);
42
+
43
+ picture_data = getPictureData("globe_east_90.jpg");
44
+ apic = new ID3v2::AttachedPictureFrame();
45
+ apic->setPicture(picture_data);
46
+ apic->setMimeType("image/jpeg");
47
+ apic->setType(ID3v2::AttachedPictureFrame::Other);
48
+ apic->setDescription("WAV Dummy Thumbnail");
49
+ apic->setTextEncoding(String::UTF8);
50
+ tag->addFrame(apic);
51
+
52
+ file.save();
53
+ }
54
+
55
+ // vim: set filetype=cpp sw=2 ts=2 expandtab:
@@ -0,0 +1,74 @@
1
+ #include <taglib/taglib.h>
2
+ #include <taglib/wavfile.h>
3
+ #include <taglib/wavproperties.h>
4
+ #include <taglib/attachedpictureframe.h>
5
+
6
+ using namespace TagLib;
7
+
8
+
9
+ void dump_id3v2(ID3v2::Tag *tag)
10
+ {
11
+ if (!tag || tag->isEmpty())
12
+ {
13
+ std::cout << " NO TAGS" << std::endl;
14
+ return;
15
+ }
16
+
17
+ std::cout << " ID3v2." << tag->header()->majorVersion() << "." << tag->header()->revisionNumber() << std::endl;
18
+ std::cout << " title: '" << tag->title() << "'" << std::endl;
19
+ std::cout << " artist: '" << tag->artist() << "'" << std::endl;
20
+ std::cout << " album: '" << tag->album() << "'" << std::endl;
21
+ std::cout << " track: " << tag->track() << std::endl;
22
+ std::cout << " year: " << tag->year() << std::endl;
23
+ std::cout << " genre: '" << tag->genre() << "'" << std::endl;
24
+ std::cout << " comment: '" << tag->comment() << "'" << std::endl;
25
+
26
+ std::cout << " Frames" << std::endl;
27
+ const ID3v2::FrameList frameList = tag->frameList();
28
+ for(ID3v2::FrameList::ConstIterator it = frameList.begin(); it != frameList.end(); ++it)
29
+ std::cout << " " << (*it)->frameID() << " - " << (*it)->toString() << std::endl;
30
+
31
+ const ID3v2::FrameList apicList = tag->frameList("APIC");
32
+ for(ID3v2::FrameList::ConstIterator it = apicList.begin(); it != apicList.end(); ++it)
33
+ {
34
+ const ID3v2::AttachedPictureFrame *apic = static_cast<ID3v2::AttachedPictureFrame *>(*it);
35
+ std::cout << " Picture" << std::endl;
36
+ std::cout << " type: " << apic->type() << std::endl;
37
+ std::cout << " mime_type: '" << apic->mimeType() << "'" << std::endl;
38
+ std::cout << " description: '" << apic->description() << "'" << std::endl;
39
+ std::cout << " size: " << apic->picture().size() << " bytes" << std::endl;
40
+ }
41
+ }
42
+
43
+ void dump_audio_properties(AudioProperties *properties)
44
+ {
45
+ std::cout << " Audio Properties" << std::endl;
46
+ std::cout << " length: " << properties->length() << " (seconds)" << std::endl;
47
+ std::cout << " bitrate: " << properties->bitrate() << " (kbits/sec)" << std::endl;
48
+ std::cout << " sample_rate: " << properties->sampleRate() << " (Hz)" << std::endl;
49
+ std::cout << " channels: " << properties->channels() << std::endl;
50
+ }
51
+
52
+ void dump_wav_properties(RIFF::WAV::Properties *properties)
53
+ {
54
+ std::cout << " WAV-specific Properties" << std::endl;
55
+ std::cout << " sample_width: " << properties->sampleWidth() << " (bits)" << std::endl;
56
+ }
57
+
58
+ int main(int argc, char **argv) {
59
+ if (argc != 2) {
60
+ std::cout << "usage: " << argv[0] << " file.wav" << std::endl;
61
+ exit(1);
62
+ }
63
+ char *filename = argv[1];
64
+
65
+ std::cout << "WAV file '" << filename << "'..." << std::endl;
66
+
67
+ RIFF::WAV::File file(filename);
68
+
69
+ dump_id3v2(file.tag());
70
+ dump_audio_properties(file.audioProperties());
71
+ dump_wav_properties(file.audioProperties());
72
+ }
73
+
74
+ // vim: set filetype=cpp sw=2 ts=2 expandtab:
Binary file
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class TestFile < Test::Unit::TestCase
4
+ context "The sample.mp3 file" do
5
+ setup do
6
+ @mpeg_file = TagLib::MPEG::File.new("test/data/sample.mp3", false)
7
+ end
8
+
9
+ context "filename" do
10
+ should "be the right name" do
11
+ assert_equal 'test/data/sample.mp3', @mpeg_file.name
12
+ end
13
+
14
+ if HAVE_ENCODING
15
+ should "have the right encoding" do
16
+ assert_equal Encoding.find('filesystem'), @mpeg_file.name.encoding
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -12,7 +12,7 @@ class TestFileRefProperties < Test::Unit::TestCase
12
12
  end
13
13
 
14
14
  should "contain basic information" do
15
- assert_equal 2, @properties.length
15
+ assert_equal 2, @properties.length_in_seconds
16
16
  assert_equal 157, @properties.bitrate
17
17
  assert_equal 44100, @properties.sample_rate
18
18
  assert_equal 2, @properties.channels
@@ -13,19 +13,27 @@ class FlacFileTest < Test::Unit::TestCase
13
13
  end
14
14
 
15
15
  should "have XiphComment" do
16
+ assert @file.xiph_comment?
16
17
  tag = @file.xiph_comment
17
18
  assert_not_nil tag
18
19
  assert_equal TagLib::Ogg::XiphComment, tag.class
19
20
  end
20
21
 
21
22
  should "have method for ID3v1 tag" do
23
+ refute @file.id3v1_tag?
22
24
  assert_nil @file.id3v1_tag
23
25
  end
24
26
 
25
27
  should "have method for ID3v2 tag" do
28
+ refute @file.id3v2_tag?
26
29
  assert_nil @file.id3v2_tag
27
30
  end
28
31
 
32
+ should "support stripping tags by type" do
33
+ @file.strip(TagLib::FLAC::File::XiphComment)
34
+ assert @file.xiph_comment?
35
+ end
36
+
29
37
  context "audio properties" do
30
38
  setup do
31
39
  @properties = @file.audio_properties
@@ -36,54 +44,61 @@ class FlacFileTest < Test::Unit::TestCase
36
44
  end
37
45
 
38
46
  should "contain basic information" do
39
- assert_equal 1, @properties.length
40
- assert_equal 212, @properties.bitrate
47
+ assert_equal 1, @properties.length_in_seconds
48
+ assert_equal 1017, @properties.length_in_milliseconds
49
+ assert_equal 209, @properties.bitrate
41
50
  assert_equal 44100, @properties.sample_rate
42
51
  assert_equal 1, @properties.channels
43
52
  end
44
53
 
45
54
  should "contain flac-specific information" do
46
- assert_equal 16, @properties.sample_width
55
+ assert_equal 16, @properties.bits_per_sample
47
56
  s = ["78d19b86df2cd488b35957e6bd884968"].pack('H*')
48
57
  assert_equal s, @properties.signature
49
58
  end
50
59
  end
51
60
 
52
- context "picture_list" do
61
+ should "have pictures" do
62
+ refute_empty @file.picture_list
63
+ end
64
+
65
+ context "first picture" do
53
66
  setup do
54
- @pictures = @file.picture_list
67
+ @picture = @file.picture_list.first
68
+ end
69
+
70
+ should "be a TagLib::FLAC::Picture," do
71
+ assert_equal TagLib::FLAC::Picture, @picture.class
55
72
  end
56
73
 
57
- should "have a picture" do
58
- assert_equal 1, @pictures.size
74
+ should "have meta-data" do
75
+ assert_equal TagLib::FLAC::Picture::FrontCover, @picture.type
76
+ assert_equal "image/jpeg", @picture.mime_type
77
+ assert_equal "Globe", @picture.description
78
+ assert_equal 90, @picture.width
79
+ assert_equal 90, @picture.height
80
+ assert_equal 8, @picture.color_depth
81
+ assert_equal 0, @picture.num_colors
59
82
  end
60
83
 
61
- context "first element" do
62
- setup do
63
- @picture = @pictures.first
64
- end
65
-
66
- should "be a TagLib::FLAC::Picture," do
67
- assert_equal TagLib::FLAC::Picture, @picture.class
68
- end
69
-
70
- should "have meta-data" do
71
- assert_equal TagLib::FLAC::Picture::FrontCover, @picture.type
72
- assert_equal "image/jpeg", @picture.mime_type
73
- assert_equal "Globe", @picture.description
74
- assert_equal 90, @picture.width
75
- assert_equal 90, @picture.height
76
- assert_equal 8, @picture.color_depth
77
- assert_equal 0, @picture.num_colors
78
- end
79
-
80
- should "have data" do
81
- picture_data = File.open("test/data/globe_east_90.jpg", 'rb'){ |f| f.read }
82
- assert_equal picture_data, @picture.data
83
- end
84
+ should "have data" do
85
+ picture_data = File.open("test/data/globe_east_90.jpg", 'rb'){ |f| f.read }
86
+ assert_equal picture_data, @picture.data
84
87
  end
85
88
  end
86
89
 
90
+ should "support removing a picture" do
91
+ refute_empty @file.picture_list
92
+ @file.remove_picture(@file.picture_list.first)
93
+ assert_empty @file.picture_list
94
+ end
95
+
96
+ should "support removing all pictures" do
97
+ refute_empty @file.picture_list
98
+ @file.remove_pictures()
99
+ assert_empty @file.picture_list
100
+ end
101
+
87
102
  teardown do
88
103
  @file.close
89
104
  @file = nil
@@ -0,0 +1,43 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class TestFlacPictureMemory < Test::Unit::TestCase
4
+
5
+ N = 10000
6
+
7
+ context "TagLib::FLAC::Picture" do
8
+
9
+ setup do
10
+
11
+ end
12
+
13
+ should "release memory when closing flac file with picture data" do
14
+ c = 0
15
+ N.times do
16
+ TagLib::FLAC::File.open("test/data/flac.flac", false) do |f|
17
+ f.picture_list.each do |p|
18
+ x = p.data
19
+ c = c + 1
20
+ end
21
+ end
22
+ end
23
+ assert_equal N,c
24
+ end
25
+
26
+ should "process a flac file without picture data" do
27
+ c = 0
28
+ N.times do
29
+ TagLib::FLAC::File.open("test/data/flac_nopic.flac", false) do |f|
30
+ f.picture_list.each do |p|
31
+ x = p.data
32
+ c = c + 1
33
+ end
34
+ end
35
+ end
36
+ assert_equal 0,c
37
+ end
38
+
39
+ teardown do
40
+
41
+ end
42
+ end
43
+ end