Module: MediaInfo

Defined in:
lib/mediainfo.rb,
lib/mediainfo/errors.rb,
lib/mediainfo/tracks.rb,
lib/mediainfo/version.rb

Defined Under Namespace

Classes: BadInputError, EnvironmentError, ExecutionError, IncompatibleVersionError, InvalidTrackAttributeValue, InvalidTrackType, NoStreamsForProxyError, RemoteUrlError, SingleStreamAPIError, Tracks, UnknownVersionError

Constant Summary collapse

VERSION =
'1.2.0'

Class Method Summary collapse

Class Method Details

.from(input) ⇒ Object

Raises:



67
68
69
70
71
# File 'lib/mediainfo.rb', line 67

def self.from(input)
  return from_uri(input) if input.is_a?(URI)
  return from_string(input) if input.is_a?(String)
  raise BadInputError
end


94
95
96
# File 'lib/mediainfo.rb', line 94

def self.from_link(input)
  from_uri(URI(input))
end

.from_local_file(input) ⇒ Object

Raises:

  • (ArgumentError)


84
85
86
87
88
89
90
91
92
# File 'lib/mediainfo.rb', line 84

def self.from_local_file(input)
  absolute_path = File.expand_path(input) # turns relative to absolute path

  raise ArgumentError, 'You must include a file location.' if absolute_path.nil?
  raise ArgumentError, "need a path to a video file, #{absolute_path} does not exist" unless File.exist?(absolute_path)

  return from_xml(File.open(absolute_path).read) if absolute_path.match(/[^\\]*\.(xml)$/)
  MediaInfo::Tracks.new(MediaInfo.run(absolute_path.shell_escape_double_quotes))
end

.from_string(input) ⇒ Object

Raises:



73
74
75
76
77
78
# File 'lib/mediainfo.rb', line 73

def self.from_string(input)
  return from_xml(input) if input.include?('<?xml')
  return from_link(input) if input.include?('://') && input =~ URI::regexp
  return from_local_file(input) if input.match(/[^\\]*\.\w+$/)
  raise BadInputError
end

.from_uri(input) ⇒ Object

Raises:



98
99
100
101
102
103
104
105
106
107
# File 'lib/mediainfo.rb', line 98

def self.from_uri(input)
  http = Net::HTTP.new(input.host, input.port) # Check if input is valid
  request = Net::HTTP::Head.new(input.request_uri) # Only grab the Headers to be sure we don't try and download the whole file

  http.use_ssl = true if input.is_a? URI::HTTPS # For https support

  raise RemoteUrlError, "HTTP call to #{input} is not working!" unless http.request(request).is_a?(Net::HTTPOK)

  MediaInfo::Tracks.new(MediaInfo.run(URI.escape(input.to_s)))
end

.from_xml(input) ⇒ Object



80
81
82
# File 'lib/mediainfo.rb', line 80

def self.from_xml(input)
  MediaInfo::Tracks.new(input)
end

.locationObject

Allow user to set custom mediainfo_path with ENV

Raises:



21
22
23
24
25
26
27
28
29
# File 'lib/mediainfo.rb', line 21

def self.location
  if ENV['MEDIAINFO_PATH'].nil?
    mediainfo_location = which('mediainfo')
  else
    mediainfo_location = ENV['MEDIAINFO_PATH']
  end
  raise EnvironmentError, "#{mediainfo_location} cannot be found. Are you sure mediainfo is installed?" unless ::File.exist? mediainfo_location
  return mediainfo_location
end

.run(input = nil) ⇒ Object

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
# File 'lib/mediainfo.rb', line 57

def self.run(input = nil)
  raise ArgumentError, 'Your input cannot be blank.' if input.nil?
  command = "#{location} #{input} --Output=XML 2>&1"
  raw_response = `#{command}`
  unless $? == 0
    raise ExecutionError, "Execution of '#{command}' failed. #{raw_response.inspect}"
  end
  return raw_response
end

.set_singleton_method(object, name, parameters) ⇒ Object



109
110
111
112
113
114
115
116
117
118
# File 'lib/mediainfo.rb', line 109

def self.set_singleton_method(object,name,parameters)
  # Handle parameters with invalid characters (instance_variable_set throws error)
  name.gsub!('.','_') if name.include?('.') ## period in name
  name.downcase!
  # Create singleton_method
  object.instance_variable_set("@#{name}",parameters)
  object.define_singleton_method name do
    object.instance_variable_get "@#{name}"
  end
end

.versionObject

Allow collection of MediaInfo version details



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/mediainfo.rb', line 32

def self.version
  version ||= `#{location} --Version`[/v([\d.]+)/, 1]
  # Ensure MediaInfo isn't buggy and returns something
  raise UnknownVersionError, 'Unable to determine mediainfo version. ' + "We tried: #{location} --Version." +
        'Set MediaInfo.path = \'/full/path/of/mediainfo\' if it is not in your PATH.' unless version
  # Ensure you're not using an old version of MediaInfo
  if version < '0.7.25'
    raise IncompatibleVersionError, "Your version of mediainfo, #{version}, " +
        'is not compatible with this gem. >= 0.7.25 required.'
  else
    @version = version
  end

end

.which(cmd) ⇒ Object



9
10
11
12
13
14
15
16
17
18
# File 'lib/mediainfo.rb', line 9

def self.which(cmd)
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each { |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return exe if File.executable?(exe) && !File.directory?(exe)
    }
  end
  return nil
end

.xml_parserObject



47
48
49
50
51
52
53
54
55
# File 'lib/mediainfo.rb', line 47

def self.xml_parser
  ENV['MEDIAINFO_XML_PARSER'].nil? || ENV['MEDIAINFO_XML_PARSER'].to_s.strip.empty? ? xml_parser = 'rexml/document' : xml_parser = ENV['MEDIAINFO_XML_PARSER']
  begin
    require xml_parser
  rescue Gem::LoadError => ex
    raise Gem::LoadError, "Your specified XML parser, #{xml_parser.inspect}, could not be loaded: #{ex.message}"
  end
  return xml_parser
end