taglib-ruby 0.6.0 → 1.1.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.
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
@@ -11,12 +11,7 @@ class TestMPEGFile < Test::Unit::TestCase
11
11
  tag = @file.tag
12
12
  assert_not_nil tag
13
13
  assert_equal TagLib::Tag, tag.class
14
- end
15
-
16
- should "have an ID3v2 tag" do
17
- tag = @file.id3v2_tag(false)
18
- assert_not_nil tag
19
- assert_equal TagLib::ID3v2::Tag, tag.class
14
+ assert tag.empty?
20
15
  end
21
16
 
22
17
  context "audio properties" do
@@ -29,7 +24,8 @@ class TestMPEGFile < Test::Unit::TestCase
29
24
  end
30
25
 
31
26
  should "contain information" do
32
- assert_equal 2, @properties.length
27
+ assert_equal 2, @properties.length_in_seconds
28
+ assert_equal 2299, @properties.length_in_milliseconds
33
29
  assert_equal 157, @properties.bitrate
34
30
  assert_equal 44100, @properties.sample_rate
35
31
  assert_equal 2, @properties.channels
@@ -54,10 +50,127 @@ class TestMPEGFile < Test::Unit::TestCase
54
50
  assert @xing_header.valid?
55
51
  assert_equal 88, @xing_header.total_frames
56
52
  assert_equal 45140, @xing_header.total_size
53
+ assert_equal TagLib::MPEG::XingHeader::Xing, @xing_header.type
57
54
  end
58
55
  end
59
56
  end
60
57
 
58
+ should "have no tag" do
59
+ refute @file.id3v1_tag?
60
+ refute @file.id3v2_tag?
61
+ refute @file.ape_tag?
62
+ end
63
+
64
+ teardown do
65
+ @file.close
66
+ @file = nil
67
+ end
68
+ end
69
+
70
+ context "The id3v1.mp3 file" do
71
+ setup do
72
+ read_properties = true
73
+ @file = TagLib::MPEG::File.new("test/data/id3v1.mp3", read_properties)
74
+ end
75
+
76
+ should "have a basic tag" do
77
+ tag = @file.tag
78
+ assert_not_nil tag
79
+ assert_equal TagLib::Tag, tag.class
80
+ refute tag.empty?
81
+ end
82
+
83
+ context "audio properties" do
84
+ setup do
85
+ @properties = @file.audio_properties
86
+ end
87
+
88
+ should "be MPEG audio properties" do
89
+ assert_equal TagLib::MPEG::Properties, @properties.class
90
+ end
91
+
92
+ should "contain information" do
93
+ assert_equal 0, @properties.length_in_seconds
94
+ assert_equal 261, @properties.length_in_milliseconds
95
+ assert_equal 141, @properties.bitrate
96
+ assert_equal 44100, @properties.sample_rate
97
+ assert_equal 2, @properties.channels
98
+ assert_equal TagLib::MPEG::Header::Version1, @properties.version
99
+ assert_equal 3, @properties.layer
100
+ assert_equal false, @properties.protection_enabled
101
+ assert_equal TagLib::MPEG::Header::JointStereo, @properties.channel_mode
102
+ assert_equal false, @properties.copyrighted?
103
+ assert_equal true, @properties.original?
104
+ end
105
+
106
+ context "Xing header" do
107
+ setup do
108
+ @xing_header = @properties.xing_header
109
+ end
110
+
111
+ should "exist" do
112
+ assert_not_nil @xing_header
113
+ end
114
+
115
+ should "contain information" do
116
+ assert @xing_header.valid?
117
+ assert_equal 10, @xing_header.total_frames
118
+ assert_equal 4596, @xing_header.total_size
119
+ assert_equal TagLib::MPEG::XingHeader::Xing, @xing_header.type
120
+ end
121
+ end
122
+ end
123
+
124
+ context "tag" do
125
+ setup do
126
+ @tag = @file.tag
127
+ end
128
+
129
+ should "exist" do
130
+ refute_nil @tag
131
+ assert_equal TagLib::Tag, @tag.class
132
+ end
133
+
134
+ should "have basic properties" do
135
+ refute @tag.empty?
136
+
137
+ assert_equal 'Title', @tag.title
138
+ assert_equal 'Artist', @tag.artist
139
+ assert_equal 'Album', @tag.album
140
+ assert_equal 'Comment', @tag.comment
141
+ assert_equal 'Pop', @tag.genre
142
+ assert_equal 2011, @tag.year
143
+ assert_equal 7, @tag.track
144
+ end
145
+ end
146
+
147
+ context "ID3V1 tag" do
148
+ setup do
149
+ @tag = @file.id3v1_tag(false)
150
+ end
151
+
152
+ should "exist" do
153
+ assert @file.id3v1_tag?
154
+ refute @file.id3v2_tag?
155
+ refute @file.ape_tag?
156
+
157
+ assert_not_nil @tag
158
+ assert_equal TagLib::ID3v1::Tag, @tag.class
159
+ end
160
+
161
+ should "have basic properties" do
162
+ refute @tag.empty?
163
+
164
+ assert_equal 'Title', @tag.title
165
+ assert_equal 'Artist', @tag.artist
166
+ assert_equal 'Album', @tag.album
167
+ assert_equal 'Comment', @tag.comment
168
+ assert_equal 'Pop', @tag.genre
169
+ assert_equal 2011, @tag.year
170
+ assert_equal 7, @tag.track
171
+ end
172
+ end
173
+
61
174
  teardown do
