You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PySide6与GStreamer接收视频流:图像无色彩且重复问题

问题:GStreamer推流在PySide6中显示色彩异常且图像重复

推流端命令

我在另一台电脑上用以下GStreamer命令推送网络摄像头视频:

gst-launch-1.0 -v v4l2src device=/dev/<video4> ! image/jpeg,width=640,height=480,framerate=30/1 ! jpegdec ! videoconvert ! x264enc bitrate=2000 speed-preset=ultrafast tune=zerolatency ref=4 qp-min=5 qp-max=10 ! rtph264pay config-interval=1 ! udpsink host=<ip_destination> port=<port_dest>

接收端GStreamer管道

在Python代码中用Gst接收流的管道如下:

self.pipeline = Gst.parse_launch("udpsrc address={ip_address} port={port} ! application/x-rtp, encoding-name=H264 ! rtph264depay ! decodebin ! videoconvert ! jpegenc ! appsink name={name}")

问题现象

将视频流处理后在PySide6中显示时,出现无色彩且重复的图像;但不使用PySide6,仅用Flask测试时显示完全正常。

完整接收端代码

import cv2
import gi
from PySide6.QtWidgets import QVBoxLayout, QWidget
from PySide6.QtCore import QTimer
from PySide6.QtGui import QImage, QPixmap
from PySide6.QtWidgets import QLabel

gi.require_version("Gst", "1.0")
from gi.repository import Gst


class VideoStreamWidget(QWidget):
    def __init__(self, port, node, parent=None):
        super(VideoStreamWidget, self).__init__(parent)
        self.node = node
        Gst.init(None)

        # 设置显示视频帧的标签
        self.video_label = QLabel(self)

        layout = QVBoxLayout()
        layout.addWidget(self.video_label)
        self.setLayout(layout)

        self.create_pipeline_gs(port)
        self.bus = self.pipeline.get_bus()
        self.bus.add_signal_watch()
        self.bus.connect("message::eos", self.on_eos)
        self.bus.connect("message::error", self.on_error)

        self.pipeline.set_state(Gst.State.PLAYING)

    def create_pipeline_gs(self, port):
        name = f"appsink{port}"
        self.pipeline = Gst.parse_launch(
            f"udpsrc address=127.0.0.1 port={port} ! application/x-rtp, encoding-name=H264 ! rtph264depay ! decodebin ! videoconvert ! jpegenc ! appsink name={name}"
        )
        self.appsink = self.pipeline.get_by_name(name)
        self.appsink.set_property('emit-signals', True)
        self.appsink.set_property('sync', False)
        self.appsink.connect("new-sample", self.on_new_sample)

    def on_new_sample(self, sink):
        sample = sink.emit("pull-sample")
        if sample:
            caps = sample.get_caps()
            buffer = sample.get_buffer()
            structure = caps.get_structure(0)
            width = structure.get_value("width")
            height = structure.get_value("height")

            success, map_info = buffer.map(Gst.MapFlags.READ)
            if success:
                image = QImage(
                    map_info.data, width, height, width * 3, QImage.Format_RGB888
                )
                pixmap = QPixmap.fromImage(image)
                self.video_label.setPixmap(pixmap)
                buffer.unmap(map_info)
        return 0

    def on_eos(self, bus, msg):
        print("流已结束")
        self.pipeline.set_state(Gst.State.NULL)

    def on_error(self, bus, msg):
        err, debug = msg.parse_error()
        print(f"错误:{err}")
        self.pipeline.set_state(Gst.State.NULL)

    def closeEvent(self, event):
        self.pipeline.set_state(Gst.State.NULL)
        event.accept()
        super(VideoStreamWidget, self).closeEvent(event)

求助

我认为问题出在将GStreamer的图像数据转换为QImage和QPixmap的过程中,但找不到具体解决方法,希望得到帮助。

内容的提问来源于stack exchange,提问作者user26714515

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 01:00:11