Class: MediaInfo::Tracks
- Inherits:
-
Object
- Object
- MediaInfo::Tracks
- Defined in:
- lib/mediainfo/tracks.rb
Defined Under Namespace
Classes: Attributes
Instance Attribute Summary collapse
-
#attribute_standardization_rules ⇒ Object
readonly
Returns the value of attribute attribute_standardization_rules.
-
#track_types ⇒ Object
readonly
Returns the value of attribute track_types.
-
#xml ⇒ Object
readonly
Returns the value of attribute xml.
Instance Method Summary collapse
-
#initialize(input = nil) ⇒ Tracks
constructor
A new instance of Tracks.
-
#method_missing(name, *args) ⇒ Object
Needed so that .image?, when there is no Image track, doesn’t throw NoMethodError.
-
#sanitize_track_type(track_types, track_attributes, track_id) ⇒ Object
Used for handling duplicate track types with differing streamid, etc Takes an array of attributes and returns the track_name Parameters must meet the following structure: TRACK_TYPES: [‘video’,‘video2’,‘text’] or [] if nothing created yet TRACK_ATTRIBUTES: [{:name=>“type”, :value=>“Text” }] or [] if not found TRACK_ID: [“1”] or [] if not found.
-
#standardize_element_name(name) ⇒ Object
Standardize our Element Names Relies on valid YAML in lib/attribute_standardization_rules.yml.
Constructor Details
#initialize(input = nil) ⇒ Tracks
Returns a new instance of Tracks.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/mediainfo/tracks.rb', line 13 def initialize(input = nil) if input && input.include?('<?xml') @xml = input.gsub(/(\n|.)*(\<\?xml)/,'<?xml') @track_types = [] @attribute_standardization_rules = YAML.load_file("#{Gem::Specification.find_by_name('mediainfo').gem_dir}/lib/attribute_standardization_rules.yml") # Populate Streams case MediaInfo.xml_parser when 'nokogiri' converted_xml = ::Nokogiri::XML(self.xml) converted_xml.css('//track').each { |track| # Have to use .css here due to iphone6 MediaInfo structure track_elements = Attributes.new(track.children.select{ |n| n.is_a? ::Nokogiri::XML::Element }.map{ |parameter| parameter.name = standardize_element_name(parameter.name) # Turn various element names into standardized versions (Bit_rate to Bitrate) if parameter.text.include?("\n") # if it has children (extra in iphone6+_video.mov.xml) [parameter.name, parameter.children.select { |n| n.is_a? ::Nokogiri::XML::Element }.map{ |parameter| [parameter.name, parameter.text]}] else [parameter.name, parameter.text] end }) 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 }) @track_types << track_type MediaInfo.set_singleton_method(self,track_type,track_elements) } else # DEFAULT REXML converted_xml = ::REXML::Document.new(self.xml) converted_xml.elements.each('//track') { |track| track_elements = Attributes.new(track.children.select { |n| n.is_a? ::REXML::Element }.map{ |parameter| parameter.name = standardize_element_name(parameter.name) if parameter.text.include?("\n") # if it has children (extra in iphone6+_video.mov.xml) [parameter.name, parameter.children.select { |n| n.is_a? ::REXML::Element }.map{ |parameter| [parameter.name, parameter.text]}] else [parameter.name, parameter.text] end }) 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) @track_types << track_type MediaInfo.set_singleton_method(self,track_type,track_elements) } end # Add {type}? @track_types.each{ |track_type| define_singleton_method("#{track_type}?"){ # Can't use set_singleton_method due to ? self.track_types.include?(__method__.to_s.gsub('?','')) } } # Add {type}.count singleton_method @track_types.each{ |track_type| MediaInfo.set_singleton_method(self.instance_variable_get("@#{track_type}"),'count',@track_types.grep(/#{track_type}/).count) } else raise ArgumentError, 'Input must be raw XML.' end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
Needed so that .image?, when there is no Image track, doesn’t throw NoMethodError
7 8 9 |
# File 'lib/mediainfo/tracks.rb', line 7 def method_missing( name, *args ) 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 end |
Instance Attribute Details
#attribute_standardization_rules ⇒ Object (readonly)
Returns the value of attribute attribute_standardization_rules.
11 12 13 |
# File 'lib/mediainfo/tracks.rb', line 11 def attribute_standardization_rules @attribute_standardization_rules end |
#track_types ⇒ Object (readonly)
Returns the value of attribute track_types.
11 12 13 |
# File 'lib/mediainfo/tracks.rb', line 11 def track_types @track_types end |
#xml ⇒ Object (readonly)
Returns the value of attribute xml.
11 12 13 |
# File 'lib/mediainfo/tracks.rb', line 11 def xml @xml end |
Instance Method Details
#sanitize_track_type(track_types, track_attributes, track_id) ⇒ Object
Used for handling duplicate track types with differing streamid, etc Takes an array of attributes and returns the track_name Parameters must meet the following structure: TRACK_TYPES: [‘video’,‘video2’,‘text’] or [] if nothing created yet TRACK_ATTRIBUTES: [{:name=>“type”, :value=>“Text” }] or [] if not found TRACK_ID: [“1”] or [] if not found
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/mediainfo/tracks.rb', line 151 def sanitize_track_type(track_types,track_attributes,track_id) 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? 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 ## Even if no streamid we need to check for duplicate track names and append an integer. ONLY WORKS IF DUPLICATE TRACKS ARE CONSECUTIVE if track_types.include?(type_attr_value.downcase) 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 type = "#{type_attr_value}#{track_id.first}" else type = "#{type_attr_value}#{track_types.grep(/#{type_attr_value.downcase}/).count + 1}" end else type = type_attr_value end else # 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. ## We use _ to separate the streamid so we can do easier matching for non-streamid duplicates type = streamid[:value] == '1' ? type_attr_value : "#{type_attr_value}#{streamid[:value]}" end return type.downcase end |
#standardize_element_name(name) ⇒ Object
Standardize our Element Names Relies on valid YAML in lib/attribute_standardization_rules.yml
70 71 72 |
# File 'lib/mediainfo/tracks.rb', line 70 def standardize_element_name(name) self.attribute_standardization_rules[name].nil? ? name : self.attribute_standardization_rules[name] end |