我有一个QML应用程序,我想将使用QMediaPlayer和QVideoWidget的C++代码集成到该应用程序中。
我知道媒体播放器在QML中是如何工作的(来自Qt的示例):
Item {
MediaPlayer {
id: mediaplayer
source: "groovy_video.mp4"
}
VideoOutput {
anchors.fill: parent
source: mediaplayer
}
MouseArea {
id: playArea
anchors.fill: parent
onPressed: mediaplayer.play();
}
}然而,我正在处理一段创建QVideoWidget的代码。我想去掉QML端的QVideoWidget,代之以我可以在C++应用程序中显示的东西。
openauto端有如下代码( C++本身是相当长的代码,它是openauto项目的一部分,这是由抽象工厂生成的C++类VideoService调用的QtVideoOutput类):
QtVideoOutput::QtVideoOutput(configuration::IConfiguration::Pointer configuration)
: VideoOutput(std::move(configuration))
{
this->moveToThread(QApplication::instance()->thread());
connect(this, &QtVideoOutput::startPlayback, this, &QtVideoOutput::onStartPlayback, Qt::QueuedConnection);
connect(this, &QtVideoOutput::stopPlayback, this, &QtVideoOutput::onStopPlayback, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "createVideoOutput", Qt::BlockingQueuedConnection);
}
void QtVideoOutput::createVideoOutput()
{
OPENAUTO_LOG(debug) << "[QtVideoOutput] create.";
videoWidget_ = std::make_unique<QVideoWidget>();
mediaPlayer_ = std::make_unique<QMediaPlayer>(nullptr, QMediaPlayer::StreamPlayback);
}
bool QtVideoOutput::open()
{
return videoBuffer_.open(QIODevice::ReadWrite);
}
bool QtVideoOutput::init()
{
emit startPlayback();
return true;
}
void QtVideoOutput::stop()
{
emit stopPlayback();
}
void QtVideoOutput::write(uint64_t, const aasdk::common::DataConstBuffer& buffer)
{
videoBuffer_.write(reinterpret_cast<const char*>(buffer.cdata), buffer.size);
}
void QtVideoOutput::onStartPlayback()
{
videoWidget_->setAspectRatioMode(Qt::IgnoreAspectRatio);
videoWidget_->setFocus();
//videoWidget_->setWindowFlags(Qt::WindowStaysOnTopHint);
videoWidget_->setFullScreen(true);
videoWidget_->show();
mediaPlayer_->setVideoOutput(videoWidget_.get()); // ???
mediaPlayer_->setMedia(QMediaContent(), &videoBuffer_);
mediaPlayer_->play();
OPENAUTO_LOG(debug) << "Player error state -> " << mediaPlayer_->errorString().toStdString();
}
void QtVideoOutput::onStopPlayback()
{
videoWidget_->hide();
mediaPlayer_->stop();
}完整代码请访问:https://github.com/matt2005/openauto
我最初的计划是在全局上下文中创建一个QQuick对象,并将其传递给QML。但我不知道该怎么做。我想请您谈谈如何在C++端摆脱videoWidget,并使其使用我在QML端可能拥有的VideoOutput / AbstractSurface:
VideoOutput {
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter;
anchors.horizontalCenter: parent.horizontalCenter;
width: 640
height: 480
source: ???
objectName: "vidout"
}我愿意提供任何额外的代码或信息,如您所需。
发布于 2021-05-01 09:09:50
取决于获取视频纹理数据的位置/方式。(从外观上看,这似乎是您的videoBuffer_)
您可以简单地基于QQuickPaintedItem创建一个VideoBufferVisualizer类,将缓冲区数据绘制到QtQuickItem的paint(QPainter *painter)方法中。教程:教程:https://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html
请注意,在嵌入式系统上,通常有更快的、零拷贝的方法将视频纹理数据直接放入OpenGL纹理/Qt快速场景图中。您可以查看https://github.com/GStreamer/gst-plugins-good/blob/master/ext/qt/gstqtsink.cc,了解gstreamer是如何做到这一点的。
https://stackoverflow.com/questions/67250330
复制相似问题