一、Qt 6多媒体模块的转变与升级
Qt 6 是一个有意识地努力使框架更有效和易于使用的结果。尽管我们试图在每个版本中维持所有公共API的二进制和源代码兼容性,但为了使Qt成为一个更好的框架,一些改变是不可避免的。
Qt 6的Qt Multimedia模块替换了Qt 5.x的Qt Multimedia模块。使用Qt 5的Qt Multimedia的现有代码可以通过有限的努力进行移植。
Qt 6的新功能包括:
- QMediaCaptureSession类是媒体捕获的中心对象。
- QMediaRecorder类现在是一个仅限于录制音频和视频的类。它处理在捕获会话中产生的数据的编码。
- 使用QMediaFormat和QMediaRecorder,设置录制时所需的编码已经发生了显著的变化。
- 现在你也可以监控捕获会话录制的音频。
- 当播放媒体文件时,已经添加了选择音频、视频和字幕轨道的支持。
- QAudioDecoder现在在所有平台上都得到支持。
被移除的功能包括:
- QMediaPlayer中的播放列表:Qt 6中的QMediaPlayer不再处理任何播放列表。
- QMediaPlayList:这个类已经从API中移除。然而,它仍然作为媒体播放器示例的一部分存在。
- QAudioProbe和QVideoProbe:音频和视频探测API已经被移除。
- QAudioRecorder:使用QMediaCaptureSession或CaptureSession QML类型。
- Audio QML类型:使用MediaPlayer QML类型。
- QMediaObject和QMediaBindableInterface:这些类已经被移除,以支持使用例如setVideoOutput和QMediaCaptureSession的更直接的API来设置对象之间的连接。
- QCameraViewFinderSettings:这个类已经被移除。使用QCameraFormat来定义相机应该使用的分辨率和帧率。
- QMediaContent:这个类已经被移除。对于单个媒体文件,使用QUrl代替。
- QSound:使用QSoundEffect代替。
- QVideoFilterRunnable:在QML中使用着色器效果,或者在C++中访问QVideoFrame的内容。
- 公共后端API:Qt 6的Qt Multimedia的后端API是私有的。这提高了支持新的多媒体用例的响应时间。在Qt 5中,任何包含“Control”或“Abstract”这些词的类名的类在Qt 6中现在都是私有的。
- 后端插件:Qt 6的Qt Multimedia不再使用插件基础设施来处理其后端。这意味着用户不再需要将这些后端与他们的应用程序一起发布。相反,正在使用的后端是在编译时基于底层操作系统确定
QVideoSink类代表了视频数据的通用接收器。QVideoSink可以用来从Qt Multimedia逐帧检索视频数据。
QVideoSink将通过videoFrameChanged()信号向应用程序开发者提供单个视频帧。然后可以使用视频帧来读取这些帧的数据并进一步处理它们。当使用QPainter时,可以使用QVideoSink中的paint()方法绘制QVideoFrame。
QVideoFrame对象可能会消耗大量的内存或系统资源,因此应用程序不应该比所需的时间更长地保留它们。
QVideoSink类的属性包括:
- subtitleText:返回当前的字幕文本。
- videoSize:返回当前正在播放的视频的大小。如果没有视频正在播放,此方法返回一个无效的大小。
QVideoSink类的成员函数包括:
- QVideoSink::QVideoSink(QObject *parent = nullptr):构造一个新的QVideoSink对象,带有parent。
- [virtual] QVideoSink::~QVideoSink():销毁对象。
- void QVideoSink::setSubtitleText(const QString &subtitle):设置当前的字幕文本。
- void QVideoSink::setVideoFrame(const QVideoFrame &frame):设置当前的视频帧。
- QVideoFrame QVideoSink::videoFrame() const:返回当前的视频帧。
QVideoSink类的信号包括:
- [signal] void QVideoSink::videoFrameChanged(const QVideoFrame &frame) const:当视频帧改变时发出信号。
1.1 Qt 6多媒体模块的分类变化
在Qt 6中,多媒体模块的分类发生了显著的变化。在Qt 5.x中,多媒体模块被视为基础模块,而在Qt 6中,它被重新分类为附加模块。这种变化是Qt团队为了提高框架的效率和易用性而做出的有意识的努力的结果。
在Qt 5.x中,多媒体模块是一个基础模块,它提供了一套完整的多媒体功能,包括音频和视频的播放、录制、处理等。然而,这种设计在一些情况下可能会导致不必要的复杂性和冗余。例如,对于一些只需要基本音频功能的应用,可能不需要视频相关的功能,但在Qt 5.x中,这些功能仍然会被包含在内,这可能会导致应用的体积过大和性能下降。
为了解决这个问题,Qt 6将多媒体模块重新分类为附加模块。这意味着,开发者现在可以根据自己的需求选择是否使用多媒体模块,而不是像在Qt 5.x中那样,无论是否需要,都必须包含多媒体模块。这种变化使得Qt 6更加灵活,也更加符合实际开发需求。
此外,Qt 6的多媒体模块也进行了大规模的重构,使其更加高效和易用。例如,Qt 6引入了新的QMediaCaptureSession类,这是媒体捕获的中心对象。而在Qt 5.x中,媒体捕获的功能分散在多个类中,如QAudioRecorder和QVideoRecorder等,这可能会导致开发者在使用时感到困惑。而在Qt 6中,所有的媒体捕获功能都集中在QMediaCaptureSession类中,这使得开发者可以更加方便地进行媒体捕获相关的操作。
以下是一个使用QMediaCaptureSession进行媒体捕获的简单示例:
QMediaCaptureSession session;
QCamera camera;
QMediaRecorder recorder;// 设置相机
session.setCamera(&camera);
// 设置录制器
session.setRecorder(&recorder);
// 开始捕获
session.start();
这个示例展示了如何使用QMediaCaptureSession进行媒体捕获。
1.2 从Qt 5到Qt 6的迁移
Qt 6的多媒体模块是对Qt 5的多媒体模块的替代。尽管在这个过程中,一些API发生了变化,但是大部分的代码都可以通过有限的努力进行迁移。
例如,如果你在Qt 5中使用了QMediaPlayer类,那么在Qt 6中,你可以使用新的QMediaCaptureSession类来替代。虽然这两个类的名称和一些方法有所不同,但是它们的功能和用法是非常相似的。你只需要对你的代码进行一些小的修改,就可以完成从Qt 5到Qt 6的迁移。
// Qt 5
QMediaPlayer *player = new QMediaPlayer;
player->setMedia(QUrl("http://example.com/myfile.mp3"));
player->play();// Qt 6
QMediaCaptureSession *session = new QMediaCaptureSession;
QMediaPlayer *player = new QMediaPlayer;
session->setPlayer(player);
player->setSource(QUrl("http://example.com/myfile.mp3"));
player->play();
以上代码示例展示了如何从Qt 5迁移到Qt 6。在Qt 5中,我们创建了一个QMediaPlayer对象,并设置了媒体源,然后播放。而在Qt 6中,我们首先创建了一个QMediaCaptureSession对象,然后创建了一个QMediaPlayer对象,并将其设置为session的播放器,然后设置媒体源,最后播放。可以看到,虽然Qt 6的代码稍微复杂一些,但是它提供了更多的
控制和灵活性。
此外,Qt 6的多媒体模块还提供了一些新的特性,比如QMediaFormat和QMediaRecorder,这些新的特性使得设置和控制媒体的编码变得更加方便和高效。
// Qt 6
QMediaCaptureSession *session = new QMediaCaptureSession;
QMediaRecorder *recorder = new QMediaRecorder;
session->setRecorder(recorder);QMediaFormat format = recorder->audioSettings().format();
format.setCodec(QMediaFormat::AAC);
recorder->audioSettings().setFormat(format);recorder->setOutputLocation(QUrl("file:///home/user/myfile.aac"));
recorder->record();
在上述代码示例中,我们首先创建了一个QMediaCaptureSession对象和一个QMediaRecorder对象,并将recorder设置为session的录音机。然后,我们获取recorder的音频设置的格式,并将编码设置为AAC。最后,我们设置了输出位置,并开始录音。这个例子展示了如何使用Qt 6的新特性来控制媒体的编码。
总的来说,从Qt 5迁移到Qt 6虽然需要一些工作,但是Qt 6提供了更多的特性和更大的灵活性,这使得这个迁移过程是值得的。
1.3 Qt 6多媒体模块的重构
在Qt 6中,多媒体模块经过了大规模的重构。这个重构的目的是为了使Qt成为一个更好的框架,提供更高效和易用的API。
在重构过程中,一些类和方法被移除,一些新的类和方法被引入。例如,QMediaObject和QMediaBindableInterface这两个类被移除,取而代之的是更直接的API,如setVideoOutput和QMediaCaptureSession。这些变化使得在Qt 6中设置对象之间的连接变得更加直接和简单。
此外,Qt 6的多媒体模块不再使用插件架构。这意味着用户不再需要将这些后端插件与他们的应用程序一起发布。相反,正在使用的后端是在编译时根据底层操作系统确定的。例如,Qt在Linux上使用gstreamer,在Windows上使用WMF,在macOS和iOS上使用AVFoundation,在Android上使用Android多媒体API。
这个重构使得Qt 6的多媒体模块更加高效,更加易用,也更加符合实际的应用需求。虽然这个重构带来了一些变化,但是这些变化都是为了使Qt成为一个更好的框架
二、Qt 6多媒体模块的新特性(New Features in Qt 6 Multimedia Module)
2.1 QMediaCaptureSession类的引入(Introduction of QMediaCaptureSession Class)
在Qt 6多媒体模块中,引入了一个新的类:QMediaCaptureSession。这个类是媒体捕捉的中心对象,它为开发者提供了一个统一的接口,用于管理和控制媒体捕捉的过程。
在Qt 5中,媒体捕捉的过程需要通过多个不同的类进行管理,如QCamera、QAudioRecorder等。这种设计虽然灵活,但也使得代码的复杂度增加,对于开发者来说,需要花费更多的精力去理解和使用这些类。
而在Qt 6中,QMediaCaptureSession类的引入,使得媒体捕捉的过程变得更加简洁和直观。开发者只需要创建一个QMediaCaptureSession对象,然后通过其提供的方法,就可以轻松地进行媒体捕捉。
Qt 6的QMediaCaptureSession类中,并没有直接提供start方法。实际上,开启捕捉的操作是通过设置好各个组件(如QCamera、QMediaRecorder等),然后调用这些组件自身的start方法来实现的。我在这里向您道歉,对此造成的误解表示歉意。
在Qt 6中,QMediaCaptureSession类主要的作用是提供一个统一的接口,用于管理和控制媒体捕捉的过程。具体的媒体捕捉操作,如开启和停止捕捉,还是需要通过各个组件自身的方法来进行。
例如,如果我们想要进行视频捕捉,我们可以先创建一个QCamera对象和一个QMediaRecorder对象,然后通过QMediaCaptureSession的setCamera和setRecorder方法,将这两个对象关联到QMediaCaptureSession上。然后,我们可以调用QCamera的start方法来开启摄像头,调用QMediaRecorder的start方法来开始录制视频。
以下是一个简单的示例:
QMediaCaptureSession session;
QCamera camera;
QMediaRecorder recorder;// 设置摄像头
session.setCamera(&camera);// 设置媒体记录器
session.setRecorder(&recorder);// 开启摄像头
camera.start();// 开始录制
recorder.record();
2.2 QMediaRecorder类的变化与应用(Changes and Applications of QMediaRecorder Class)
在Qt 6的多媒体模块中,QMediaRecorder类经历了一些重要的变化。在Qt 5中,QMediaRecorder类的功能相对复杂,它不仅负责录制音频和视频,还负责处理数据的编码。然而,在Qt 6中,QMediaRecorder类的功能被限制为仅录制音频和视频,数据的编码工作则由QMediaCaptureSession类负责。
这种变化使得QMediaRecorder类的职责更加明确,也使得代码的结构更加清晰。开发者可以更加方便地使用QMediaRecorder类进行音频和视频的录制。
QMediaRecorder类是用于对QMediaCaptureSession中生成的媒体进行编码和录制的类。:
QMediaCaptureSession session;
QAudioInput audioInput;
session.setAudioInput(&input);
QMediaRecorder recorder;
session.setRecorder(&recorder);
recorder.setQuality(QMediaRecorder::HighQuality);
recorder.setOutputLocation(QUrl::fromLocalFile("test.mp3"));
recorder.record();
可以看到,通过QMediaRecorder类,我们可以更加方便地进行音频和视频的录制。这是Qt 6多媒体模块的一个重要新特性,它将帮助开发者更加高效地开发媒体相关的应用。
2.3 QMediaFormat和QMediaRecorder的新应用(New Applications of QMediaFormat and QMediaRecorder)
在Qt 6的多媒体模块中,QMediaFormat和QMediaRecorder的使用方式发生了重大变化。在Qt 5中,设置录制的编码格式需要通过字符串来指定,这种方式虽然灵活,但也容易出错。而在Qt 6中,设置编码格式的方式变得更加直观和安全,我们可以通过枚举值来指定编码格式,这大大减少了出错的可能性。
QMediaFormat类在Qt 6中被引入,它提供了一种统一的方式来表示媒体的格式。通过QMediaFormat,我们可以方便地设置和获取媒体的编码格式、采样率、比特率等信息。
以下是一个使用QMediaFormat和QMediaRecorder进行录制设置的示例:
QMediaCaptureSession session;
QCamera camera;
QMediaRecorder recorder;// 设置摄像头
session.setCamera(&camera);// 设置媒体记录器
session.setRecorder(&recorder);// 创建一个媒体格式对象
QMediaFormat format(QMediaFormat::MP4);// 设置音频编码格式为AAC
format.setAudioCodec(QMediaFormat::AAC);// 设置视频编码格式为H264
format.setVideoCodec(QMediaFormat::H264);// 将媒体格式应用到记录器
recorder.setEncodingFormat(format);// 开始录制
recorder.record();
在这个示例中,我们首先创建了一个QMediaFormat对象format
,并设置其文件格式为MP4。然后,我们通过setAudioCodec
和setVideoCodec
方法,设置了音频编码格式为AAC和视频编码格式为H264。接着,我们通过setEncodingFormat
方法,将这个媒体格式应用到了记录器。最后,调用record
方法,开始进行录制。
可以看到,通过QMediaFormat和QMediaRecorder,我们可以更加方便和安全地进行录制设置。这是Qt 6多媒体模块的一个重要新特性,它将帮助开发者更加高效地开发媒体相关的应用。
三、 Qt 6多媒体模块的移除特性(Removed Features in Qt 6 Multimedia Module)
3.1 QMediaPlayer的播放列表助手QMediaPlayList类移除
QMediaPlayer
并不是Qt6新加的类,它在早期的Qt版本中就已经存在。这个类主要用于播放音频和视频文件,它提供了播放、暂停、停止等基本的媒体播放控制,以及获取媒体信息(如时长、状态等)的功能。
然而,QMediaPlayer
本身并不直接支持播放列表(playlist)功能,这在Qt5中是由QMediaPlaylist
类提供的。在Qt6中,QMediaPlaylist
类已经被移除,Qt6并没有直接提供一个替代的类来支持播放列表功能。
如果你需要在Qt6中实现播放列表功能,你可能需要自己管理一个媒体URL列表,并在当前媒体播放结束后,通过QMediaPlayer
的setMedia()
或setSource()
方法来设置下一个要播放的媒体。你可以通过连接QMediaPlayer
的mediaStatusChanged
信号,并在媒体状态变为QMediaPlayer::EndOfMedia
时切换到下一个媒体,以实现播放列表的功能。
以下是一个简单的示例,说明你可能如何做到这一点:
#include <QMediaPlayer>
#include <QMediaContent>
#include <QList>class MyPlayer : public QObject
{Q_OBJECTpublic:MyPlayer(QObject *parent = nullptr): QObject(parent), m_player(new QMediaPlayer(this)){connect(m_player, &QMediaPlayer::stateChanged, this, &MyPlayer::onStateChanged);}void setPlaylist(const QList<QUrl> &urls){m_playlist = urls;}void play(){if (!m_playlist.isEmpty()){m_player->setMedia(QMediaContent(m_playlist.first()));m_player->play();}}private slots:void onStateChanged(QMediaPlayer::State state){if (state == QMediaPlayer::StoppedState && !m_playlist.isEmpty()){m_playlist.removeFirst();if (!m_playlist.isEmpty()){m_player->setMedia(QMediaContent(m_playlist.first()));m_player->play();}}}private:QMediaPlayer *m_player;QList<QUrl> m_playlist;
};
在这个例子中,我们创建了一个新的类MyPlayer
,用于管理媒体文件的播放列表。setPlaylist
方法用于设置播放列表。play
方法开始播放播放列表中的第一个媒体文件。当QMediaPlayer
对象将其状态更改为StoppedState
时,意味着当前媒体文件已经播放完毕。在这种情况下,我们从播放列表中移除第一个媒体文件,并开始播放下一个。
请注意,这只是一个非常基础的例子。根据你的需求,你可能想要添加更多的功能,如随机播放、重复播放等。
3.2 QAudioProbe和QVideoProbe的移除(Removal of QAudioProbe and QVideoProbe)
在Qt 6中,QAudioProbe
和QVideoProbe
被移除了。根据Qt 6的多媒体变化文档,这两个类的功能已经被其他方式替代:
-
QAudioProbe
:在Qt 6中,你可以使用QMediaCaptureSession
或CaptureSession
QML类型来替代QAudioProbe
。你现在也可以监控捕获会话录制的音频。 -
QVideoProbe
:在Qt 6中,QVideoProbe
的功能可以通过使用QMediaCaptureSession
或CaptureSession
QML类型,或者通过在C++中访问QVideoFrame
的内容来实现。
这些变化是为了使Qt成为一个更高效、易于使用的框架。虽然在每个版本中都试图保持所有公共API的二进制和源代码的兼容性,但为了使Qt成为一个更好的框架,一些变化是不可避免的。
QAudioProbe替代方案
在Qt 6中,QAudioProbe
和QVideoProbe
被移除了。取而代之的是QMediaCaptureSession
类,它是媒体捕获的中心对象。下面是一个使用QMediaCaptureSession
的简单示例:
#include <QMediaCaptureSession>
#include <QMediaRecorder>
#include <QCamera>// 创建一个媒体捕获会话
QMediaCaptureSession *captureSession = new QMediaCaptureSession;// 创建一个媒体录制器
QMediaRecorder *recorder = new QMediaRecorder;// 将录制器添加到捕获会话
captureSession->setRecorder(recorder);// 创建一个摄像头对象
QCamera *camera = new QCamera;// 将摄像头添加到捕获会话
captureSession->setCamera(camera);// 开始摄像头
camera->start();// 开始录制
recorder->record();
在这个示例中,我们创建了一个QMediaCaptureSession对象,然后创建了一个QMediaRecorder对象和一个QCamera对象。我们将这两个对象添加到了捕获会话中,然后分别启动了摄像头和录制器。
QVideoProbe替代方案
在Qt 6中,QVideoProbe
的功能可以通过使用QMediaCaptureSession
或CaptureSession
QML类型,或者通过在C++中访问QVideoFrame
的内容来实现。以下是一个使用QMediaCaptureSession
和QVideoSink
来访问视频帧的示例:
#include <QMediaCaptureSession>
#include <QCamera>
#include <QVideoSink>
#include <QVideoFrame>// 创建一个媒体捕获会话
QMediaCaptureSession *captureSession = new QMediaCaptureSession;// 创建一个摄像头对象
QCamera *camera = new QCamera;// 将摄像头添加到捕获会话
captureSession->setCamera(camera);// 创建一个视频接收器
QVideoSink *videoSink = new QVideoSink;// 将视频接收器添加到捕获会话
captureSession->setVideoOutput(videoSink);// 连接视频接收器的帧接收信号
QObject::connect(videoSink, &QVideoSink::videoFrame, [=](const QVideoFrame &frame){// 在这里处理视频帧// ...
});// 开始摄像头
camera->start();
在这个示例中,我们创建了一个QMediaCaptureSession
对象和一个QCamera
对象,并将摄像头添加到了捕获会话中。然后我们创建了一个QVideoSink
对象,并将其添加到了捕获会话中。我们连接了QVideoSink
的videoFrame
信号,这样每当有新的视频帧时,我们就可以在槽函数中处理这个帧。最后,我们启动了摄像头。
四、Qt 6多媒体模块的变化特性(Changed Features in Qt 6 Multimedia Module)
4.1相机分辨率和帧率的处理变化(Changes in Handling of Camera Resolutions and Frame Rates)
在Qt 6中,相机分辨率和帧率的处理发生了变化。这些变化已经被简化,新的QCameraFormat类有助于选择相机的正确分辨率和帧率。
在Qt 5中,QCameraViewFinderSettings类被用来定义相机应使用的分辨率和帧率。然而,在Qt 6中,这个类已经被移除,取而代之的是使用QCameraFormat来定义相机应使用的分辨率和帧率。
这意味着在Qt 6中,你需要使用QCameraFormat类来设置和处理相机的分辨率和帧率,而不再使用QCameraViewFinderSettings类。这个改变可能会影响到之前使用Qt 5编写的代码,需要进行相应的修改和调整。
你可以在这里查看:QCameraFormat Class。
一般来说,你可以创建一个QCameraFormat对象,然后使用其方法来设置你想要的分辨率和帧率。例如:
QCameraFormat format;
format.setResolution(1920, 1080);
format.setFrameRate(30.0);
然后,你可以将这个格式应用到你的相机对象上:
camera->setViewfinderFormat(format);
请注意,这只是一个基本的示例,实际使用时可能需要根据具体需求进行更多的设置和处理。
4.2 QAbstractVideoSurface到QVideoSink的变化(Changes in Handling of Camera Resolutions and Frame Rates)
在Qt 6中,QAbstractVideoSurface已被QVideoSink替代,这是一个重大的API变化。QVideoSink可以用来从Qt Multimedia逐帧检索视频数据。QVideoSink将通过videoFrameChanged()信号向应用程序开发者提供单个视频帧。然后可以使用视频帧来读取这些帧的数据并进一步处理它们。
在Qt 5中,你可能会使用QAbstractVideoSurface来处理视频帧。但在Qt 6中,你需要使用QVideoSink来接收视频帧。以下是一个简单的示例,说明如何在Qt 6中使用QVideoSink:
QMediaPlayer player;
QVideoSink videoSink;// Connect the videoFrameChanged signal to a lambda function
QObject::connect(&videoSink, &QVideoSink::videoFrameChanged,[&](QVideoFrame frame) {// Process the video frame here});player.setVideoOutput(&videoSink);
player.setSource(QUrl::fromLocalFile("/path/to/your/video.mp4"));
player.play();
4.2.1 Qt 6中的QCamera和QVideoSink的代码示例
这是一个使用Qt 6中的QCamera和QVideoSink的代码示例,你可以在这个链接中找到完整的代码。以下是一些主要的代码片段:
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "frames.hpp"int main(int argc, char *argv[])
{QGuiApplication app(argc, argv);qmlRegisterType<Frames>("Frames", 1, 0, "Frames");QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
// frames.hpp
#ifndef FRAMES_HPP_INCLUDED
#define FRAMES_HPP_INCLUDED#include <QObject>
#include <QCamera>
#include <QVideoSink>class Frames : public QObject
{Q_OBJECTQ_PROPERTY(QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)Q_PROPERTY(QVideoSink *videoSink READ videoSink CONSTANT)public:explicit Frames(QObject *parent = nullptr);~Frames();QCamera *camera() const;void setCamera(QCamera *camera);QVideoSink *videoSink() const;signals:void cameraChanged();private:QCamera *m_camera;QVideoSink *m_videoSink;
};#endif // FRAMES_HPP_INCLUDED
// frames.cpp
#include "frames.hpp"
#include <QCameraInfo>
#include <QCameraFormat>
#include <QVideoFrame>Frames::Frames(QObject *parent): QObject(parent), m_camera(new QCamera(QCameraInfo::defaultCamera(), this)), m_videoSink(new QVideoSink(this))
{m_videoSink->setSource(m_camera);QObject::connect(m_videoSink, &QVideoSink::videoFrame, [this](const QVideoFrame &frame) {// 在这里处理视频帧});m_camera->start();
}Frames::~Frames()
{m_camera->stop();
}QCamera *Frames::camera() const
{return m_camera;
}void Frames::setCamera(QCamera *camera)
{if (m_camera == camera)return;m_camera = camera;emit cameraChanged();
}QVideoSink *Frames::videoSink() const
{return m_videoSink;
}
这个示例中,Frames
类包含一个QCamera
对象和一个QVideoSink
对象。QCamera
对象用于获取摄像头的视频流,QVideoSink
对象用于接收和处理这个视频流。在Frames
类的构造函数中,我们设置了QVideoSink
的源为QCamera
对象,并连接了QVideoSink
的videoFrame
信号,这样每当有新的视频帧时,我们就可以在槽函数中处理这个视频帧。
注意,这只是一个基本的示例,实际使用时可能需要根据具体需求进行更多的设置和处理。
4.3 QMediaMetaData的元数据类型变化(Metadata Type Changes in QMediaMetaData)
在这个示例中,我们创建了一个QMediaPlayer和一个QVideoSink。我们将QVideoSink的videoFrameChanged信号连接到一个lambda函数,这个函数将处理每一个视频帧。然后,我们将QVideoSink设置为QMediaPlayer的视频输出,并设置视频源为一个本地文件。最后,我们调用play()方法来开始播放视频。
这个示例展示了如何在Qt 6中使用QVideoSink来处理视频帧,这是一个替代QAbstractVideoSurface的方法。
在Qt 6中,QMediaMetaData的元数据类型发生了显著的变化。主要的变化是从基于字符串的键转向基于枚举的键,以及减少支持的键的集合,只保留在大多数平台上可以支持的键。
在Qt 5中,QMediaMetaData使用字符串作为键来存储和检索元数据。这意味着你可以使用任何字符串作为键来存储元数据。然而,这种方法的问题是,不同的开发者可能会使用不同的字符串来表示相同的元数据,这可能会导致混淆和不一致。
为了解决这个问题,Qt 6的QMediaMetaData改为使用枚举作为键。这意味着你现在需要使用预定义的枚举值来存储和检索元数据。这种方法的优点是,所有的开发者都会使用相同的枚举值来表示相同的元数据,这可以确保一致性。
此外,Qt 6的QMediaMetaData减少了支持的键的集合。在Qt 5中,QMediaMetaData支持大量的键,但并非所有的键都可以在所有平台上使用。在Qt 6中,QMediaMetaData只支持那些可以在大多数平台上使用的键。这可以确保你的代码在不同的平台上有一致的行为。
这些变化可能会影响到已经使用QMediaMetaData的代码。如果你的代码依赖于使用字符串作为键,或者依赖于那些在Qt 6中不再支持的键,那么你可能需要修改你的代码以适应这些变化。
在Qt 5中,你可能会这样使用QMediaMetaData:
QMediaPlayer player;
player.setMedia(QUrl::fromLocalFile("/path/to/your/audio.mp3"));
player.play();// Wait for the player to load the media and read the metadata
// ...QVariant title = player.metaData("Title");
QVariant album = player.metaData("Album");
QVariant artist = player.metaData("Artist");
// ...
在Qt 6中,你需要使用预定义的枚举值来存储和检索元数据,如下所示:
QMediaPlayer player;
player.setSource(QUrl::fromLocalFile("/path/to/your/audio.mp3"));
player.play();// Wait for the player to load the media and read the metadata
// ...QVariant title = player.metaData(QMediaMetaData::Title);
QVariant album = player.metaData(QMediaMetaData::Album);
QVariant artist = player.metaData(QMediaMetaData::Artist);
// ...
在这个示例中,我们使用QMediaMetaData::Title,QMediaMetaData::Album和QMediaMetaData::Artist这些预定义的枚举值来检索元数据。这些枚举值在所有的平台上都是一致的,这可以确保你的代码在不同的平台上有一致的行为。
五、被移除的功能原因以及替代方案
被移除的功能 | 移除原因 | Qt 6中的替代方案 |
---|---|---|
QMediaPlayer中的播放列表 | Qt 6中的QMediaPlayer不再处理任何播放列表 | 无 |
QMediaPlayList | 这个类已经从API中移除 | 仍然作为媒体播放器示例的一部分存在 |
QAudioProbe和QVideoProbe | 音频和视频探测API已经被移除 | 无 |
QAudioRecorder | 无 | 使用QMediaCaptureSession或CaptureSession QML类型 |
Audio QML类型 | 无 | 使用MediaPlayer QML类型 |
QMediaObject和QMediaBindableInterface | 这些类已经被移除 | 使用例如setVideoOutput和QMediaCaptureSession的更直接的API来设置对象之间的连接 |
QCameraViewFinderSettings | 这个类已经被移除 | 使用QCameraFormat来定义相机应该使用的分辨率和帧率 |
QMediaContent | 这个类已经被移除 | 对于单个媒体文件,使用QUrl代替 |
QSound | 无 | 使用QSoundEffect代替 |
QVideoFilterRunnable | 无 | 在QML中使用着色器效果,或者在C++中访问QVideoFrame的内容 |
公共后端API | Qt 6的Qt Multimedia的后端API是私有的 | 无 |
后端插件 | Qt 6的Qt Multimedia不再使用插件基础设施来处理其后端 | 正在使用的后端是在编译时基于底层操作系统确定 |