2011-09-04 2 views
2

GStreamer로 작업하려고합니다.GStreamer 및 Theora

#!/usr/bin/env python 

import sys, os 
import pygtk, gtk, gobject 
import pygst 
pygst.require("0.10") 
import gst 

class GTK_Main: 

    def __init__(self): 
     window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     window.set_title("Mpeg2-Player") 
     window.set_default_size(500, 400) 
     window.connect("destroy", gtk.main_quit, "WM destroy") 
     vbox = gtk.VBox() 
     window.add(vbox) 
     hbox = gtk.HBox() 
     vbox.pack_start(hbox, False) 
     self.entry = gtk.Entry() 
     hbox.add(self.entry) 
     self.button = gtk.Button("Start") 
     hbox.pack_start(self.button, False) 
     self.button.connect("clicked", self.start_stop) 
     self.movie_window = gtk.DrawingArea() 
     vbox.add(self.movie_window) 
     window.show_all() 

     self.player = gst.Pipeline("player") 
     source = gst.element_factory_make("filesrc", "file-source") 
     demuxer = gst.element_factory_make("oggdemux", "demuxer") 
     demuxer.connect("pad-added", self.demuxer_callback) 
     self.video_decoder = gst.element_factory_make("theoradec", "video-decoder") 
     self.audio_decoder = gst.element_factory_make("mad", "audio-decoder") 
     audioconv = gst.element_factory_make("audioconvert", "converter") 
     audiosink = gst.element_factory_make("autoaudiosink", "audio-output") 
     videosink = gst.element_factory_make("autovideosink", "video-output") 
     self.queuea = gst.element_factory_make("queue", "queuea") 
     self.queuev = gst.element_factory_make("queue", "queuev") 
     colorspace = gst.element_factory_make("ffmpegcolorspace", "colorspace") 

     self.player.add(source, demuxer, self.video_decoder, self.audio_decoder, audioconv, 
      audiosink, videosink, self.queuea, self.queuev, colorspace) 
     gst.element_link_many(source, demuxer) 
     gst.element_link_many(self.queuev, self.video_decoder, colorspace, videosink) 
     gst.element_link_many(self.queuea, self.audio_decoder, audioconv, audiosink) 

     bus = self.player.get_bus() 
     bus.add_signal_watch() 
     bus.enable_sync_message_emission() 
     bus.connect("message", self.on_message) 
     bus.connect("sync-message::element", self.on_sync_message) 

    def start_stop(self, w): 
     if self.button.get_label() == "Start": 
      filepath = self.entry.get_text() 
      if os.path.isfile(filepath): 
       self.button.set_label("Stop") 
       self.player.get_by_name("file-source").set_property("location", filepath) 
       self.player.set_state(gst.STATE_PLAYING) 
     else: 
      self.player.set_state(gst.STATE_NULL) 
      self.button.set_label("Start") 

    def on_message(self, bus, message): 
     t = message.type 
     if t == gst.MESSAGE_EOS: 
      self.player.set_state(gst.STATE_NULL) 
      self.button.set_label("Start") 
     elif t == gst.MESSAGE_ERROR: 
      err, debug = message.parse_error() 
      print "Error: %s" % err, debug 
      self.player.set_state(gst.STATE_NULL) 
      self.button.set_label("Start") 

    def on_sync_message(self, bus, message): 
     if message.structure is None: 
      return 
     message_name = message.structure.get_name() 
     if message_name == "prepare-xwindow-id": 
      imagesink = message.src 
      imagesink.set_property("force-aspect-ratio", True) 
      gtk.gdk.threads_enter() 
      imagesink.set_xwindow_id(self.movie_window.window.xid) 
      gtk.gdk.threads_leave() 

    def demuxer_callback(self, demuxer, pad): 
     if pad.get_property("template").name_template == "video_%02d": 
      qv_pad = self.queuev.get_pad("sink") 
      pad.link(qv_pad) 
     elif pad.get_property("template").name_template == "audio_%02d": 
      qa_pad = self.queuea.get_pad("sink") 
      pad.link(qa_pad) 

GTK_Main() 
gtk.gdk.threads_init() 
gtk.main() 

나는 시도하고 .ogv 파일을 재생할 때 다음과 같은 오류를 받고 있어요 : 나는 나에게 다음 코드를 제공하는 튜토리얼 (http://pygstdocs.berlios.de/pygst-tutorial/pipeline.html를) 다음과 같은거야.

videotest.py:88: Warning: g_object_set_qdata: assertion `G_IS_OBJECT (object)' failed if pad.get_property("template").name_template == "video_%02d": Traceback (most recent call last): File "videotest.py", line 88, in demuxer_callback if pad.get_property("template").name_template == "video_%02d": AttributeError: 'NoneType' object has no attribute 'name_template' Traceback (most recent call last): File "videotest.py", line 88, in demuxer_callback if pad.get_property("template").name_template == "video_%02d": AttributeError: 'NoneType' object has no attribute 'name_template'

정말 비디오를 재생할 수 있어야합니다. 이 문제를 어떻게 해결할 수 있습니까?

+0

자습서에 대한 링크를 추가 할 수 있습니까? demuxer_callback 함수가 왜 그렇게 보이는지 이해하고 싶습니다. – xubuntix

답변

2

패드 유형을 템플릿 이름으로 결정하는 것이 항상 신뢰할 수있는 것은 아니기 때문에 템플릿 이름을 사용하는 것이 신뢰할 수 없습니다.

기능을 확인하는 것이 좋습니다. 차이점은 다음과 같습니다.

@@ -85,10 +85,11 @@ 
      gtk.gdk.threads_leave() 

    def demuxer_callback(self, demuxer, pad): 
-  if pad.get_property("template").name_template == "video_%02d": 
+  typ = pad.get_caps()[0].get_name() 
+  if typ.startswith("video"): 
      qv_pad = self.queuev.get_pad("sink") 
      pad.link(qv_pad) 
-  elif pad.get_property("template").name_template == "audio_%02d": 
+  elif typ.startswith("audio"): 
      qa_pad = self.queuea.get_pad("sink") 
      pad.link(qa_pad) 
+0

이 코드는 내 프로젝트와 관련성이 없지만 코드를 개선했지만 답변을 수락하고이 질문을 폐회합니다. 고맙습니다! – CodeMouse92

관련 문제