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

Qt中能否不使用QML Multimedia组件,仅通过QVideoSink播放视频?

无需QML Multimedia组件,使用QVideoSink实现Qt视频播放

完全可以脱离QML的Video/VideoOutput组件,仅通过Qt C++ API结合QVideoSink实现视频播放,核心是在C++层处理视频帧并渲染到Widget,适配不支持QML Multimedia的设备。

实现步骤

  • 1. 搭建视频源
    使用Qt C的QMediaPlayer和QMediaCaptureSession加载视频(这部分属于Qt Multimedia的C模块,和QML组件相互独立),示例代码:

    QMediaPlayer *player = new QMediaPlayer(this);
    QMediaCaptureSession *captureSession = new QMediaCaptureSession(this);
    captureSession->setPlayer(player);
    // 加载本地视频文件
    player->setSource(QUrl::fromLocalFile("/path/to/your/video.mp4"));
    
  • 2. 绑定QVideoSink接收帧数据
    创建QVideoSink实例并关联到QMediaCaptureSession,用于接收视频帧:

    QVideoSink *videoSink = new QVideoSink(this);
    captureSession->setVideoSink(videoSink);
    
  • 3. 自定义Widget渲染视频帧
    实现一个继承自QWidget的自定义组件,在videoFrameChanged信号触发时转换视频帧为QImage,并在paintEvent中绘制:

    class VideoDisplayWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit VideoDisplayWidget(QWidget *parent = nullptr) : QWidget(parent) {}
    
    public slots:
        void handleVideoFrame(const QVideoFrame &frame) {
            if (!frame.isValid()) return;
    
            QVideoFrame frameClone = frame;
            if (!frameClone.map(QVideoFrame::ReadOnly)) return;
    
            // 转换视频帧为QImage
            const QImage image(frameClone.bits(),
                               frameClone.width(),
                               frameClone.height(),
                               frameClone.bytesPerLine(),
                               QVideoFrame::imageFormatFromPixelFormat(frameClone.pixelFormat()));
            m_displayImage = image.copy();
            frameClone.unmap();
    
            update(); // 触发重绘
        }
    
    protected:
        void paintEvent(QPaintEvent *) override {
            QPainter painter(this);
            if (!m_displayImage.isNull()) {
                // 自适应Widget尺寸绘制
                painter.drawImage(rect(), m_displayImage, m_displayImage.rect());
            }
        }
    
    private:
        QImage m_displayImage;
    };
    
    // 关联信号与槽
    connect(videoSink, &QVideoSink::videoFrameChanged,
            videoDisplayWidget, &VideoDisplayWidget::handleVideoFrame);
    
  • 4. 启动播放
    调用QMediaPlayer的播放接口即可开始视频输出:

    player->play();
    

注意事项

  • 确认目标设备支持Qt Multimedia的C++ API(多数情况下,即使不支持QML Multimedia组件,C++层API仍可正常运行)。
  • 若需自定义视频源(如自行解码视频文件、获取摄像头流),可直接构造QVideoFrame并调用QVideoSink::setVideoFrame()传递帧数据。
  • 视频帧格式转换时需注意像素格式匹配,避免出现花屏、色彩异常等问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:43:35