我正试图使自己成为一个具有更多功能的QML相机项目,并为VideoOutput
元素提供源。例如:
VideoOutput{
source:mycamera
}
MyCustomCamera{
id:mycamera
}
在文档里写着
如果您正在扩展自己的c++类以与之互操作,您可以提供一个基于QObject的类属性,该属性公开QMediaObject派生类有一个可用的QVideoRendererControl,或者你可以提供一个QObject类,具有可写的videoSurface属性,该属性可以接受基于QAbstractVideoSurface的类,可以遵循正确的协议给它传送QVideoFrames
我试过给我的对象一个私有属性mediaObject
,这是QCamera类型,但看起来像QCamera没有QVideoRenderControl(或者是我的错不知道如何正确地做到这一点)。
我需要达到我在开始展示的效果,无论如何都是受欢迎的。
或者,谁能给我一个简短的例子,说明什么是"一个可写的videoSurace
属性,接受blablabla并遵循正确的协议"?
我不能帮你解决你的主要问题,但我可以给你一个videoSurface
的例子。你可以像这样使用"可写的videoSurface
":
我的例子包括三个主要步骤:
- 你写了一个类,它有一个QAbstactVideoSurface属性。这个类是你的视频提供者,它可以通过调用present()函数在VideoOutput上显示帧。
videoadapter.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
videoadapter.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!";
}
}
这个类只加载一个图像文件,并使用计时器显示它,但在你的情况下,你将有一个帧源,所以你可以改变它来满足你的需要。如果你可以将你的帧转换为QVideoFrame
的QImage
,你可以像这样显示它。
你必须使这个类在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(); }
您将此对象作为QML中的源提供给VideoOutput。
Window { visible: true width: 640 height: 480 color: "black" title: qsTr("Video Player") VideoOutput { id: videoPlayer anchors.fill: parent source: videoAdapter } }
这个例子就像我说的那样是一个简单的例子,它只加载一个图像,并且只周期性地显示这个图像。
这个问题是一个老问题,你可能已经离开了,但希望这至少能帮助到其他人。
@U。Tuken工作得很好,除非我将Q_PROPERTY中的属性名称从"videoSurface"换句话说,这行不通。这是非常奇怪的行为引起Qt的观点";videoSurface"只是一个名字。
另外,我得到了错误
"qt.gui。icc: frommiccprofile: failed minimal tag size sanity".
如果导入的"JPG"格式不正确按此链接
更改"JPG"文件帮我摆脱了上面的警告