lib/mediainfo.rb in mediainfo-0.7.1 vs lib/mediainfo.rb in mediainfo-0.7.2

- old
+ new

@@ -6,24 +6,53 @@ # Mediainfo Mediainfo is a class wrapping [the mediainfo CLI](http://mediainfo.sourceforge.net). ## Installation - - $ gem install mediainfo -s http://gemcutter.org - + + $ gem install mediainfo + ## Usage - + info = Mediainfo.new "/path/to/file" - + That will issue the system call to `mediainfo` and parse the output. You can specify an alternate path if necessary: - + Mediainfo.path = "/opt/local/bin/mediainfo" - + +Once you have an info object, you can start inspecting streams and general metadata. + + info.streams.count # 2 + info.audio? # true + info.video? # true + info.image? # false + +When inspecting specific types of streams, you have a couple general API options. The +first approach assumes one stream of a given type, a common scenario in many video files, +for example. + + info.video.count # 1 + info.audio.count # 1 + info.video.duration # 120 (seconds) + +Sometimes you'll have more than one stream of a given type. Quicktime files can often +contain artifacts like this from somebody editing a more 'normal' file. + + info = Mediainfo.new "funky.mov" + + info.video? # true + info.video.count # 2 + info.video.duration # raises SingleStreamAPIError ! + info.video[0].duration # 120 + info.video[1].duration # 10 + +For some more usage examples, please see the very reasonable test suite accompanying the source code +for this library. It contains a bunch of relevant usage examples. More docs in the future.. contributions +*very* welcome! -By default, REXML is used as the XML parser. If you'd like, you can +Moving on, REXML is used as the XML parser by default. If you'd like, you can configure Mediainfo to use Hpricot or Nokogiri instead using one of the following approaches: * define the `MEDIAINFO_XML_PARSER` environment variable to be the name of the parser as you'd pass to a :gem or :require call. @@ -60,27 +89,32 @@ extend AttrReaders class Error < StandardError; end class ExecutionError < Error; end class IncompatibleVersionError < Error; end + class UnknownVersionError < Error; end def self.delegate(method_name, stream_type = nil) if stream_type == :general def_delegator :"@#{stream_type}_stream", method_name else def_delegator :"@#{stream_type}_stream", method_name, "#{stream_type}_#{method_name}" end end def self.version - @version ||= `#{path} --Version`[/v([\d.]+)/, 1] + @version ||= `#{version_command}`[/v([\d.]+)/, 1] end + def self.version_command + "#{path} --Version" + end + # AttrReaders depends on this. def self.supported_attributes; @supported_attributes ||= []; end - SECTIONS = [:general, :video, :audio, :image] + SECTIONS = [:general, :video, :audio, :image, :menu, :text] NON_GENERAL_SECTIONS = SECTIONS - [:general] attr_reader :streams # Size of source file as reported by File.size. @@ -311,11 +345,25 @@ mediainfo_int_reader :width mediainfo_int_reader :height def frame_size; "#{width}x#{height}" if width or height; end end + + class TextStream < Stream + mediainfo_attr_reader :stream_id, "ID" + mediainfo_attr_reader :format + mediainfo_attr_reader :codec_id, "Codec ID" + mediainfo_attr_reader :codec_info, "Codec ID/Info" + end + class MenuStream < Stream + mediainfo_attr_reader :stream_id, "ID" + mediainfo_date_reader :encoded_date + mediainfo_date_reader :tagged_date + mediainfo_int_reader :delay + end + Mediainfo::SECTIONS.each do |stream_type| class_eval %{ def #{stream_type}; @#{stream_type}_proxy ||= StreamProxy.new(self, :#{stream_type}); end def #{stream_type}?; streams.any? { |x| x.#{stream_type}? }; end }, __FILE__, __LINE__ @@ -326,10 +374,18 @@ attr_reader :raw_response, :full_filename, :filename, :path, :escaped_full_filename ### def initialize(full_filename = nil) + unless mediainfo_version + raise UnknownVersionError, + "Unable to determine mediainfo version. " + + "We tried: #{self.class.version_command} " + + "Are you sure mediainfo is installed at #{self.class.path.inspect}? " + + "Set Mediainfo.path = /where/is/mediainfo if it is not in your PATH." + end + if mediainfo_version < "0.7.25" raise IncompatibleVersionError, "Your version of mediainfo, #{mediainfo_version}, " + "is not compatible with this gem. >= 0.7.25 required." end @@ -393,10 +449,10 @@ def inspect super.sub(/@raw_response=".+?", @/, %{@raw_response="...", @}) end -private + private def mediainfo! @last_command = "#{path} #{@escaped_full_filename} --Output=XML" run_command! end