mediainfo 0.7.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ module MediaInfo
2
+ # General
3
+ class Error < StandardError; end
4
+ class EnvironmentError < Error; end
5
+ class ExecutionError < Error; end
6
+ class IncompatibleVersionError < Error; end
7
+ class UnknownVersionError < Error; end
8
+ class RemoteUrlError < Error; end
9
+ # Stream
10
+ class SingleStreamAPIError < RuntimeError; end
11
+ class NoStreamsForProxyError < NoMethodError; end
12
+ class InvalidTrackType < Error; end
13
+ class InvalidTrackAttributeValue < Error; end
14
+ end
@@ -12,14 +12,4 @@ class String
12
12
  def shell_escape_double_quotes
13
13
  '"'+gsub(/\\|"|\$|`/, '\\\\\0')+'"'
14
14
  end unless method_defined?(:shell_escape_double_quotes)
15
-
16
- # stolen from active_support/inflector
17
- # TODO require "active_support/core_ext/string/inflections" when 3.0 is released
18
- def underscore
19
- gsub(/::/, '/').
20
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
21
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
22
- tr("-", "_").
23
- downcase
24
- end unless method_defined?(:underscore)
25
15
  end
@@ -0,0 +1,172 @@
1
+ require 'time'
2
+ require 'yaml' # Used for standardization methods
3
+ module MediaInfo
4
+ class Tracks
5
+
6
+ # Needed so that .image?, when there is no Image track, doesn't throw NoMethodError
7
+ def method_missing( name, *args )
8
+ nil # We use nil here instead of false as nil should be understood by the client/requester as false. We might not want to specifically return false for other missing methods
9
+ end
10
+
11
+ attr_reader :xml, :track_types, :attribute_standardization_rules
12
+
13
+ def initialize(input = nil)
14
+ if input && input.include?('<?xml')
15
+ @xml = input
16
+ @track_types = []
17
+ @attribute_standardization_rules = YAML.load_file("#{Gem::Specification.find_by_name('mediainfo').gem_dir}/lib/attribute_standardization_rules.yml")
18
+ # Populate Streams
19
+ case MediaInfo.xml_parser
20
+ when 'nokogiri'
21
+ converted_xml = ::Nokogiri::XML(self.xml)
22
+ converted_xml.css('//track').each { |track| # Have to use .css here due to iphone6 MediaInfo structure
23
+ track_elements = Attributes.new(track.children.select{ |n| n.is_a? ::Nokogiri::XML::Element }.map{ |parameter|
24
+ parameter.name = standardize_element_name(parameter.name) # Turn various element names into standardized versions (Bit_rate to Bitrate)
25
+ if parameter.text.include?("\n") # if it has children (extra in iphone6+_video.mov.xml)
26
+ [parameter.name, parameter.children.select { |n| n.is_a? ::Nokogiri::XML::Element }.map{ |parameter| [parameter.name, parameter.text]}]
27
+ else
28
+ [parameter.name, parameter.text]
29
+ end
30
+ })
31
+ track_type = sanitize_track_type(@track_types,track.attributes.map{ |k,v| { :name => v.name, :value => v.value } },track.children.css('ID').map{ |el| el.text })
32
+ @track_types << track_type
33
+ MediaInfo.set_singleton_method(self,track_type,track_elements)
34
+ }
35
+ else # DEFAULT REXML
36
+ converted_xml = ::REXML::Document.new(self.xml)
37
+ converted_xml.elements.each('//track') { |track|
38
+ track_elements = Attributes.new(track.children.select { |n| n.is_a? ::REXML::Element }.map{ |parameter|
39
+ parameter.name = standardize_element_name(parameter.name)
40
+ if parameter.text.include?("\n") # if it has children (extra in iphone6+_video.mov.xml)
41
+ [parameter.name, parameter.children.select { |n| n.is_a? ::REXML::Element }.map{ |parameter| [parameter.name, parameter.text]}]
42
+ else
43
+ [parameter.name, parameter.text]
44
+ end
45
+ })
46
+ track_type = sanitize_track_type(@track_types,track.attributes.map{ |attr| { :name => attr[0], :value => attr[1] } },track.elements.detect{|el| el.name == 'id' }.to_a)
47
+ @track_types << track_type
48
+ MediaInfo.set_singleton_method(self,track_type,track_elements)
49
+ }
50
+ end
51
+
52
+ # Add {type}?
53
+ @track_types.each{ |track_type|
54
+ define_singleton_method("#{track_type}?"){ # Can't use set_singleton_method due to ?
55
+ self.track_types.any?(__method__.to_s.gsub('?',''))
56
+ }
57
+ }
58
+ # Add {type}.count singleton_method
59
+ @track_types.each{ |track_type|
60
+ MediaInfo.set_singleton_method(self.instance_variable_get("@#{track_type}"),'count',@track_types.grep(/#{track_type}/).count)
61
+ }
62
+
63
+ else
64
+ raise ArgumentError, 'Input must be raw XML.'
65
+ end
66
+ end # end Initialize
67
+
68
+ # Standardize our Element Names
69
+ ## Relies on valid YAML in lib/attribute_standardization_rules.yml
70
+ def standardize_element_name(name)
71
+ self.attribute_standardization_rules[name].nil? ? name : self.attribute_standardization_rules[name]
72
+ end
73
+
74
+ class Attributes
75
+
76
+ # Needed so that sanitize_elements doesn't throw NoMethodError
77
+ def method_missing( name, *args )
78
+ nil # We use nil here instead of false as nil should be understood by the client/requester as false. We might not want to specifically return false for other missing methods
79
+ end
80
+
81
+ def initialize(params)
82
+ params.each{ |param|
83
+ if param[1].is_a?(Array)
84
+ MediaInfo.set_singleton_method(self,param[0],Extra.new(param[1]))
85
+ else
86
+ MediaInfo.set_singleton_method(self,param[0],MediaInfo::Tracks::Attributes.sanitize_element_value(param))
87
+ end
88
+ }
89
+ end
90
+
91
+ class Extra
92
+ def initialize(params)
93
+ params.each{ |param| MediaInfo.set_singleton_method(self,param[0],MediaInfo::Tracks::Attributes.sanitize_element_value(param)) }
94
+ end
95
+ end
96
+
97
+ def self.sanitize_element_value(param)
98
+ name = param[0]
99
+ value = param[1]
100
+ case
101
+ # Convert String with integer in it to Integer.
102
+ ## Don't to_f anything with 2 or more dots (versions,etc)
103
+ when value.match(/(?!\.)\D+/).nil? then
104
+ if value.scan(/\./).any? && value.scan(/\./).count > 1
105
+ value
106
+ elsif value.scan(/\./).any?
107
+ value.to_f
108
+ else # Prevent float if it's just a normal integer
109
+ value.to_i
110
+ end
111
+ # Duration
112
+ when ['Duration'].include?(name) then standardize_to_milliseconds(value)
113
+ # Dates
114
+ ## Be sure the name has "date" and it has an integer and a dash, like a normal date would
115
+ when name.downcase.include?('date') && !value.match(/\d-/).nil? then Time.parse(value)
116
+ else
117
+ return value
118
+ end
119
+ end
120
+
121
+ def self.standardize_to_milliseconds(value)
122
+ # TODO iphone video has a float as the duration
123
+ # UPDATE THE README IF YOU'RE CHANGING THIS
124
+ milliseconds = 0
125
+ value.scan(/\d+\s?\w+/).each do |chunk|
126
+ case chunk
127
+ when /\d+\s?h/ then milliseconds += chunk.to_i * 60 * 60 * 1000
128
+ when /\d+\s?hour/ then milliseconds += chunk.to_i * 60 * 60 * 1000
129
+ when /\d+\s?m/ then milliseconds += chunk.to_i * 60 * 1000
130
+ when /\d+\s?mn/ then milliseconds += chunk.to_i * 60 * 1000
131
+ when /\d+\s?min/ then milliseconds += chunk.to_i * 60 * 1000
132
+ when /\d+\s?s/ then milliseconds += chunk.to_i * 1000
133
+ when /\d+\s?sec/ then milliseconds += chunk.to_i * 1000
134
+ when /\d+\s?ms/ then milliseconds += chunk.to_i
135
+ end
136
+ end
137
+ milliseconds = value if milliseconds == 0 # We don't raise anymore. It's much better for the gem to work, returning the original MediaInfo attribute, than raise.
138
+ return milliseconds
139
+ end
140
+
141
+ end
142
+
143
+
144
+ # Used for handling duplicate track types with differing streamid, etc
145
+ # Takes an array of attributes and returns the track_name
146
+ ## Parameters must meet the following structure:
147
+ # TRACK_TYPES: ['video','video2','text'] or [] if nothing created yet
148
+ # TRACK_ATTRIBUTES: [{:name=>"type", :value=>"Text" }] or [] if not found
149
+ # TRACK_ID: ["1"] or [] if not found
150
+ def sanitize_track_type(track_types,track_attributes,track_id)
151
+ raise("Unable to sanitize a track type due to missing 'type' attribute in on of the elements: \n #{track_attributes}") if (type_attr_value = track_attributes.detect{ |attr| attr[:name] == 'type' }[:value]).nil?
152
+ if (streamid = track_attributes.detect{ |attr| attr[:name] == 'streamid' || attr[:name] == 'typeorder' }).nil? # No StreamId, however, ensuring that if the streamid is there we use it ## We must still manually specify the id attr until https://sourceforge.net/p/mediainfo/discussion/297610/thread/f17a0cf5/ is answered
153
+ ## Even if no streamid we need to check for duplicate track names and append an integer. ONLY WORKS IF DUPLICATE TRACKS ARE CONSECUTIVE
154
+ if track_types.include?(type_attr_value.downcase)
155
+ if !track_id.nil? && !track_id.empty? && track_id.first.to_s.to_i > 1 ## If the track has an ID child, and it's an integer above 1 (if it's a string, to_i returns 0) (if to_i returns > 1 so we can match id convention of video vs video1; see code below this section), use that
156
+ type = "#{type_attr_value}#{track_id.first}"
157
+ else
158
+ type = "#{type_attr_value}#{track_types.grep(/#{type_attr_value.downcase}/).count + 1}"
159
+ end
160
+ else
161
+ type = type_attr_value
162
+ end
163
+ else
164
+ # For anything with a streamid of 1, ignore it. This is due to the logic of non-streamid duplicates not appending an integer for the first occurrence. We want to be consistent.
165
+ ## We use _ to separate the streamid so we can do easier matching for non-streamid duplicates
166
+ type = streamid[:value] == '1' ? type_attr_value : "#{type_attr_value}#{streamid[:value]}"
167
+ end
168
+ return type.downcase
169
+ end
170
+
171
+ end
172
+ end
@@ -0,0 +1,3 @@
1
+ module MediaInfo
2
+ VERSION = '1.0.1'
3
+ end
data/mediainfo.gemspec CHANGED
@@ -1,30 +1,33 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mediainfo/version'
2
5
 
3
6
  Gem::Specification.new do |s|
4
7
  s.name = %q{mediainfo}
5
- s.version = "0.7.2"
6
-
7
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
- s.authors = [%q{Seth Thomas Rasmussen}]
9
- s.date = %q{2011-05-13}
10
- s.description = %q{Mediainfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net)}
8
+ s.version = MediaInfo::VERSION
9
+ s.licenses = ['MIT']
10
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.2') if s.respond_to? :required_rubygems_version=
11
+ s.authors = ['Seth Thomas Rasmussen']
12
+ s.description = %q{MediaInfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net) that standardizes attributes/methods and also converts most values into something Ruby can understand.}
11
13
  s.email = %q{sethrasmussen@gmail.com}
12
- s.extra_rdoc_files = [%q{LICENSE}, %q{README.markdown}, %q{lib/mediainfo.rb}, %q{lib/mediainfo/attr_readers.rb}, %q{lib/mediainfo/string.rb}]
13
- s.files = [%q{Changelog}, %q{LICENSE}, %q{Manifest}, %q{README.markdown}, %q{Rakefile}, %q{index.html.template}, %q{lib/mediainfo.rb}, %q{lib/mediainfo/attr_readers.rb}, %q{lib/mediainfo/string.rb}, %q{mediainfo.gemspec}, %q{test/mediainfo_awaywego_test.rb}, %q{test/mediainfo_broken_embraces_test.rb}, %q{test/mediainfo_dinner_test.rb}, %q{test/mediainfo_hats_test.rb}, %q{test/mediainfo_multiple_streams_test.rb}, %q{test/mediainfo_omen_image_test.rb}, %q{test/mediainfo_string_test.rb}, %q{test/mediainfo_subtilte_test.rb}, %q{test/mediainfo_test.rb}, %q{test/mediainfo_vimeo_test.rb}, %q{test/test_helper.rb}]
14
- s.homepage = %q{http://greatseth.github.com/mediainfo}
15
- s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Mediainfo}, %q{--main}, %q{README.markdown}]
16
- s.require_paths = [%q{lib}]
14
+ s.homepage = %q{https://github.com/greatseth/mediainfo}
15
+ s.rdoc_options = ['--line-numbers', '--inline-source', '--title', 'Mediainfo', '--main']
16
+ s.require_paths = ['lib']
17
17
  s.rubyforge_project = %q{mediainfo}
18
- s.rubygems_version = %q{1.8.2}
19
- s.summary = %q{Mediainfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net)}
20
- s.test_files = [%q{test/mediainfo_awaywego_test.rb}, %q{test/mediainfo_broken_embraces_test.rb}, %q{test/mediainfo_dinner_test.rb}, %q{test/mediainfo_hats_test.rb}, %q{test/mediainfo_multiple_streams_test.rb}, %q{test/mediainfo_omen_image_test.rb}, %q{test/mediainfo_string_test.rb}, %q{test/mediainfo_subtilte_test.rb}, %q{test/mediainfo_test.rb}, %q{test/mediainfo_vimeo_test.rb}, %q{test/test_helper.rb}]
18
+ s.summary = %q{MediaInfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net)}
19
+ s.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+
23
+ # Since Ruby 1.8, REXML is included in the standard Ruby distribution.
24
+ s.add_development_dependency 'bundler', '~> 1.16'
25
+ s.add_development_dependency 'rake', '~> 12.3'
26
+ s.add_development_dependency 'rspec', '~> 3.0'
27
+ s.add_development_dependency 'nokogiri', '~> 1.8' # Ability to parse XML response # Optional and should be included by user in their own gemfile
21
28
 
