質問

私は PyQt を使用して、Web カメラからビデオを取得して QT ウィジェット内で再生しようとしています。C と Qt、Python と gtk のチュートリアルは見つかりましたが、pyQt と gstreamer の組み合わせについては何もありませんでした。これを機能させた人はいますか?

これによりビデオは正常に再生されますが、別のウィンドウが表示されます。

self.gcam = gst.parse_launch('v4l2src device=/dev/video0 ! autovideosink')
self.gcam.set_state(gst.STATE_PLAYING)

必要なのは、オーバーレイを動作させて、GUI 上のウィジェット内に表示されるようにすることです。ありがとう、インターネットの達人!

さて、かなり遠くまで進みましたが、まだ助けが必要です。私は実際にこれを Maemo 用に書いていますが、次のコードは私の Linux ラップトップで正常に動作します。

class Vid:
    def __init__(self, windowId):
    self.player = gst.Pipeline("player")
    self.source = gst.element_factory_make("v4l2src", "vsource")
    self.sink = gst.element_factory_make("autovideosink", "outsink")
    self.source.set_property("device", "/dev/video0")
    self.scaler = gst.element_factory_make("videoscale", "vscale")
    self.window_id = None
    self.windowId = windowId

    self.player.add(self.source, self.scaler, self.sink)
    gst.element_link_many(self.source,self.scaler, self.sink)

    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 on_message(self, bus, message):
    t = message.type
    if t == gst.MESSAGE_EOS:
        self.player.set_state(gst.STATE_NULL)
    elif t == gst.MESSAGE_ERROR:
       err, debug = message.parse_error()
       print "Error: %s" % err, debug
       self.player.set_state(gst.STATE_NULL)

    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":
        win_id = self.windowId
        assert win_id
        imagesink = message.src
        imagesink.set_property("force-aspect-ratio", True)
        imagesink.set_xwindow_id(win_id)
    def startPrev(self):
    self.player.set_state(gst.STATE_PLAYING)
    print "should be playing"
vidStream = Vid(wId)
vidStream.startPrev()

ここで、wId は、出力を表示しようとしているウィジェットのウィンドウ ID です。これを N900 で実行すると、画面が真っ暗になって点滅します。何か案は?ここで死ぬんだ!

編集:完全なコードを投稿するように求められました。まだ少し整理する必要がありますが、関連する部分は次のとおりです。

self.cameraWindow = QtGui.QWidget(self)
self.cameraWindow.setGeometry(QtCore.QRect(530, 20, 256, 192))
self.cameraWindow.setObjectName("cameraWindow")
self.cameraWindow.setAttribute(0, 1); # AA_ImmediateWidgetCreation == 0
self.cameraWindow.setAttribute(3, 1); # AA_NativeWindow == 3

global wId
wId = self.cameraWindow.winId()

self.camera = Vid(wId)

self.camera.startPrev()

class Vid:
    def __init__(self, windowId):
    self.player = gst.Pipeline("player")
    self.source = gst.element_factory_make("v4l2src", "vsource")
    self.sink = gst.element_factory_make("autovideosink", "outsink")
    self.source.set_property("device", "/dev/video0")
    #self.scaler = gst.element_factory_make("videoscale", "vscale")
    self.fvidscale = gst.element_factory_make("videoscale", "fvidscale")
    self.fvidscale_cap = gst.element_factory_make("capsfilter", "fvidscale_cap")
    self.fvidscale_cap.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=256, height=192'))
    self.window_id = None
    self.windowId = windowId
    print windowId

    self.player.add(self.source, self.fvidscale, self.fvidscale_cap, self.sink)
    gst.element_link_many(self.source,self.fvidscale, self.fvidscale_cap, self.sink)

    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 on_message(self, bus, message):
    t = message.type
    if t == gst.MESSAGE_EOS:
        self.player.set_state(gst.STATE_NULL)
    elif t == gst.MESSAGE_ERROR:
       err, debug = message.parse_error()
       print "Error: %s" % err, debug
       self.player.set_state(gst.STATE_NULL)

    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":
        win_id = self.windowId
        assert win_id
        imagesink = message.src
        imagesink.set_property("force-aspect-ratio", True)
        imagesink.set_xwindow_id(win_id)
    def startPrev(self):
    self.player.set_state(gst.STATE_PLAYING)
    def pausePrev(self):
    self.player.set_state(gst.STATE_NULL)

