c++传递视频流到qml 的 VideoOutput

c++传递视频流到qml 的 VideoOutput

QT官方文档里面介绍的方法 Video Overview

继承QObject,实现属性, 具有可读写videoSurface属性

Q_PROPERTY(QAbstractVideoSurface *videoSurface READ videoSurface WRITE setVideoSurface)

举例:

FrameProvider.h

#ifndef FRAMEPRODER_H
#define FRAMEPRODER_H

#include 
#include 
#include 

/*!
 * \brief FrameProvider 作为qml VideoOutput.source
 */
class FrameProvider : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QAbstractVideoSurface *videoSurface READ videoSurface WRITE setVideoSurface)


public:
    FrameProvider();
    ~FrameProvider();
    
    QAbstractVideoSurface *videoSurface() const;
    
	/*!
     * \brief 可设置外部自定义QAbstractVideoSurface
     * \param surface
     */
    void setVideoSurface(QAbstractVideoSurface *surface);

    /*!
     * \brief 设置视频格式
     * \param width     视频宽
     * \param heigth    视频高
     * \param format    enum QVideoFrame::PixelFormat
     */
    void setFormat(int width, int heigth, QVideoFrame::PixelFormat format);

public slots:
    /*!
     * \brief 接收外部数据源,视频帧
     * \param frame
     */
    void onNewVideoContentReceived(const QVideoFrame &frame);

private:
    QAbstractVideoSurface *m_surface = NULL;
    QVideoSurfaceFormat m_format;
};
#endif // FRAMEPRODER_H

FrameProvider.cpp

#include "frameproder.h"


FrameProvider::FrameProvider()
{

}

FrameProvider::~FrameProvider()
{

}

QAbstractVideoSurface *FrameProvider::videoSurface() const {
    return m_surface;
}

void FrameProvider::setVideoSurface(QAbstractVideoSurface *surface)
{
    if (m_surface && m_surface != surface  && m_surface->isActive()) {
        m_surface->stop();
    }

    m_surface = surface;

    if (m_surface && m_format.isValid())
    {
        m_format = m_surface->nearestFormat(m_format);
        m_surface->start(m_format);
    }
}

void FrameProvider::setFormat(int width, int heigth, QVideoFrame::PixelFormat format)
{
    QSize size(width, heigth);
    QVideoSurfaceFormat vsformat(size, format);
    m_format = vsformat;

    if (m_surface)
    {
        if (m_surface->isActive())
        {
            m_surface->stop();
        }
        m_format = m_surface->nearestFormat(m_format);
        m_surface->start(m_format);
    }
}

void FrameProvider::onNewVideoContentReceived(const QVideoFrame &frame)
{
    //按照视频帧设置格式
    setFormat(frame.width(),frame.height(),frame.pixelFormat());
    if (m_surface)
        m_surface->present(frame);
}

main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);


    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    foreach (const QCameraInfo &cameraInfo, cameras) {
        qDebug()<<"name: "<<cameraInfo.deviceName()<<" \n description"<<cameraInfo.description();
    }

    //相机
    QSharedPointer<QCamera> cameraPtr(new QCamera(cameras.at(0)));
    //取景器
    QSharedPointer<MyVideoSurface> surface(new MyVideoSurface);
    cameraPtr.get()->setViewfinder(qobject_cast<MyVideoSurface*>(surface.get()));

    //QWidget 视频输出界面
    //QSharedPointer videoView(new VideoOut );
    //QObject::connect(surface.get(),&MyVideoSurface::imageChanged,videoView.get(),&VideoOut::onFrameChanged);
    //videoView->setWindowTitle("QWidget Camera");
    //videoView->show();


    //qml 视频输出界面
    QSharedPointer<FrameProvider> provider( new FrameProvider());
    QObject::connect(surface.get(),&MyVideoSurface::frameChanged,provider.get(),&FrameProvider::onNewVideoContentReceived);

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("_provider",provider.get());

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);



    cameraPtr->start();

    //simple case
//    QSharedPointer cameraPtr1(new QCamera(cameras.at(1)));
//    QSharedPointer viewfinder(new QCameraViewfinder());
//    viewfinder->resize(400,400);
//    cameraPtr1->setViewfinder(viewfinder.get());
//    viewfinder->show();
//    cameraPtr1->start();

    return app.exec();
}

qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtMultimedia 5.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("qml camera")


//    Camera{
//        id:cameraDev
//        imageProcessing.whiteBalanceMode: CameraImageProcessing.WhiteBalanceFlash

//        exposure {
//            exposureCompensation: -1.0
//            exposureMode: Camera.ExposurePortrait
//        }

//        flash.mode: Camera.FlashRedEyeReduction

//    }

    VideoOutput{
        source: _provider //cameraDev
        anchors.fill: parent
        focus : visible
    }
}

你可能感兴趣的:(多媒体,QT/QML)