22
29
  if s.respond_to? :specification_version then
30
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
31
  s.specification_version = 3
24
-
25
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
- else
27
- end
28
- else
29
32
  end
30
33
  end
metadata CHANGED
@@ -1,93 +1,120 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mediainfo
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.7.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - Seth Thomas Rasmussen
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
-
13
- date: 2011-05-13 00:00:00 Z
14
- dependencies: []
15
-
16
- description: Mediainfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net)
11
+ date: 2018-05-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
69
+ description: MediaInfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net)
70
+ that standardizes attributes/methods and also converts most values into something
71
+ Ruby can understand.
17
72
  email: sethrasmussen@gmail.com
18
73
  executables: []
19
-
20
74
  extensions: []
21
-
22
- extra_rdoc_files:
23
- - LICENSE
24
- - README.markdown
25
- - lib/mediainfo.rb
26
- - lib/mediainfo/attr_readers.rb
27
- - lib/mediainfo/string.rb
28
- files:
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".rspec"
29
79
  - Changelog
80
+ - GemFile
30
81
  - LICENSE
31
- - Manifest
32
- - README.markdown
82
+ - README.md
33
83
  - Rakefile
34
- - index.html.template
84
+ - lib/attribute_standardization_rules.yml
35
85
  - lib/mediainfo.rb
