Skip to content

Instantly share code, notes, and snippets.

@joshdoe
Created August 2, 2011 13:56
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joshdoe/1120231 to your computer and use it in GitHub Desktop.
Save joshdoe/1120231 to your computer and use it in GitHub Desktop.
PySide (Qt) + PyGst (GStreamer) on Microsoft Windows
import sys
# needed for casting PyCObject to void pointer
from ctypes import pythonapi, c_void_p, py_object
from PySide.QtCore import *
from PySide.QtGui import *
import gobject
import pygst
pygst.require('0.10')
import gst
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.setWindowTitle('PySide+GStreamer on Microsoft Windows')
# create widgets and set properties
self.videoWidget = QWidget(self)
self.videoWidget.setMinimumSize(640, 480)
self.numBuffersSpinBox = QSpinBox()
self.numBuffersSpinBox.setMinimum(-1)
self.numBuffersSpinBox.setValue(-1)
self.button = QPushButton('Start')
# build layout
layout = QVBoxLayout()
layout.addWidget(self.videoWidget)
layout.addWidget(QLabel('num-buffers'))
layout.addWidget(self.numBuffersSpinBox)
layout.addWidget(self.button)
self.setLayout(layout)
# connect signals
self.button.clicked.connect(self.on_start_stop)
# build pipeline
self.pipeline = gst.Pipeline()
self.source = gst.element_factory_make('videotestsrc')
self.sink = gst.element_factory_make('dshowvideosink')
self.pipeline.add(self.source, self.sink)
gst.element_link_many(self.source, self.sink)
# connect sync-message from gst.Bus
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.enable_sync_message_emission()
self.bus.connect('sync-message::element', self.on_sync_message)
# create timer for checking gst.Bus messages
self.timer = QTimer()
self.timer.timeout.connect(self.on_timer)
# we can't call winId() within the streaming thread (on_sync_message)
# so we must do it here
winid = self.videoWidget.winId()
# convert winId from PyCObject to void pointer (only for PySide on
# Windows)
pythonapi.PyCObject_AsVoidPtr.restype = c_void_p
pythonapi.PyCObject_AsVoidPtr.argtypes = [py_object]
self.hWnd = pythonapi.PyCObject_AsVoidPtr(self.videoWidget.winId())
def on_start_stop(self):
if self.button.text() == 'Stop':
self.pipeline.set_state(gst.STATE_NULL)
self.button.setText('Start')
else:
self.source.props.num_buffers = self.numBuffersSpinBox.value()
self.pipeline.set_state(gst.STATE_PLAYING)
self.button.setText('Stop')
self.timer.start(30)
def on_sync_message(self, bus, message):
if message.structure is None:
return
if message.structure.get_name() == 'prepare-xwindow-id':
# enables video to play in QWidget
self.sink.set_xwindow_id(self.hWnd)
def on_timer(self):
message = self.bus.pop()
if message == None:
return
t = message.type
if t == gst.MESSAGE_EOS:
self.on_start_stop()
elif t == gst.MESSAGE_ERROR:
err, debug = message.parse_error()
QMessageBox.critical(self, self.tr('Pipeline error'),
str(err) + '\n' + debug)
self.on_start_stop()
if __name__ == '__main__':
gobject.threads_init()
app = QApplication(sys.argv)
form = Form()
form.show()
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment