Skip to content

Instantly share code, notes, and snippets.

@neotrinity
Forked from joshdoe/pyside_pygst_on_windows.py
Last active August 29, 2015 14:07
Show Gist options
  • Select an option

  • Save neotrinity/44870cac57ccba02f3ad to your computer and use it in GitHub Desktop.

Select an option

Save neotrinity/44870cac57ccba02f3ad to your computer and use it in GitHub Desktop.

Revisions

  1. @joshdoe joshdoe created this gist Aug 2, 2011.
    103 changes: 103 additions & 0 deletions pyside_pygst_on_windows.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,103 @@
    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_())