36
- - lib/mediainfo/attr_readers.rb
86
+ - lib/mediainfo/errors.rb
37
87
  - lib/mediainfo/string.rb
88
+ - lib/mediainfo/tracks.rb
89
+ - lib/mediainfo/version.rb
38
90
  - mediainfo.gemspec
39
- - test/mediainfo_awaywego_test.rb
40
- - test/mediainfo_broken_embraces_test.rb
41
- - test/mediainfo_dinner_test.rb
42
- - test/mediainfo_hats_test.rb
43
- - test/mediainfo_multiple_streams_test.rb
44
- - test/mediainfo_omen_image_test.rb
45
- - test/mediainfo_string_test.rb
46
- - test/mediainfo_subtilte_test.rb
47
- - test/mediainfo_test.rb
48
- - test/mediainfo_vimeo_test.rb
49
- - test/test_helper.rb
50
- homepage: http://greatseth.github.com/mediainfo
51
- licenses: []
52
-
91
+ homepage: https://github.com/greatseth/mediainfo
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
53
95
  post_install_message:
54
- rdoc_options:
55
- - --line-numbers
56
- - --inline-source
57
- - --title
96
+ rdoc_options:
97
+ - "--line-numbers"
98
+ - "--inline-source"
99
+ - "--title"
58
100
  - Mediainfo
