#!/usr/bin/env ruby # encoding: utf-8 if ARGV.length < 1 puts "usage: #{$0} " exit 1 end require 'gst' Gst.init #TODO define Exceptions class Pipeline < Gst::Pipeline @@new_pipe_per_file=true @@new_pipe_per_file=false def self.pipeline if @@new_pipe_per_file new("pipeline") else @pipeline||=new("pipeline") end end attr_reader :location def initialize(name) pipeline=super @source=Gst::ElementFactory.make("filesrc", "source") raise "'filesrc' gstreamer plugin missing" if @source.nil? decodebin=Gst::ElementFactory.make("decodebin", "decode") raise "'decodebin' gstreamer plugin missing" if decodebin.nil? pipeline << @source << decodebin @source >> decodebin pipeline end def location=(file) @location=file @source.location=@location end def stop super check_state_returned(super) end def pause check_state_returned(super) end def bus (@bus||=super) || raise("Bus not found") end def tags tags=Gst::TagList.new while message=bus.pop #case message#Not working case message.type when Gst::MessageType::ERROR puts message.parse_error when Gst::MessageType::EOS puts "EOS" break when Gst::MessageType::TAG p "TAG" tags=tags.merge(message.parse_tag, Gst::TagMergeMode::KEEP) end end tags end private def check_state_returned(sret) return if sret==Gst::StateChangeReturn::SUCCESS if sret==Gst::StateChangeReturn::ASYNC return if get_state(5*Gst::SECOND).first==Gst::StateChangeReturn::SUCCESS end raise "State failed to changed" end end ARGV.each do |filename| pipeline=Pipeline.pipeline pipeline.stop pipeline.location=filename begin # Decodebin will only commit to PAUSED if it actually finds a type # otherwise the state change fails pipeline.pause tags=pipeline.tags if tags.empty? puts "No metadata found for #{filename}" else tags.each do |taglist, tag| if taglist.get_tag_size(tag)==1 puts "%-15s: %s" % [Gst.tag_get_nick(tag), taglist.get_value_index(tag, 0).value] else puts "#{tag}" end end end rescue => error puts "#{error.message} (#{filename})" next end end