mediainfo 0.7.2 → 1.0.1

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.
@@ -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: []