59
- - --main
60
- - README.markdown
61
- require_paths:
101
+ - "--main"
102
+ require_paths:
62
103
  - lib
63
- required_ruby_version: !ruby/object:Gem::Requirement
64
- none: false
65
- requirements:
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
66
106
  - - ">="
67
- - !ruby/object:Gem::Version
68
- version: "0"
69
- required_rubygems_version: !ruby/object:Gem::Requirement
70
- none: false
71
- requirements:
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
72
111
  - - ">="
73
- - !ruby/object:Gem::Version
74
- version: "1.2"
112
+ - !ruby/object:Gem::Version
113
+ version: '1.2'
75
114
  requirements: []
76
-
77
115
  rubyforge_project: mediainfo
78
- rubygems_version: 1.8.2
116
+ rubygems_version: 2.7.6
79
117
  signing_key:
80
118
  specification_version: 3
81
- summary: Mediainfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net)
82
- test_files:
83
- - test/mediainfo_awaywego_test.rb
84
- - test/mediainfo_broken_embraces_test.rb
85
- - test/mediainfo_dinner_test.rb
86
- - test/mediainfo_hats_test.rb
87
- - test/mediainfo_multiple_streams_test.rb
88
- - test/mediainfo_omen_image_test.rb
89
- - test/mediainfo_string_test.rb
90
- - test/mediainfo_subtilte_test.rb
91
- - test/mediainfo_test.rb
92
- - test/mediainfo_vimeo_test.rb
93
- - test/test_helper.rb
119
+ summary: MediaInfo is a class wrapping the mediainfo CLI (http://mediainfo.sourceforge.net)
120
+ test_files: []