greatseth-mediainfo 0.1 → 0.3

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/Changelog CHANGED
@@ -1 +1,14 @@
1
+ v0.3 Mediainfo Is High Class
2
+ - Class instead of instance-level customization of mediainfo binary path.
3
+ Set Mediainfo.path = /path/to/binary if mediainfo is not in your shell
4
+ path.
5
+ - Instances retain the :last_command run. The API to rerun that command is
6
+ still private.
7
+ - Started defining custom Mediainfo exception classes and are now raising
8
+ Mediainfo::ExecutionError instead of RuntimeError if the system command
9
+ exits with anything other than 0.
10
+
11
+ v0.2 Escape from the Shell
12
+ - Added proper escaping for funky filenames. Thanks to Peter Vandenberk!
13
+
1
14
  v0.1 Initial Release
data/Manifest CHANGED
@@ -1,7 +1,9 @@
1
1
  Changelog
2
2
  lib/mediainfo/attr_readers.rb
3
+ lib/mediainfo/string.rb
3
4
  lib/mediainfo.rb
4
5
  LICENSE
5
6
  Manifest
7
+ mediainfo.gemspec
6
8
  Rakefile
7
9
  README.markdown
data/README.markdown CHANGED
@@ -1,10 +1,6 @@
1
1
  # Mediainfo
2
2
 
