我试图让自己成为一个 QML 相机项目,它具有更多功能,并为VideoOutput元素提供源。比如这个:
VideoOutput{
source:mycamera
}
MyCustomCamera{
id:mycamera
}
Run Code Online (Sandbox Code Playgroud)
如果您要扩展自己的 C++ 类以与 VideoOutput 互操作,您可以提供一个基于 QObject 的类,该类具有一个 mediaObject 属性,该属性公开一个 QMediaObject 派生类,该类具有一个 QVideoRendererControl 可用,或者您可以提供一个基于 QObject 的类与一个可写的 videoSurface 属性可以接受基于 QAbstractVideoSurface 的类,并且可以遵循正确的协议将 QVideoFrames 传递给它。
我试过给我的对象一个私有财产 mediaObject,它是 QCamera 类型,但看起来 QCamera 没有 QVideoRenderControl (或者是我的错,不知道如何正确地做到这一点)。
我要达到我一开始的效果,反正欢迎。
或者,谁能给我一个简短的例子,说明“videoSurace接受 blablabla 并遵循正确协议的可写属性”是什么意思?
小智 8
我无法帮助您解决您主要关心的问题,但我可以给您一个 的示例用法。您可以像这样videoSurface使用“可写”:videoSurface
我的示例包含三个主要步骤:
视频适配器.h
#ifndef VIDEOADAPTER_H
#define VIDEOADAPTER_H
#include <QObject>
#include <QAbstractVideoSurface>
#include <QVideoSurfaceFormat>
#include <QTimer>
class VideoAdapter : public QObject
{
Q_OBJECT
Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface NOTIFY signalVideoSurfaceChanged)
public:
explicit VideoAdapter(QObject *parent = nullptr);
QAbstractVideoSurface *videoSurface() const;
void setVideoSurface(QAbstractVideoSurface *videoSurface);
signals:
void signalVideoSurfaceChanged();
private slots:
void slotTick();
private:
void startSurface();
private:
QAbstractVideoSurface *mVideoSurface;
QVideoSurfaceFormat *mSurfaceFormat;
QImage *mImage;
QTimer mTimer;
};
#endif // VIDEOADAPTER_H
Run Code Online (Sandbox Code Playgroud)
视频适配器.cpp
#include "videoadapter.h"
#include <QDebug>
VideoAdapter::VideoAdapter(QObject *parent)
: QObject(parent), mVideoSurface(nullptr), mSurfaceFormat(nullptr)
{
mTimer.setInterval(1000);
connect(&mTimer, &QTimer::timeout, this, &VideoAdapter::slotTick);
}
QAbstractVideoSurface *VideoAdapter::videoSurface() const
{
return mVideoSurface;
}
void VideoAdapter::setVideoSurface(QAbstractVideoSurface *videoSurface)
{
if(videoSurface != mVideoSurface)
{
mVideoSurface = videoSurface;
emit signalVideoSurfaceChanged();
startSurface();
// This is the test timer that will tick for us to present the image
// on the video surface
mTimer.start();
}
}
void VideoAdapter::slotTick()
{
QVideoFrame frame(*mImage);
mVideoSurface->present(frame);
}
void VideoAdapter::startSurface()
{
mImage = new QImage("../resources/images/test.jpg");
auto pixelFormat = QVideoFrame::pixelFormatFromImageFormat(mImage->format());
mSurfaceFormat = new QVideoSurfaceFormat(mImage->size(), pixelFormat);
if(!mVideoSurface->start(*mSurfaceFormat))
{
qDebug() << "Surface couldn't be started!";
}
}
Run Code Online (Sandbox Code Playgroud)
此类仅加载图像文件并使用计时器显示它,但在您的情况下,您将拥有一个帧源,因此您可以更改它以满足您的需要。如果您可以将框架转换为QImage您QVideoFrame可以像这样显示它。
您必须使此类在 QML 中可用。就我而言,我创建了一个对象,并通过将其设置为属性使其对 QML 可见。
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlDebuggingEnabler enabler;
VideoAdapter adapter;
// When you do this this object is made visible to QML context with the
// given name
engine.rootContext()->setContextProperty("videoAdapter", &adapter);
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);
return app.exec();
}
Run Code Online (Sandbox Code Playgroud)您将此对象作为 QML 中的源提供给 VideoOutput。
Window {
visible: true
width: 640
height: 480
color: "black"
title: qsTr("Video Player")
VideoOutput {
id: videoPlayer
anchors.fill: parent
source: videoAdapter
}
}
Run Code Online (Sandbox Code Playgroud)正如我所说,这个示例是一个简单的示例,仅加载一张图像并仅定期显示该图像。
这个问题是一个老问题,您可能会继续前进,但希望这至少可以帮助其他人。
| 归档时间: |
|
| 查看次数: |
2196 次 |
| 最近记录: |