62
175
  @file.close
63
176
  @file = nil
@@ -22,8 +22,8 @@ class TestVorbisFile < Test::Unit::TestCase
22
22
  end
23
23
 
24
24
  should "contain basic information" do
25
- assert_equal 0, @properties.length # file is short
26
- assert_equal 64, @properties.bitrate
25
+ assert_equal 0, @properties.length_in_seconds # file is short
26
+ assert_equal 371, @properties.bitrate
27
27
  assert_equal 44100, @properties.sample_rate
28
28
  assert_equal 2, @properties.channels
29
29
  end
@@ -11,6 +11,7 @@ class TestVorbisTag < Test::Unit::TestCase
11
11
  assert_equal "Title", @tag.title
12
12
  assert_equal "Artist", @tag.artist
13
13
  assert_equal "Album", @tag.album
14
+ # Use DESCRIPTION if it exists, otherwise COMMENT.
14
15
  assert_equal "Test file", @tag.comment
15
16
  assert_equal "Pop", @tag.genre
16
17
  assert_equal 2011, @tag.year
@@ -24,7 +25,7 @@ class TestVorbisTag < Test::Unit::TestCase
24
25
  end
25
26
 
26
27
  should "have field_count" do
27
- assert_equal 16, @tag.field_count
28
+ assert_equal 18, @tag.field_count
28
29
  end
29
30
 
30
31
  should "have vendor_id" do
@@ -61,14 +62,58 @@ class TestVorbisTag < Test::Unit::TestCase
61
62
  assert_equal ["Title", "Additional Title"], @tag.field_list_map['TITLE']
62
63
  end
63
64
 
64
- should "support remove_field with value" do
65
- @tag.remove_field('MULTIPLE', "A")
66
- assert_equal ["B"], @tag.field_list_map['MULTIPLE']
65
+ should "support remove_fields" do
66
+ assert @tag.contains?('MULTIPLE')
67
+ @tag.remove_fields('MULTIPLE')
68
+ refute @tag.contains?('MULTIPLE')
67
69
  end
68
70
 
69
- should "support remove_field without value" do
70
- @tag.remove_field('MULTIPLE')
71
- assert !@tag.contains?('MULTIPLE')
71
+ should "support remove_all_fields" do
72
+ refute_equal 0, @tag.field_count
73
+ @tag.remove_all_fields()
74
+ # remove_all_fields() do not remove pictures
75
+ assert_equal 1, @tag.field_count
76
+ end
77
+
78
+ should "have pictures" do
79
+ refute_empty @tag.picture_list
80
+ end
81
+
82
+ context "first picture" do
83
+ setup do
84
+ @picture = @tag.picture_list.first
85
+ end
86
+
87
+ should "be a TagLib::FLAC::Picture," do
88
+ assert_equal TagLib::FLAC::Picture, @picture.class
89
+ end
90
+
91
+ should "have meta-data" do
92
+ assert_equal TagLib::FLAC::Picture::FrontCover, @picture.type
93
+ assert_equal "image/jpeg", @picture.mime_type
94
+ assert_equal "Globe", @picture.description
95
+ assert_equal 90, @picture.width
96
+ assert_equal 90, @picture.height
97
+ assert_equal 24, @picture.color_depth
98
+ assert_equal 0, @picture.num_colors
99
+ end
100
+
101
+ should "have data" do
102
+ picture_data = File.open("test/data/globe_east_90.jpg", 'rb'){ |f| f.read }
103
+ assert_equal picture_data, @picture.data
104
+ end
105
+ end
106
+
107
+ should "support removing a picture" do
108
+ refute_empty @tag.picture_list
109
+ @tag.remove_picture(@tag.picture_list.first)
110
+ assert_empty @tag.picture_list
111
+ end
112
+
113
+ should "support removing all pictures" do
114
+ refute_empty @tag.picture_list
115
+ @tag.remove_all_pictures()
116
+ assert_empty @tag.picture_list
72
117
  end
