ruby-ogginfo 0.4.2 → 0.5
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/History.txt +4 -0
- data/Manifest.txt +1 -1
- data/{README.txt → README.rdoc} +1 -0
- data/Rakefile +6 -2
- data/lib/ogginfo.rb +31 -6
- data/test/test_ruby-spxinfo.rb +105 -0
- metadata +43 -16
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/{README.txt → README.rdoc}
RENAMED
data/Rakefile
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'hoe'
|
5
|
+
|
6
|
+
Hoe.plugin :yard
|
7
|
+
|
5
8
|
require 'lib/ogginfo.rb'
|
6
9
|
|
7
10
|
Hoe.new('ruby-ogginfo', OggInfo::VERSION) do |p|
|
@@ -9,10 +12,11 @@ Hoe.new('ruby-ogginfo', OggInfo::VERSION) do |p|
|
|
9
12
|
p.author = 'Guillaume Pierronnet'
|
10
13
|
p.email = 'moumar@rubyforge.org'
|
11
14
|
p.summary = 'ruby-ogginfo is a pure-ruby library that gives low level informations on ogg files'
|
12
|
-
p.description = p.paragraphs_of('README.
|
13
|
-
p.url = p.paragraphs_of('README.
|
15
|
+
p.description = p.paragraphs_of('README.rdoc', 3).first
|
16
|
+
p.url = p.paragraphs_of('README.rdoc', 1).first
|
14
17
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
15
18
|
p.remote_rdoc_dir = ''
|
19
|
+
p.rdoc_locations << "rubyforge.org:/var/www/gforge-projects/ruby-ogginfo/"
|
16
20
|
end
|
17
21
|
|
18
22
|
# vim: syntax=Ruby
|
data/lib/ogginfo.rb
CHANGED
@@ -23,7 +23,7 @@ end
|
|
23
23
|
class OggInfoError < StandardError ; end
|
24
24
|
|
25
25
|
class OggInfo
|
26
|
-
VERSION = "0.
|
26
|
+
VERSION = "0.5"
|
27
27
|
CHECKSUM_TABLE = [
|
28
28
|
0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
|
29
29
|
0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
|
@@ -103,7 +103,7 @@ class OggInfo
|
|
103
103
|
@file = File.new(@filename, "rb")
|
104
104
|
|
105
105
|
frames = (1..2).collect { |i| OggInfo.read_frame(@file) }
|
106
|
-
|
106
|
+
extract_bitstream_infos(frames[0])
|
107
107
|
extract_tag(frames[1])
|
108
108
|
convert_tag_charset("utf-8", @charset)
|
109
109
|
@original_tag = @tag.dup
|
@@ -130,7 +130,7 @@ class OggInfo
|
|
130
130
|
|
131
131
|
# commits any tags to file
|
132
132
|
def close
|
133
|
-
if @tag != @original_tag
|
133
|
+
if @bitstream_format == "vorbis" && @tag != @original_tag
|
134
134
|
cmd = %w{vorbiscomment -w}
|
135
135
|
convert_tag_charset(@charset, "utf-8")
|
136
136
|
|
@@ -202,20 +202,45 @@ class OggInfo
|
|
202
202
|
end
|
203
203
|
|
204
204
|
private
|
205
|
+
def extract_bitstream_infos(frame)
|
206
|
+
@file.seek(frame[:file_position] + frame[:header_size] + 1)
|
207
|
+
@bitstream_format = @file.read(6).rstrip()
|
208
|
+
case @bitstream_format
|
209
|
+
when "vorbis" : extract_vorbis_infos(frame)
|
210
|
+
when "peex" :
|
211
|
+
#Speex does not align itself to a 4 byte boundary.
|
212
|
+
@bitstream_format="Speex"
|
213
|
+
extract_speex_infos(frame)
|
214
|
+
else raise(OggInfoError,"Unknown bitstream format #{@bitstream_format}")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def extract_speex_infos(frame)
|
219
|
+
@file.seek(frame[:file_position] + frame[:header_size] )
|
220
|
+
speex_string,speex_version,speex_version_id,header_size,@samplerate,mode,mode_bitstream_version,
|
221
|
+
@channels,bitrate,framesize,vbr = @file.read(28+ 9 * 4).unpack("A8A20VVVVVVVVV")
|
222
|
+
#not sure how to make sense of the bitrate info,picard doesn't show it either...
|
223
|
+
end
|
224
|
+
|
205
225
|
def extract_vorbis_infos(frame)
|
206
|
-
@file.seek(frame[:file_position] + frame[:header_size] + 1 )
|
226
|
+
@file.seek(frame[:file_position] + frame[:header_size] + 1 )
|
227
|
+
|
207
228
|
vorbis_string, vorbis_version, @channels, @samplerate, upper_bitrate, @nominal_bitrate, lower_bitrate = @file.read(27).unpack("a6VCV4")
|
208
229
|
if @nominal_bitrate == 0
|
209
230
|
if upper_bitrate == 2**32 - 1 or lower_bitrate == 2**32 - 1
|
210
231
|
@nominal_bitrate = 0
|
211
232
|
else
|
212
233
|
@nominal_bitrate = (upper_bitrate + lower_bitrate)/2
|
213
|
-
end
|
234
|
+
end
|
214
235
|
end
|
215
236
|
end
|
216
237
|
|
217
238
|
def extract_tag(frame)
|
218
|
-
@file.seek(frame[:file_position] + frame[:header_size]
|
239
|
+
@file.seek(frame[:file_position] + frame[:header_size] )
|
240
|
+
# GG: Vorbis includes a preamble "vorbis", which is not included in the comments,
|
241
|
+
# but is definitely in the /libvorbis/lib/info.c _vorbis_pack_comment reference implementation.
|
242
|
+
# Speex does not seem to include this preamble.
|
243
|
+
@file.read(7) if @bitstream_format=="vorbis"
|
219
244
|
vendor_length = @file.read(4).unpack("V").first
|
220
245
|
@vendor = @file.read(vendor_length)
|
221
246
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
$:.unshift("lib/")
|
4
|
+
|
5
|
+
require "test/unit"
|
6
|
+
require "ogginfo"
|
7
|
+
require "fileutils"
|
8
|
+
require "tempfile"
|
9
|
+
|
10
|
+
VALID_SPX = <<EOF
|
11
|
+
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
|
55
|
+
uTv3X00=
|
56
|
+
EOF
|
57
|
+
|
58
|
+
class SpxInfoTest < Test::Unit::TestCase
|
59
|
+
|
60
|
+
TEMP_FILE = File.join(Dir.tmpdir, "test.spxinfo.spx")
|
61
|
+
|
62
|
+
def setup
|
63
|
+
valid_spx_file = VALID_SPX.unpack("m*").first
|
64
|
+
File.open(TEMP_FILE, "w") { |f| f.write(valid_spx_file) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def teardown
|
68
|
+
FileUtils.rm_f(TEMP_FILE)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_infos
|
72
|
+
OggInfo.open(TEMP_FILE) do |spx|
|
73
|
+
assert_equal 1, spx.channels
|
74
|
+
assert_equal 32000, spx.samplerate
|
75
|
+
assert_in_delta(0.5, spx.length, 1)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_generated_info
|
80
|
+
generate_spx
|
81
|
+
OggInfo.open("test.spx") do |spx|
|
82
|
+
assert_equal 2, spx.channels
|
83
|
+
assert_equal 44100, spx.samplerate
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def test_charset
|
89
|
+
generate_spx
|
90
|
+
OggInfo.open("test.spx", "utf-8") do |spx|
|
91
|
+
assert_equal "spxinfotest", spx.tag["author"]
|
92
|
+
end
|
93
|
+
|
94
|
+
OggInfo.open("test.spx", "iso-8859-1") do |spx|
|
95
|
+
assert_equal "hello\xe9", spx.tag["test"]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def generate_spx
|
100
|
+
unless test(?f, "test.spx")
|
101
|
+
system("dd if=/dev/urandom bs=1024 count=3000 | speexenc --rate 44100 --stereo --author spxinfotest --title SpxInfoTest --comment test=\"hello\303\251\" - test.spx") or
|
102
|
+
flunk("cannot generate \"test.spx\", tests cannot be fully performed")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-ogginfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 5
|
8
|
+
version: "0.5"
|
5
9
|
platform: ruby
|
6
10
|
authors:
|
7
11
|
- Guillaume Pierronnet
|
@@ -9,19 +13,37 @@ autorequire:
|
|
9
13
|
bindir: bin
|
10
14
|
cert_chain: []
|
11
15
|
|
12
|
-
date:
|
16
|
+
date: 2011-01-13 00:00:00 +01:00
|
13
17
|
default_executable:
|
14
18
|
dependencies:
|
15
19
|
- !ruby/object:Gem::Dependency
|
16
|
-
name: hoe
|
20
|
+
name: hoe-yard
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
segments:
|
27
|
+
- 0
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
version: 0.1.2
|
17
31
|
type: :development
|
18
|
-
|
19
|
-
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: hoe
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
20
37
|
requirements:
|
21
38
|
- - ">="
|
22
39
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
40
|
+
segments:
|
41
|
+
- 2
|
42
|
+
- 8
|
43
|
+
- 0
|
44
|
+
version: 2.8.0
|
45
|
+
type: :development
|
46
|
+
version_requirements: *id002
|
25
47
|
description: |-
|
26
48
|
ruby-ogginfo gives you access to low level information on ogg files
|
27
49
|
(bitrate, length, samplerate, encoder, etc... ), as well as tag.
|
@@ -34,43 +56,48 @@ extensions: []
|
|
34
56
|
extra_rdoc_files:
|
35
57
|
- History.txt
|
36
58
|
- Manifest.txt
|
37
|
-
- README.txt
|
38
59
|
files:
|
39
60
|
- History.txt
|
40
61
|
- Manifest.txt
|
41
|
-
- README.
|
62
|
+
- README.rdoc
|
42
63
|
- Rakefile
|
43
64
|
- setup.rb
|
44
65
|
- lib/ogginfo.rb
|
45
66
|
- test/test_ruby-ogginfo.rb
|
46
|
-
has_rdoc:
|
47
|
-
homepage:
|
67
|
+
has_rdoc: yard
|
68
|
+
homepage: |
|
69
|
+
http://ruby-ogginfo.rubyforge.org/
|
70
|
+
|
48
71
|
licenses: []
|
49
72
|
|
50
73
|
post_install_message:
|
51
74
|
rdoc_options:
|
52
|
-
- --
|
53
|
-
-
|
75
|
+
- --title
|
76
|
+
- RubyOgginfo Documentation
|
77
|
+
- --quiet
|
54
78
|
require_paths:
|
55
79
|
- lib
|
56
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
57
81
|
requirements:
|
58
82
|
- - ">="
|
59
83
|
- !ruby/object:Gem::Version
|
84
|
+
segments:
|
85
|
+
- 0
|
60
86
|
version: "0"
|
61
|
-
version:
|
62
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
88
|
requirements:
|
64
89
|
- - ">="
|
65
90
|
- !ruby/object:Gem::Version
|
91
|
+
segments:
|
92
|
+
- 0
|
66
93
|
version: "0"
|
67
|
-
version:
|
68
94
|
requirements: []
|
69
95
|
|
70
96
|
rubyforge_project: ruby-ogginfo
|
71
|
-
rubygems_version: 1.3.
|
97
|
+
rubygems_version: 1.3.6
|
72
98
|
signing_key:
|
73
99
|
specification_version: 3
|
74
100
|
summary: ruby-ogginfo is a pure-ruby library that gives low level informations on ogg files
|
75
101
|
test_files:
|
76
102
|
- test/test_ruby-ogginfo.rb
|
103
|
+
- test/test_ruby-spxinfo.rb
|