これはいくつかの部分をつなぎ合わせたもので、今はテストできませんが、もしかしたら誰かの役に立つかもしれません。幸運を!

役に立ちましたか?

解決 2

は、それを手に入れました!

:私が私がビデオをポンピングされたウィジェットの解像度に合わせてパイプラインの解像度を強制するために必要な表示されます

self.fvidscale_cap = gst.element_factory_make( "capsfilter"、 "fvidscale_cap") self.fvidscale_cap.set_property(gst.caps_from_string 'キャップ'、( 'ビデオ/ X-RAW-YUV、幅= 256、高さ= 192'))

それからちょうど他の要素のようなパイプラインにそれらを追加し、それは素晴らしい作品。男は、それはそう簡単に今それを見ているようだが、私はそれはとても明らかではなかった数日間、壁に頭を叩いたとき...

他のヒント

Linux 以外のプラットフォームで PyQt の代わりに PySide を使用している場合、winId() は PyCObject を返します。 ネイティブ関数や他のモジュールでは直接使用できません. 。私の場合、これは Microsoft Windows 上の PySide で GStreamer (pygst) を使用するときに便利でした。

from ctypes import pythonapi, c_void_p, py_object
...
if message_name == 'prepare-xwindow-id':
    # convert winId from PyCObject to void pointer
    pythonapi.PyCObject_AsVoidPtr.restype = c_void_p
    pythonapi.PyCObject_AsVoidPtr.argtypes = [py_object]
    hWnd = pythonapi.PyCObject_AsVoidPtr(self.videoWidget.winId())

    # set window handle to video sink
    self.videoSink.set_xwindow_id(hWnd)

Ptterb、あなたの完全なコードを投稿することができますしてください?

私はあなたのコードをコピーした。
で、パイプラインに追加されましたfvidscale_capます:

self.player.add(self.source, self.scaler, self.fvidscale_cap, self.sink)
gst.element_link_many(self.source,self.scaler, self.fvidscale_cap, self.sink)

は、メインプログラムから私は新しいのQWidgetを作成し、ヴィドのコンストラクタにそのwinIdを()に渡します。
ロードが、クラッシュを開始ウィジェットます。

出力は述べています。

をプレイする必要があります セグメンテーションフォールト

貼り付けたコードが却下することができないGObjectの負荷を、表示されません。 欠けていたかを把握する一方、それは私にいいました。 6月を持ってくれてありがとう 作業オーディオ例ます。

import gobject, pygst
pygst.require('0.10')
import gst
from PyQt4.QtGui import QMainWindow, QWidget, QApplication 
import sys

class Video(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        container = QWidget()
        self.setCentralWidget(container)
        self.windowId = container.winId()
        self.setGeometry(300,300,640,480)
        self.show()

    def setUpGst(self):
        self.player = gst.Pipeline("player")
        source = gst.element_factory_make("v4l2src", "vsource")
        sink = gst.element_factory_make("xvimagesink", "sink")
        fvidscale_cap = gst.element_factory_make("capsfilter", "fvidscale_cap")
        fvidscale = gst.element_factory_make("videoscale", "fvidscale")
        caps = gst.caps_from_string('video/x-raw-yuv')
        fvidscale_cap.set_property('caps', caps)
        source.set_property("device", "/dev/video0")

        self.player.add(source, fvidscale, fvidscale_cap, sink)
        gst.element_link_many(source,fvidscale, fvidscale_cap, sink)
        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 on_message(self, bus, message):
        t = message.type
        if t == gst.MESSAGE_EOS:
            self.player.set_state(gst.STATE_NULL)
            print "end of message"
        elif t == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
            self.player.set_state(gst.STATE_NULL)

    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":
            win_id = self.windowId
            assert win_id
            imagesink = message.src
            imagesink.set_xwindow_id(win_id)

    def startPrev(self):
        self.player.set_state(gst.STATE_PLAYING)
        print "should be playing"

if __name__ == "__main__":
    gobject.threads_init()
    app = QApplication(sys.argv)
    video = Video()
    video.setUpGst()
    video.startPrev()
    sys.exit(app.exec_())
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top