73
118
 
74
119
  teardown do
@@ -76,4 +121,13 @@ class TestVorbisTag < Test::Unit::TestCase
76
121
  @file = nil
77
122
  end
78
123
  end
124
+
125
+ context "The XiphComment class" do
126
+ should "support check_key" do
127
+ refute TagLib::Ogg::XiphComment::check_key("")
128
+ refute TagLib::Ogg::XiphComment::check_key("something=")
129
+ refute TagLib::Ogg::XiphComment::check_key("something~")
130
+ assert TagLib::Ogg::XiphComment::check_key("something")
131
+ end
132
+ end
79
133
  end
@@ -0,0 +1,42 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class WAVExamples < Test::Unit::TestCase
4
+
5
+ DATA_FILE_PREFIX = "test/data/wav-"
6
+
7
+ context "TagLib::RIFF::WAV::File" do
8
+
9
+ should "Run TagLib::RIFF::WAV::File examples" do
10
+
11
+
12
+ # Reading the title
13
+
14
+ title = TagLib::RIFF::WAV::File.open("#{DATA_FILE_PREFIX}sample.wav") do |file|
15
+ file.tag.title
16
+ end
17
+
18
+ # Reading WAV-specific audio properties
19
+
20
+ TagLib::RIFF::WAV::File.open("#{DATA_FILE_PREFIX}sample.wav") do |file|
21
+ file.audio_properties.sample_rate #=> 8
22
+ end
23
+
24
+ # Saving ID3v2 cover-art to disk
25
+
26
+ TagLib::RIFF::WAV::File.open("#{DATA_FILE_PREFIX}sample.wav") do |file|
27
+ id3v2_tag = file.tag
28
+ cover = id3v2_tag.frame_list('APIC').first
29
+ ext = cover.mime_type.rpartition('/')[2]
30
+ File.open("#{DATA_FILE_PREFIX}cover-art.#{ext}", "wb") { |f| f.write cover.picture }
31
+ end
32
+
33
+
34
+ # checks
35
+ assert_equal "WAV Dummy Track Title", title
36
+ assert_equal true, File.exist?("#{DATA_FILE_PREFIX}cover-art.jpeg")
37
+ FileUtils.rm("#{DATA_FILE_PREFIX}cover-art.jpeg")
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,108 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class WAVFileTest < Test::Unit::TestCase
4
+
5
+ SAMPLE_FILE = "test/data/wav-sample.wav"
6
+ PICTURE_FILE = "test/data/globe_east_540.jpg"
7
+
8
+ context "TagLib::RIFF::WAV::File" do
9
+ setup do
10
+ @file = TagLib::RIFF::WAV::File.new(SAMPLE_FILE)
11
+ end
12
+
13
+ should "open" do
14
+ assert_not_nil @file
15
+ end
16
+
17
+ context "audio properties" do
18
+ setup do
19
+ @properties = @file.audio_properties
20
+ end
21
+
22
+ should "exist" do
23
+ assert_not_nil @properties
24
+ end
25
+
26
+ should "contain basic information" do
27
+ assert_equal 0, @properties.length_in_seconds
28
+ assert_equal 698, @properties.length_in_milliseconds
29
+ assert_equal 88, @properties.bitrate
30
+ assert_equal 11025, @properties.sample_rate
31
+ assert_equal 1, @properties.channels
32
+ end
33
+
34
+ should "contain WAV-specific information" do
35
+ assert_equal 8, @properties.bits_per_sample
36
+ assert_equal TagLib::RIFF::WAV::FORMAT_PCM, @properties.format
37
+ end
38
+ end
39
+
40
+ context "ID3V2 tag" do
41
+ setup do
42
+ @tag = @file.tag
43
+ end
44
+
45
+ should "exist" do
46
+ assert @file.id3v2_tag?
47
+ assert_not_nil @tag
48
+ assert_equal TagLib::ID3v2::Tag, @tag.class
49
+ end
50
+
51
+ should "not have an Info tag" do
52
+ refute @file.info_tag?
53
+ end
54
+
55
+ should "contain basic tag information" do
56
+ assert_equal "WAV Dummy Track Title", @tag.title
57
+ assert_equal "WAV Dummy Artist Name", @tag.artist
58
+ assert_equal "WAV Dummy Album Title", @tag.album
59
+ assert_equal "WAV Dummy Comment", @tag.comment
60
+ assert_equal "Jazz", @tag.genre
61
+ assert_equal 2014, @tag.year
62
+ assert_equal 5, @tag.track
63
+ assert_equal false, @tag.empty?
64
+ end
65
+
66
+ context "APIC frame" do
67
+ setup do
68
+ @picture_data = File.open(PICTURE_FILE, 'rb') { |f| f.read }
69
+ @apic = @tag.frame_list('APIC').first
70
+ end
71
+
72
+ should "exist" do
73
+ assert_not_nil @apic
74
+ assert_equal TagLib::ID3v2::AttachedPictureFrame, @apic.class
75
+ end
76
+
77
+ should "have a type" do
78
+ assert_equal TagLib::ID3v2::AttachedPictureFrame::FrontCover, @apic.type
79
+ end
80
+
81
+ should "have a mime type" do
82
+ assert_equal "image/jpeg", @apic.mime_type
83
+ end
84
+
85
+ should "have picture bytes" do
86
+ assert_equal 61649, @apic.picture.size
87
+ assert_equal @picture_data, @apic.picture
88
+ end
89
+ end
90
+ end
91
+
92
+ teardown do
93
+ @file.close
94
+ @file = nil
95
+ end
96
+ end
97
+
98
+ context "TagLib::RIFF::WAV::File.open" do
99
+ should "have open method" do
100
+ title = nil
101
+ TagLib::RIFF::WAV::File.open(SAMPLE_FILE, false) do |file|
102
+ title = file.tag.title
103
+ end
104
+ assert_equal "WAV Dummy Track Title", title
105
+ end
106
+ end
107
+
108
+ end
@@ -0,0 +1,113 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class WAVFileWriteTest < Test::Unit::TestCase
4
+
5
+ SAMPLE_FILE = "test/data/wav-sample.wav"
6
+ OUTPUT_FILE = "test/data/_output.wav"
7
+ PICTURE_FILE = "test/data/globe_east_90.jpg"
8
+
9
+ def reloaded
10
+ TagLib::RIFF::WAV::File.open(OUTPUT_FILE, false) do |file|
11
+ yield file
12
+ end
13
+ end
14
+
15
+ context "TagLib::RIFF::WAV::File" do
16
+ setup do
17
+ FileUtils.cp SAMPLE_FILE, OUTPUT_FILE
18
+ @file = TagLib::RIFF::WAV::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 2, @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 3, file.tag.frame_list('APIC').size
70
+ end
71
+
72
+ reloaded do |file|
73
+ written_apic = file.tag.frame_list("APIC")[2]
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
+
89
+ context "TagLib::RIFF::WAV::File.strip" do
90
+ setup do
91
+ FileUtils.cp SAMPLE_FILE, OUTPUT_FILE
92
+ @file = TagLib::RIFF::WAV::File.new(OUTPUT_FILE)
93
+ end
94
+
95
+ should "update the file immediately" do
96
+ assert @file.id3v2_tag?
97
+
98
+ @file.strip(TagLib::RIFF::WAV::File::ID3v2)
99
+
100
+ reloaded do |file|
101
+ refute @file.id3v2_tag?
102
+ end
103
+ end
104
+
105
+ teardown do
106
+ if @file
107
+ @file.close
108
+ @file = nil
109
+ end
110
+ FileUtils.rm OUTPUT_FILE
111
+ end
112
+ end
113
+ end