我写过这个非常简单的视频播放器,在Ruby中使用gstreamer和gtk2。
require 'gtk2'
require 'gst'
if ARGV.size != 1
puts "Usage: #{$0} <file>"
exit 0
end
class VideoWidget < Gtk::DrawingArea
def initialize(file)
super()
@playbin = Gst::ElementFactory.make('playbin2')
@video = Gst::ElementFactory.make('xvimagesink')
@video.force_aspect_ratio = true
@overlay = Gst::ElementFactory.make('textoverlay')
@overlay.text = 'Foo bar'
@playbin.text_sink = @overlay
@playbin.video_sink = @video
@playbin.audio_sink = Gst::ElementFactory.make('autoaudiosink')
@playbin.signal_connect('notify') do
@playbin.video_sink.xwindow_id = self.window.xid if self.window
@playbin.video_sink.expose
end
@playbin.uri = "file://#{File.absolute_path(file)}"
@playbin.ready
end
def play
@playbin.play
end
def pause
@playbin.pause
end
def stop
@playbin.stop
end
def seek(time)
@playbin.seek(1.0, Gst::Format::TIME,
Gst::Seek::FLAG_FLUSH | Gst::Seek::FLAG_KEY_UNIT,
Gst::Seek::TYPE_CUR, time * Gst::SECOND,
Gst::Seek::TYPE_NONE, -1);
end
end
window = Gtk::Window.new
video = VideoWidget.new(ARGV.first)
buttonbox = Gtk::HButtonBox.new
button = Gtk::Button.new(Gtk::Stock::MEDIA_PLAY)
button.signal_connect('clicked') { video.play }
buttonbox.add(button)
button = Gtk::Button.new(Gtk::Stock::MEDIA_PAUSE)
button.signal_connect('clicked') { video.pause }
buttonbox.add(button)
button = Gtk::Button.new(Gtk::Stock::MEDIA_STOP)
button.signal_connect('clicked') { video.stop }
buttonbox.add(button)
button = Gtk::Button.new(Gtk::Stock::MEDIA_REWIND)
button.signal_connect('clicked') { video.seek(-10) }
buttonbox.add(button)
button = Gtk::Button.new(Gtk::Stock::MEDIA_FORWARD)
button.signal_connect('clicked') { video.seek(10) }
buttonbox.add(button)
hbox = Gtk::HBox.new
hbox.pack_start(buttonbox, false)
vbox = Gtk::VBox.new
vbox.pack_start(video)
vbox.pack_start(hbox, false)
window.add(vbox)
window.signal_connect('destroy') do
video.stop
Gtk.main_quit
end
window.set_default_size(640, 480)
window.window_position = Gtk::Window::POS_CENTER
window.show_all
Gtk.main
它有效,但我想在视频上显示一些文字。我尝试使用gstreamer元素textoverlay
,但我没想到要在管道中链接这个元素。有人有想法吗?
答案 0 :(得分:4)
好的,我找到了解决方案:
我需要创建一个带有鬼垫的Gst bin元素:
@playbin = Gst::ElementFactory.make('playbin2')
@video = Gst::ElementFactory.make('xvimagesink')
@audio = Gst::ElementFactory.make('autoaudiosink')
@overlay = Gst::ElementFactory.make('textoverlay')
bin = Gst::Bin.new
bin.add(@overlay)
ghost_pad = Gst::GhostPad.new('sink', @overlay.get_pad('video_sink'))
bin.add_pad(ghost_pad)
bin.add(@video)
@overlay.link(@video)
@playbin.video_sink = bin
@playbin.audio_sink = @audio
@playbin.ready
@overlay.text = 'Fukc yeah!'