QT官方文档里面介绍的方法 Video Overview
继承QObject,实现属性, 具有可读写videoSurface属性
Q_PROPERTY(QAbstractVideoSurface *videoSurface READ videoSurface WRITE setVideoSurface)
举例:
#ifndef FRAMEPRODER_H #define FRAMEPRODER_H #include <QObject> #include <QAbstractVideoSurface> #include <QVideoSurfaceFormat> /*! * \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
#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); }
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<VideoOut> 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<QCamera> cameraPtr1(new QCamera(cameras.at(1))); // QSharedPointer<QCameraViewfinder> viewfinder(new QCameraViewfinder()); // viewfinder->resize(400,400); // cameraPtr1->setViewfinder(viewfinder.get()); // viewfinder->show(); // cameraPtr1->start(); return app.exec(); }
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 } }