3
- Mediainfo is a class encapsulating the ability to run `mediainfo`
4
- on a file and expose the information it produces in a straightforward
5
- manner.
6
-
7
- The mediainfo CLI can be obtained at http://mediainfo.sourceforge.net.
3
+ Mediainfo is a class wrapping [the mediainfo CLI](http://mediainfo.sourceforge.net).
8
4
 
9
5
  ## Usage
10
6
 
@@ -22,6 +18,14 @@ For a list of all possible attributes supported:
22
18
  In addition to the stock arguments provided by parsing `mediainfo` output,
23
19
  some convenience methods and added behavior is added.
24
20
 
21
+ Mediainfo is inspired by RVideo::Inspector, part of the rvideo gem.
22
+ The rvideo inspector is based on output from ffmpeg which is not
23
+ intended to be machine parseable. I spent a little while chasing
24
+ the ffmpeg development team, and decided finally that perhaps other
25
+ tools were better. As such, some of the API for Mediainfo is straight
26
+ from RVideo::Inspector. Some is not. Just saying.
27
+
25
28
  ## Contributors
26
29
 
27
- * Seth Thomas Rasmussen - http://greatseth.com
30
+ * Seth Thomas Rasmussen - [http://greatseth.com](http://greatseth.com)
31
+ * Peter Vandenberk - [http://github.com/pvdb](http://github.com/pvdb)
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require "rake/testtask"
2
+ load "Rakefile.cloud" if File.exist? "Rakefile.cloud"
2
3
 
3
4
  Rake::TestTask.new do |t|
4
5
  t.libs << "test"
@@ -0,0 +1,9 @@
1
+ class String
2
+ def shell_escape
3
+ # The gsub is for ANSI-C style quoting.
4
+ #
5
+ # The $'' is for bash, see http://www.faqs.org/docs/bashman/bashref_12.html,
6
+ # but appears to be working for other shells: sh, zsh, ksh, dash
7
+ "$'#{gsub(/\\|'/) { |c| "\\#{c}" }}'"
8
+ end
9
+ end
data/lib/mediainfo.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require "mediainfo/string"
1
2
  require "mediainfo/attr_readers"
2
3
 
3
4
  # Mediainfo is a class encapsulating the ability to run `mediainfo`
@@ -117,6 +118,19 @@ class Mediainfo
117
118
  mediainfo_duration_reader :audio_duration
118
119
 
119
120
  mediainfo_attr_reader :audio_sampling_rate
121
+ def audio_sample_rate
122
+ return unless rate = audio_sampling_rate_before_type_cast
123
+ number = rate.gsub(/[^\d.]+/, "").to_f
124
+ number = case rate
125
+ when /KHz/ then number * 1000
126
+ when /Hz/ then number
127
+ else
128
+ raise "unhandled sample rate! please report bug!"
129
+ end
130
+ number.to_i
131
+ end
132
+ alias_method :audio_sampling_rate, :audio_sample_rate
133
+
120
134
  mediainfo_attr_reader :audio_stream_size
121
135
  mediainfo_attr_reader :audio_bit_rate
122
136
  mediainfo_attr_reader :audio_bit_rate_mode
@@ -154,38 +168,57 @@ class Mediainfo
154
168
  ###
155
169
 
156
170
  attr_reader :raw_response, :parsed_response,
157
- :full_filename, :filename, :path
171
+ :full_filename, :filename, :path, :escaped_full_filename
158
172
 
159
173
  def initialize(full_filename)
160
- @mediainfo_binary = "mediainfo"
161
-
162
- @full_filename = full_filename
174
+ @full_filename = File.expand_path full_filename
163
175
  @path = File.dirname @full_filename
164
176
  @filename = File.basename @full_filename
165
177
 
166
178
  raise ArgumentError, "need a path to a video file, got nil" unless @full_filename
167
179
  raise ArgumentError, "need a path to a video file, #{@full_filename} does not exist" unless File.exist? @full_filename
168
180
 
181
+ @escaped_full_filename = @full_filename.shell_escape
169
182
  @raw_response = mediainfo!
170
183
  parse!
171
184
  end
172
185
 
173
- attr_accessor :mediainfo_binary
186
+ class << self; attr_accessor :path; end
187
+ def path; self.class.path; end
188
+
189
+ def self.default_mediainfo_path!; self.path = "mediainfo"; end
190
+ default_mediainfo_path! unless path
174
191
 
175
192
  def mediainfo_version
176
- `#{@mediainfo_binary} --Version`[/v([\d.]+)/, 1]
193
+ `#{path} --Version`[/v([\d.]+)/, 1]
177
194
  end
178
195
 
196
+ attr_reader :last_command
197
+
198
+ class Error < StandardError; end
199
+ class ExecutionError < Error; end
200
+
179
201
  private
180
202
  def mediainfo!
181
- `#{@mediainfo_binary} #{@full_filename}`
203
+ # for bash, see: http://www.faqs.org/docs/bashman/bashref_12.html
204
+ # but appears to be working for other shells: sh, zsh, ksh, dash
205
+ @last_command = "#{path} #{@escaped_full_filename}"
206
+ run_last_command!
207
+ end
208
+
209
+ def run_last_command!
210
+ raw_response = `#{@last_command}`
211
+ unless $? == 0
212
+ raise ExecutionError, "Execution of `#{@last_command}` failed: #{raw_response.inspect}"
213
+ end
214
+ raw_response
182
215
  end
183
216
 
184
217
  def parse!
185
218
  @parsed_response = {}
186
219
  subsection = nil
187
220
 
188
- @raw_response.split("\n").map { |x| x.strip }.each do |line|
221
+ @raw_response.to_s.split("\n").map { |x| x.strip }.each do |line|
189
222
  next if line.empty? || line == "General"
190
223
 
191
224
  if SECTIONS.include? line
data/mediainfo.gemspec CHANGED
@@ -2,33 +2,30 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{mediainfo}
5
- s.version = "0.1"
5
+ s.version = "0.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Seth Thomas Rasmussen"]
9
- s.date = %q{2009-05-10}
9
+ s.date = %q{2009-07-20}
10
10
  s.description = %q{}
11
11
  s.email = %q{sethrasmussen@gmail.com}
12
- s.extra_rdoc_files = ["lib/mediainfo/attr_readers.rb", "lib/mediainfo.rb", "LICENSE", "README.markdown"]
13
- s.files = ["Changelog", "lib/mediainfo/attr_readers.rb", "lib/mediainfo.rb", "LICENSE", "Manifest", "Rakefile", "README.markdown", "mediainfo.gemspec", "test/mediainfo_awaywego_encoded_test.rb", "test/mediainfo_awaywego_test.rb", "test/mediainfo_dinner_test.rb", "test/mediainfo_hats_test.rb", "test/mediainfo_test.rb", "test/mediainfo_vimeo_test.rb", "test/mediainfo_vimeoimage_test.rb", "test/test_helper.rb"]
12
+ s.extra_rdoc_files = ["lib/mediainfo/attr_readers.rb", "lib/mediainfo/string.rb", "lib/mediainfo.rb", "LICENSE", "README.markdown"]
13
+ s.files = ["Changelog", "lib/mediainfo/attr_readers.rb", "lib/mediainfo/string.rb", "lib/mediainfo.rb", "LICENSE", "Manifest", "mediainfo.gemspec", "Rakefile", "README.markdown", "test/mediainfo_awaywego_encoded_test.rb", "test/mediainfo_awaywego_test.rb", "test/mediainfo_dinner_test.rb", "test/mediainfo_hats_test.rb", "test/mediainfo_string_test.rb", "test/mediainfo_test.rb", "test/mediainfo_vimeo_test.rb", "test/mediainfo_vimeoimage_test.rb", "test/test_helper.rb"]
14
14
  s.homepage = %q{http://greatseth.com}
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Mediainfo", "--main", "README.markdown"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{mediainfo}
18
- s.rubygems_version = %q{1.3.3}
18
+ s.rubygems_version = %q{1.3.4}
19
19
  s.summary = %q{}
20
- s.test_files = ["test/mediainfo_awaywego_encoded_test.rb", "test/mediainfo_awaywego_test.rb", "test/mediainfo_dinner_test.rb", "test/mediainfo_hats_test.rb", "test/mediainfo_test.rb", "test/mediainfo_vimeo_test.rb", "test/mediainfo_vimeoimage_test.rb", "test/test_helper.rb"]
20
+ s.test_files = ["test/mediainfo_awaywego_encoded_test.rb", "test/mediainfo_awaywego_test.rb", "test/mediainfo_dinner_test.rb", "test/mediainfo_hats_test.rb", "test/mediainfo_string_test.rb", "test/mediainfo_test.rb", "test/mediainfo_vimeo_test.rb", "test/mediainfo_vimeoimage_test.rb", "test/test_helper.rb"]
21
21
 
22
22
  if s.respond_to? :specification_version then
23
23
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
24
  s.specification_version = 3
25
25
 
26
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
- s.add_development_dependency(%q<echoe>, [">= 0"])
28
27
  else
29
- s.add_dependency(%q<echoe>, [">= 0"])
30
28
  end
31
29
  else
32
- s.add_dependency(%q<echoe>, [">= 0"])
33
30
  end
34
31
  end
@@ -238,7 +238,9 @@ class MediainfoAwaywegoEncodedTest < ActiveSupport::TestCase
238
238
  end
239
239
 
240
240
  test "audio Sampling rate" do
241
- assert_equal "48.0 KHz", @info.audio_sampling_rate
241
+ assert_equal 48000, @info.audio_sample_rate
242
+ assert_equal 48000, @info.audio_sampling_rate
243
+ assert_equal "48.0 KHz", @info.audio_sampling_rate_before_type_cast
242
244
  end
243
245
 
244
246
  test "audio Resolution" do
@@ -241,7 +241,9 @@ class MediainfoAwaywegoTest < ActiveSupport::TestCase
241
241
  end
242
242
 
243
243
  test "audio Sampling rate" do
244
- assert_equal "48.0 KHz", @info.audio_sampling_rate
244
+ assert_equal 48000, @info.audio_sample_rate
245
+ assert_equal 48000, @info.audio_sampling_rate
246
+ assert_equal "48.0 KHz", @info.audio_sampling_rate_before_type_cast
245
247
  end
246
248
 
247
249
  test "audio resolution" do
@@ -225,7 +225,9 @@ class MediainfoDinnerTest < ActiveSupport::TestCase
225
225
  end
226
226
 
227
227
  test "audio Sampling rate" do
228
- assert_equal "8 000 Hz", @info.audio_sampling_rate
228
+ assert_equal 8000, @info.audio_sample_rate
229
+ assert_equal 8000, @info.audio_sampling_rate
230
+ assert_equal "8 000 Hz", @info.audio_sampling_rate_before_type_cast
229
231
  end
230
232
 
231
233
  test "audio resolution" do
@@ -225,7 +225,9 @@ class MediainfoHatsTest < ActiveSupport::TestCase
225
225
  end
226
226
 
227
227
  test "audio Sampling rate" do
228
- assert_equal "16.0 KHz", @info.audio_sampling_rate
228
+ assert_equal 16000, @info.audio_sample_rate
229
+ assert_equal 16000, @info.audio_sampling_rate
230
+ assert_equal "16.0 KHz", @info.audio_sampling_rate_before_type_cast
229
231
  end
230
232
 
231
233
  test "audio resolution" do
@@ -0,0 +1,12 @@
1
+ require "test_helper"
2
+ require "mediainfo_test_helper"
3
+
4
+ class MediainfoStringTest < ActiveSupport::TestCase
5
+ test "escaping slashes" do
6
+ assert_equal '$\'foo\\\bar\'', 'foo\bar'.shell_escape
7
+ end
8
+
9
+ test "escaping quotes" do
10
+ assert_equal '$\'foo\\\'bar\'', "foo'bar".shell_escape
11
+ end
12
+ end
@@ -75,10 +75,31 @@ class MediainfoTest < ActiveSupport::TestCase
75
75
  :image_height
76
76
  ]
77
77
 
78
- supported_attributes.each do |attribute|
78
+ Mediainfo.supported_attributes.each do |attribute|
79
79
  test "supports #{attribute} attribute" do
80
- assert Mediainfo.supported_attributes.include?(attribute),
80
+ assert supported_attributes.include?(attribute),
81
81
  "#{attribute} is not supported"
82
82
  end
83
83
  end
84
+
85
+ def setup
86
+ Mediainfo.default_mediainfo_path!
87
+ end
88
+
89
+ test "retains last system command generated" do
90
+ m = Mediainfo.new "/dev/null"
91
+ assert_equal "mediainfo $'/dev/null'", m.last_command
92
+ end
93
+
94
+ test "allows customization of path to mediainfo binary" do
95
+ Mediainfo.any_instance.stubs(:run_last_command!)
96
+
97
+ assert_equal "mediainfo", Mediainfo.path
98
+
99
+ Mediainfo.path = "/opt/local/bin/mediainfo"
100
+ assert_equal "/opt/local/bin/mediainfo", Mediainfo.path
101
+
102
+ m = Mediainfo.new "/dev/null"
103
+ assert_equal "/opt/local/bin/mediainfo $'/dev/null'", m.last_command
104
+ end
84
105
  end
@@ -225,7 +225,9 @@ class MediainfoVimeoTest < ActiveSupport::TestCase
225
225
  end
226
226
 
227
227
  test "audio Sampling rate" do
228
- assert_equal "11.025 KHz", @info.audio_sampling_rate
228
+ assert_equal 11025, @info.audio_sample_rate
229
+ assert_equal 11025, @info.audio_sampling_rate
230
+ assert_equal "11.025 KHz", @info.audio_sampling_rate_before_type_cast
229
231
  end
230
232
 
231
233
  test "audio resolution" do
data/test/test_helper.rb CHANGED
@@ -12,6 +12,7 @@ end
12
12
 
13
13
  require "rubygems"
14
14
  require "mocha"
15
+ begin; require "redgreen"; rescue LoadError; end
15
16
 
16
17
  $: << File.dirname(__FILE__) + "/../lib"
17
18
  require "mediainfo"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: greatseth-mediainfo
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: "0.3"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seth Thomas Rasmussen
@@ -9,19 +9,10 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-10 00:00:00 -07:00
12
+ date: 2009-07-20 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: echoe
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
24
- version:
14
+ dependencies: []
15
+
25
16
  description: ""
26
17
  email: sethrasmussen@gmail.com
27
18
  executables: []
@@ -30,22 +21,25 @@ extensions: []
30
21
 
31
22
  extra_rdoc_files:
32
23
  - lib/mediainfo/attr_readers.rb
24
+ - lib/mediainfo/string.rb
33
25
  - lib/mediainfo.rb
34
26
  - LICENSE
35
27
  - README.markdown
36
28
  files:
37
29
  - Changelog
38
30
  - lib/mediainfo/attr_readers.rb
31
+ - lib/mediainfo/string.rb
39
32
  - lib/mediainfo.rb
40
33
  - LICENSE
41
34
  - Manifest
35
+ - mediainfo.gemspec
42
36
  - Rakefile
43
37
  - README.markdown
44
- - mediainfo.gemspec
45
38
  - test/mediainfo_awaywego_encoded_test.rb
46
39
  - test/mediainfo_awaywego_test.rb
47
40
  - test/mediainfo_dinner_test.rb
48
41
  - test/mediainfo_hats_test.rb
42
+ - test/mediainfo_string_test.rb
49
43
  - test/mediainfo_test.rb
50
44
  - test/mediainfo_vimeo_test.rb
51
45
  - test/mediainfo_vimeoimage_test.rb
@@ -86,6 +80,7 @@ test_files:
86
80
  - test/mediainfo_awaywego_test.rb
87
81
  - test/mediainfo_dinner_test.rb
88
82
  - test/mediainfo_hats_test.rb
83
+ - test/mediainfo_string_test.rb
89
84
  - test/mediainfo_test.rb
90
85
  - test/mediainfo_vimeo_test.rb
91
86
  - test/mediainfo_vimeoimage_test.rb