diff --git a/Rakefile b/Rakefile index 8e3b088..dee769b 100644 --- a/Rakefile +++ b/Rakefile @@ -2,7 +2,7 @@ require 'rubygems' require 'rake' require 'echoe' -Echoe.new("mediainfo-ruby", "0.1.6") do |p| +Echoe.new("mediainfo-ruby", "0.1.9") do |p| p.description = "MediaInfo Ruby Bridge. Call MediaInfo lib directly" p.url = "http://github.com/hackerdude/mediainfo-ruby" p.author = "David Martinez" diff --git a/lib/mediainfo-ruby.rb b/lib/mediainfo-ruby.rb index b04388c..611298e 100644 --- a/lib/mediainfo-ruby.rb +++ b/lib/mediainfo-ruby.rb @@ -5,6 +5,15 @@ require "mediainfo_ruby" module MediaInfoRubyisms_Streams + ThingsWithMultipleStreams = [:video, :audio] + + # Set to true if you want empty values + attr_reader :empty_values + + attr_reader :include_deprecated + + attr_reader :include_inform + # A symbol map to translate from the Rubyisms we use on mediainfo-ruby # to the constants libmediainfo uses. StreamKindSymbolsMap = { @@ -47,12 +56,13 @@ def menu_streams ; self.count_get(MediaInfoLib_StreamKind::Menu, -1); end # value is the help for that option. # By default, anything marked as deprecated in the underlying # library is removed. - def option_definitions(remove_deprecated=true) - option_map = {} + def option_definitions + option_map = {:general=>{}} current = :general switching = true current_map = option_map[:general] - option_defs = self.option("Info_Parameters_CSV", "").each_line{|row| + + option_defs = parameters_csv.each_line{|row| if row.strip == "" switching = true else @@ -67,40 +77,57 @@ def option_definitions(remove_deprecated=true) else key = kv[0] value = kv[1].nil? ? nil : kv[1].chomp - current_map[key] = value unless remove_deprecated && kv[1].nil? ? false : kv[1].include?("Deprecated") + current_map[key] = value unless ! (self.include_deprecated ) && kv[1].nil? ? false : kv[1].include?("Deprecated") end end } option_map end + def parameters_csv + params_csv = self.option("Info_Parameters_CSV", "") + if RUBY_PLATFORM =~ /darwin/ + params_csv = params_csv.gsub("\r", "\n") + end + params_csv + end + # It introspects a video. This means returning a map of all the # values for a definition. By default empty values are not returned. # Send with true to return empty values - def introspect(empty_values=false,include_inform=false) + def introspect results = {} self.option_definitions.each{|topic, topic_parameters| kind_constant = StreamKindSymbolsMap[topic] if ! kind_constant.nil? - results[topic] = {} - topic_parameters.each{|key, value| - # TODO Do this for multiple streams and whatnot? - #debugger if topic == :video && self.video_streams > 0 - value = self.get_value(kind_constant, 0, key, MediaInfoLib_InfoKind::Text, MediaInfoLib_InfoKind::Name) - - if empty_values == true || value.length > 0 - results[topic][key] = value - end - if key == "Inform" - results[topic].delete(key) if ! include_inform - end - # self.get(kind_constant, 1,0, key) # Something like this - } + if ThingsWithMultipleStreams.include?(topic) + streams = self.send("#{topic.to_s}_streams".to_sym) + results[topic] = 0.upto(streams-1).collect{|ix| introspect_topic(kind_constant, topic_parameters, ix) } + else + results[topic] = introspect_topic(kind_constant, topic_parameters) + end end } results end +private + def introspect_topic(kind_constant, topic_parameters, stream_index=0) + result = {} + topic_parameters.each{|key, value| + value = self.get_value(kind_constant, stream_index, key, MediaInfoLib_InfoKind::Text, MediaInfoLib_InfoKind::Name) + + if self.empty_values == true || value.length > 0 + result[key] = value + end + if key == "Inform" + result.delete(key) if ! self.include_inform + end + # self.get(kind_constant, 1,0, key) # Something like this + } + result + end + end class MediaInfoLib::MediaInfo diff --git a/spec/mediainfo_spec.rb b/spec/mediainfo_spec.rb index 50abef4..6ded8df 100644 --- a/spec/mediainfo_spec.rb +++ b/spec/mediainfo_spec.rb @@ -10,49 +10,59 @@ puts "Please put some video files on spec/fixtures to test" end end + it "Can get the option definitions for a file" do + @mediainfo = MediaInfoLib::MediaInfo.new + definitions = @mediainfo.option_definitions + [:general, :audio, :video, :text, :chapters, :menu, :text, :image].each{|topic| + # All these topics should be there + definitions.keys.should include(topic) + # All these topics should have more than one item + definitions[topic].keys.length.should > 0 + } + #pp definitions + end context "When getting video files" do before(:each) do - @mediainfo = MediaInfoLib::MediaInfo.new end after(:each) do - @mediainfo.close end it "Can open local files" do @video_files.each{|video| + @mediainfo = MediaInfoLib::MediaInfo.new @mediainfo.open("#{VIDEO_FIXTURES}/#{video}").should > 0 @mediainfo.inform.length.should > 0 + @mediainfo.close } end it "Can get info from files" do @video_files.each{|video| + @mediainfo = MediaInfoLib::MediaInfo.new @mediainfo.open("#{VIDEO_FIXTURES}/#{video}").should > 0 @mediainfo.streams.should > 0 @mediainfo.streams.should < 1000 #@mediainfo.get(MediaInfoLib_StreamKind::General,1,0,MediaInfoLib_InfoKind::Name).should_not be_nil } end - it "Can get the option definitions for a file" do - definitions = @mediainfo.option_definitions - [:general, :audio, :video, :text, :chapters, :menu, :text, :image].each{|topic| - # All these topics should be there - definitions.keys.should include(topic) - # All these topics should have more than one item - definitions[topic].keys.length.should > 0 - } - #pp definitions - end it "Can get the Media Info values for a file" do @video_files.each{|video| + @mediainfo = MediaInfoLib::MediaInfo.new + puts "Reading #{video}" @mediainfo.open("#{VIDEO_FIXTURES}/#{video}").should > 0 values = @mediainfo.introspect #puts "Streams for #{video}: Video:#{@mediainfo.video_streams} Audio:#{@mediainfo.audio_streams} Image:#{@mediainfo.image_streams}" if @mediainfo.video_streams > 0 [:general, :audio, :video, :text, :chapters, :menu, :text, :image].each{|topic| values.should include(topic)} - # TODO Spot check some topics. values[:general].keys.length.should > 0 - values[:general]["CodecID"].should_not be_nil - values[:general]["CodecID"].should_not include("TODO") + values[:video][0]["Format"].should_not be_nil + values[:video][0]["Format"].should_not include("TODO") + if @mediainfo.audio_streams > 0 + values[:audio][0]["Format"].should_not be_nil + values[:audio][0]["Format"].should_not include("TODO") + end + values[:audio].length.should == @mediainfo.audio_streams + values[:video].length.should == @mediainfo.video_streams #pp values + @mediainfo.close end } end