summaryrefslogtreecommitdiffstats
path: root/src/multimedia/playback/qmediaplayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/playback/qmediaplayer.cpp')
-rw-r--r--src/multimedia/playback/qmediaplayer.cpp1826
1 files changed, 770 insertions, 1056 deletions
diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp
index 6c32e110b..2336cf12e 100644
--- a/src/multimedia/playback/qmediaplayer.cpp
+++ b/src/multimedia/playback/qmediaplayer.cpp
@@ -1,372 +1,155 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmediaplayer.h"
-#include "qvideosurfaces_p.h"
-#include "qvideosurfaceoutput_p.h"
-
-#include "qmediaobject_p.h"
-#include <qmediaservice.h>
-#include <qmediaplayercontrol.h>
-#include <qmediaserviceprovider_p.h>
-#include <qmediaplaylist.h>
-#include <qmediaplaylistcontrol_p.h>
-#include <qmediaplaylistsourcecontrol_p.h>
-#include <qaudiorolecontrol.h>
-#include <qcustomaudiorolecontrol.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qmediaplayer_p.h"
+
+#include <private/qmultimediautils_p.h>
+#include <private/qplatformmediaintegration_p.h>
+#include <qvideosink.h>
+#include <qaudiooutput.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qtimer.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qdir.h>
#include <QtCore/qpointer.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qtemporaryfile.h>
-#include <QDir>
+#include <QtCore/qcoreapplication.h>
+
+#if defined(Q_OS_ANDROID)
+# include <QtCore/qjniobject.h>
+#endif
QT_BEGIN_NAMESPACE
/*!
\class QMediaPlayer
- \brief The QMediaPlayer class allows the playing of a media source.
+ \brief The QMediaPlayer class allows the playing of a media files.
\inmodule QtMultimedia
\ingroup multimedia
\ingroup multimedia_playback
+ \ingroup multimedia_video
The QMediaPlayer class is a high level media playback class. It can be used
- to playback such content as songs, movies and internet radio. The content
- to playback is specified as a QMediaContent object, which can be thought of as a
- main or canonical URL with additional information attached. When provided
- with a QMediaContent playback may be able to commence.
+ to playback audio of video media files. The content
+ to playback is specified as a QUrl object.
\snippet multimedia-snippets/media.cpp Player
- QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist
- for accessing playlist functionality.
-
- \snippet multimedia-snippets/media.cpp Movie playlist
-
- Since QMediaPlayer is a QMediaObject, you can use several of the QMediaObject
- functions for things like:
-
- \list
- \li Accessing the currently playing media's metadata (\l {QMediaObject::metaData()} and \l {QMediaMetaData}{predefined meta-data keys})
- \li Checking to see if the media playback service is currently available (\l {QMediaObject::availability()})
- \endlist
+ QVideoWidget can be used with QMediaPlayer for video rendering.
- \sa QMediaObject, QMediaService, QVideoWidget, QMediaPlaylist
+ \sa QVideoWidget
*/
-static void qRegisterMediaPlayerMetaTypes()
-{
- qRegisterMetaType<QMediaPlayer::State>("QMediaPlayer::State");
- qRegisterMetaType<QMediaPlayer::MediaStatus>("QMediaPlayer::MediaStatus");
- qRegisterMetaType<QMediaPlayer::Error>("QMediaPlayer::Error");
-}
-
-Q_CONSTRUCTOR_FUNCTION(qRegisterMediaPlayerMetaTypes)
-
-#define MAX_NESTED_PLAYLISTS 16
-
-class QMediaPlayerPrivate : public QMediaObjectPrivate
-{
- Q_DECLARE_NON_CONST_PUBLIC(QMediaPlayer)
-
-public:
- QMediaPlayerPrivate()
- : provider(nullptr)
- , control(nullptr)
- , audioRoleControl(nullptr)
- , customAudioRoleControl(nullptr)
- , playlist(nullptr)
- , state(QMediaPlayer::StoppedState)
- , status(QMediaPlayer::UnknownMediaStatus)
- , error(QMediaPlayer::NoError)
- , ignoreNextStatusChange(-1)
- , nestedPlaylists(0)
- , hasStreamPlaybackFeature(false)
- {}
-
- QMediaServiceProvider *provider;
- QMediaPlayerControl* control;
- QAudioRoleControl *audioRoleControl;
- QCustomAudioRoleControl *customAudioRoleControl;
- QString errorString;
-
- QPointer<QObject> videoOutput;
- QMediaPlaylist *playlist;
- QVideoSurfaceOutput surfaceOutput;
- QMediaContent qrcMedia;
- QScopedPointer<QFile> qrcFile;
-
- QMediaContent rootMedia;
- QMediaContent pendingPlaylist;
- QMediaPlayer::State state;
- QMediaPlayer::MediaStatus status;
- QMediaPlayer::Error error;
- int ignoreNextStatusChange;
- int nestedPlaylists;
- bool hasStreamPlaybackFeature;
-
- QMediaPlaylist *parentPlaylist(QMediaPlaylist *pls);
- bool isInChain(const QUrl &url);
-
- void setMedia(const QMediaContent &media, QIODevice *stream = nullptr);
-
- void setPlaylist(QMediaPlaylist *playlist);
- void setPlaylistMedia();
- void loadPlaylist();
- void disconnectPlaylist();
- void connectPlaylist();
-
- void _q_stateChanged(QMediaPlayer::State state);
- void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
- void _q_error(int error, const QString &errorString);
- void _q_updateMedia(const QMediaContent&);
- void _q_playlistDestroyed();
- void _q_handleMediaChanged(const QMediaContent&);
- void _q_handlePlaylistLoaded();
- void _q_handlePlaylistLoadFailed();
-};
-
-QMediaPlaylist *QMediaPlayerPrivate::parentPlaylist(QMediaPlaylist *pls)
-{
- // This function finds a parent playlist for an item in the active chain of playlists.
- // Every item in the chain comes from currentMedia() of its parent.
- // We don't need to travers the whole tree of playlists,
- // but only the subtree of active ones.
- for (QMediaPlaylist *current = rootMedia.playlist(); current && current != pls; current = current->currentMedia().playlist())
- if (current->currentMedia().playlist() == pls)
- return current;
- return nullptr;
-}
-
-bool QMediaPlayerPrivate::isInChain(const QUrl &url)
-{
- // Check whether a URL is already in the chain of playlists.
- // Also see a comment in parentPlaylist().
- for (QMediaPlaylist *current = rootMedia.playlist(); current && current != playlist; current = current->currentMedia().playlist())
- if (current->currentMedia().request().url() == url) {
- return true;
+/*!
+ \qmltype MediaPlayer
+ \instantiates QMediaPlayer
+ \brief Adds media playback to a scene.
+
+ \inqmlmodule QtMultimedia
+ \ingroup multimedia_qml
+ \ingroup multimedia_audio_qml
+ \ingroup multimedia_video_qml
+
+ \qml
+ Text {
+ text: "Click Me!";
+ font.pointSize: 24;
+ width: 150; height: 50;
+
+ MediaPlayer {
+ id: playMusic
+ source: "music.wav"
+ audioOutput: AudioOutput {}
}
- return false;
-}
-
-void QMediaPlayerPrivate::_q_stateChanged(QMediaPlayer::State ps)
-{
- Q_Q(QMediaPlayer);
-
- // Backend switches into stopped state every time new media is about to be loaded.
- // If media player has a playlist loaded make sure player doesn' stop.
- if (playlist && playlist->currentIndex() != -1 && ps != state && ps == QMediaPlayer::StoppedState) {
- if (control->mediaStatus() == QMediaPlayer::EndOfMedia ||
- control->mediaStatus() == QMediaPlayer::InvalidMedia) {
- // if media player is not stopped, and
- // we have finished playback for the current media,
- // advance to the next item in the playlist
- Q_ASSERT(state != QMediaPlayer::StoppedState);
- playlist->next();
- return;
- } else if (control->mediaStatus() == QMediaPlayer::LoadingMedia) {
- return;
+ MouseArea {
+ anchors.fill: parent
+ onPressed: { playMusic.play() }
}
}
+ \endqml
+
+ You can use MediaPlayer together with a MultiMedia::AudioOutput to play audio content, or you can use it
+ in conjunction with a Multimedia::VideoOutput for rendering video.
+
+ \qml
+ Item {
+ MediaPlayer {
+ id: mediaplayer
+ source: "groovy_video.mp4"
+ audioOutput: AudioOutput {}
+ videoOutput: videoOutput
+ }
- if (ps != state) {
- state = ps;
-
- if (ps == QMediaPlayer::PlayingState)
- q->addPropertyWatch("position");
- else
- q->removePropertyWatch("position");
+ VideoOutput {
+ id: videoOutput
+ anchors.fill: parent
+ }
- emit q->stateChanged(ps);
+ MouseArea {
+ anchors.fill: parent
+ onPressed: mediaplayer.play();
+ }
}
-}
+ \endqml
+
+ \sa AudioOutput, VideoOutput
+*/
-void QMediaPlayerPrivate::_q_mediaStatusChanged(QMediaPlayer::MediaStatus s)
+void QMediaPlayerPrivate::setState(QMediaPlayer::PlaybackState toState)
{
Q_Q(QMediaPlayer);
- if (int(s) == ignoreNextStatusChange) {
- ignoreNextStatusChange = -1;
- return;
- }
-
- if (s != status) {
- status = s;
-
- switch (s) {
- case QMediaPlayer::StalledMedia:
- case QMediaPlayer::BufferingMedia:
- q->addPropertyWatch("bufferStatus");
- break;
- default:
- q->removePropertyWatch("bufferStatus");
- break;
- }
-
- emit q->mediaStatusChanged(s);
+ if (toState != state) {
+ const auto fromState = std::exchange(state, toState);
+ if (toState == QMediaPlayer::PlayingState || fromState == QMediaPlayer::PlayingState)
+ emit q->playingChanged(toState == QMediaPlayer::PlayingState);
+ emit q->playbackStateChanged(toState);
}
}
-void QMediaPlayerPrivate::_q_error(int error, const QString &errorString)
+void QMediaPlayerPrivate::setStatus(QMediaPlayer::MediaStatus s)
{
Q_Q(QMediaPlayer);
- if (error == int(QMediaPlayer::MediaIsPlaylist)) {
- loadPlaylist();
- } else {
- this->error = QMediaPlayer::Error(error);
- this->errorString = errorString;
- emit q->error(this->error);
-
- if (playlist)
- playlist->next();
- }
+ emit q->mediaStatusChanged(s);
}
-void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media)
+void QMediaPlayerPrivate::setError(QMediaPlayer::Error error, const QString &errorString)
{
Q_Q(QMediaPlayer);
- if (!control)
- return;
-
- // check if the current playlist is a top-level playlist
- Q_ASSERT(playlist);
- if (media.isNull() && playlist != rootMedia.playlist()) {
- // switch back to parent playlist
- QMediaPlaylist *pls = parentPlaylist(playlist);
- Q_ASSERT(pls);
- disconnectPlaylist();
- playlist = pls;
- connectPlaylist();
-
- Q_ASSERT(!pendingPlaylist.playlist());
- nestedPlaylists--;
- Q_ASSERT(nestedPlaylists >= 0);
-
- playlist->next();
- return;
- }
-
- if (media.playlist()) {
- if (nestedPlaylists < MAX_NESTED_PLAYLISTS) {
- nestedPlaylists++;
- Q_ASSERT(!pendingPlaylist.playlist());
-
- // disconnect current playlist
- disconnectPlaylist();
- // new playlist signals are connected
- // in the call to setPlaylist() in _q_handlePlaylistLoaded()
- playlist = media.playlist();
- emit q->currentMediaChanged(media);
- _q_handlePlaylistLoaded();
- return;
- } else if (playlist) {
- playlist->next();
- }
- return;
- }
-
- const QMediaPlayer::State currentState = state;
-
- setMedia(media, nullptr);
-
- if (!media.isNull()) {
- switch (currentState) {
- case QMediaPlayer::PlayingState:
- control->play();
- break;
- case QMediaPlayer::PausedState:
- control->pause();
- break;
- default:
- break;
- }
- }
-
- _q_stateChanged(control->state());
+ this->error.setAndNotify(error, errorString, *q);
}
-void QMediaPlayerPrivate::_q_playlistDestroyed()
+void QMediaPlayerPrivate::setMedia(const QUrl &media, QIODevice *stream)
{
- playlist = nullptr;
- setMedia(QMediaContent(), nullptr);
-}
-
-void QMediaPlayerPrivate::setMedia(const QMediaContent &media, QIODevice *stream)
-{
- Q_Q(QMediaPlayer);
-
if (!control)
return;
- QScopedPointer<QFile> file;
+ std::unique_ptr<QFile> file;
- // Backends can't play qrc files directly.
- // If the backend supports StreamPlayback, we pass a QFile for that resource.
+ // Back ends can't play qrc files directly.
+ // If the back end supports StreamPlayback, we pass a QFile for that resource.
// If it doesn't, we copy the data to a temporary file and pass its path.
- if (!media.isNull() && !stream && media.request().url().scheme() == QLatin1String("qrc")) {
+ if (!media.isEmpty() && !stream && media.scheme() == QLatin1String("qrc")) {
qrcMedia = media;
- file.reset(new QFile(QLatin1Char(':') + media.request().url().path()));
+ file.reset(new QFile(QLatin1Char(':') + media.path()));
if (!file->open(QFile::ReadOnly)) {
- QMetaObject::invokeMethod(q, "_q_error", Qt::QueuedConnection,
- Q_ARG(int, QMediaPlayer::ResourceError),
- Q_ARG(QString, QMediaPlayer::tr("Attempting to play invalid Qt resource")));
- QMetaObject::invokeMethod(q, "_q_mediaStatusChanged", Qt::QueuedConnection,
- Q_ARG(QMediaPlayer::MediaStatus, QMediaPlayer::InvalidMedia));
file.reset();
- // Ignore the next NoMedia status change, we just want to clear the current media
- // on the backend side since we can't load the new one and we want to be in the
- // InvalidMedia status.
- ignoreNextStatusChange = QMediaPlayer::NoMedia;
- control->setMedia(QMediaContent(), nullptr);
-
- } else if (hasStreamPlaybackFeature) {
- control->setMedia(media, file.data());
+ control->setMedia(QUrl(), nullptr);
+ control->mediaStatusChanged(QMediaPlayer::InvalidMedia);
+ control->error(QMediaPlayer::ResourceError, QMediaPlayer::tr("Attempting to play invalid Qt resource"));
+
+ } else if (control->streamPlaybackSupported()) {
+ control->setMedia(media, file.get());
} else {
#if QT_CONFIG(temporaryfile)
#if defined(Q_OS_ANDROID)
- QString tempFileName = QDir::tempPath() + media.request().url().path();
+ QString tempFileName = QDir::tempPath() + media.path();
QDir().mkpath(QFileInfo(tempFileName).path());
QTemporaryFile *tempFile = QTemporaryFile::createNativeFile(*file);
if (!tempFile->rename(tempFileName))
@@ -374,14 +157,21 @@ void QMediaPlayerPrivate::setMedia(const QMediaContent &media, QIODevice *stream
#else
QTemporaryFile *tempFile = new QTemporaryFile;
- // Preserve original file extension, some backends might not load the file if it doesn't
+ // Preserve original file extension, some back ends might not load the file if it doesn't
// have an extension.
const QString suffix = QFileInfo(*file).suffix();
if (!suffix.isEmpty())
tempFile->setFileTemplate(tempFile->fileTemplate() + QLatin1Char('.') + suffix);
// Copy the qrc data into the temporary file
- tempFile->open();
+ if (!tempFile->open()) {
+ control->setMedia(QUrl(), nullptr);
+ control->mediaStatusChanged(QMediaPlayer::InvalidMedia);
+ control->error(QMediaPlayer::ResourceError, tempFile->errorString());
+ delete tempFile;
+ qrcFile.reset();
+ return;
+ }
char buffer[4096];
while (true) {
qint64 len = file->read(buffer, sizeof(buffer));
@@ -392,253 +182,53 @@ void QMediaPlayerPrivate::setMedia(const QMediaContent &media, QIODevice *stream
tempFile->close();
#endif
file.reset(tempFile);
- control->setMedia(QMediaContent(QUrl::fromLocalFile(file->fileName())), nullptr);
+ control->setMedia(QUrl(QUrl::fromLocalFile(file->fileName())), nullptr);
#else
qWarning("Qt was built with -no-feature-temporaryfile: playback from resource file is not supported!");
#endif
}
} else {
- qrcMedia = QMediaContent();
- control->setMedia(media, stream);
- }
-
- qrcFile.swap(file); // Cleans up any previous file
-}
-
-void QMediaPlayerPrivate::_q_handleMediaChanged(const QMediaContent &media)
-{
- Q_Q(QMediaPlayer);
-
- emit q->currentMediaChanged(qrcMedia.isNull() ? media : qrcMedia);
-}
-
-void QMediaPlayerPrivate::setPlaylist(QMediaPlaylist *pls)
-{
- disconnectPlaylist();
- playlist = pls;
-
- setPlaylistMedia();
-}
-
-void QMediaPlayerPrivate::setPlaylistMedia()
-{
- // This function loads current playlist media into backend.
- // If current media is a playlist, the function recursively
- // loads media from the playlist.
- // It also makes sure the correct playlist signals are connected.
- Q_Q(QMediaPlayer);
-
- if (playlist) {
- connectPlaylist();
- if (playlist->currentMedia().playlist()) {
- if (nestedPlaylists < MAX_NESTED_PLAYLISTS) {
- emit q->currentMediaChanged(playlist->currentMedia());
- // rewind nested playlist to start
- playlist->currentMedia().playlist()->setCurrentIndex(0);
- nestedPlaylists++;
- setPlaylist(playlist->currentMedia().playlist());
- } else {
- playlist->next();
- }
- return;
- } else {
- // If we've just switched to a new playlist,
- // then last emitted currentMediaChanged was a playlist.
- // Make sure we emit currentMediaChanged if new playlist has
- // the same media as the previous one:
- // sample.m3u
- // test.wav -- processed by backend
- // nested.m3u -- processed by frontend
- // test.wav -- processed by backend,
- // media is not changed,
- // frontend needs to emit currentMediaChanged
- bool isSameMedia = (q->currentMedia() == playlist->currentMedia());
- setMedia(playlist->currentMedia(), nullptr);
- if (isSameMedia) {
- emit q->currentMediaChanged(q->currentMedia());
- }
+ qrcMedia = QUrl();
+ QUrl url = qMediaFromUserInput(media);
+ if (url.scheme() == QLatin1String("content") && !stream) {
+ file.reset(new QFile(media.url()));
+ stream = file.get();
}
- } else {
- setMedia(QMediaContent(), nullptr);
- }
-}
-void QMediaPlayerPrivate::loadPlaylist()
-{
- Q_Q(QMediaPlayer);
- Q_ASSERT(pendingPlaylist.isNull());
-
- // Do not load a playlist if there are more than MAX_NESTED_PLAYLISTS in the chain already,
- // or if the playlist URL is already in the chain, i.e. do not allow recursive playlists and loops.
- if (nestedPlaylists < MAX_NESTED_PLAYLISTS
- && !q->currentMedia().request().url().isEmpty()
- && !isInChain(q->currentMedia().request().url()))
- {
- pendingPlaylist = QMediaContent(new QMediaPlaylist, q->currentMedia().request().url(), true);
- QObject::connect(pendingPlaylist.playlist(), SIGNAL(loaded()), q, SLOT(_q_handlePlaylistLoaded()));
- QObject::connect(pendingPlaylist.playlist(), SIGNAL(loadFailed()), q, SLOT(_q_handlePlaylistLoadFailed()));
- pendingPlaylist.playlist()->load(pendingPlaylist.request());
- } else if (playlist) {
- playlist->next();
+ control->setMedia(url, stream);
}
-}
-void QMediaPlayerPrivate::disconnectPlaylist()
-{
- Q_Q(QMediaPlayer);
- if (playlist) {
- QObject::disconnect(playlist, SIGNAL(currentMediaChanged(QMediaContent)),
- q, SLOT(_q_updateMedia(QMediaContent)));
- QObject::disconnect(playlist, SIGNAL(destroyed()), q, SLOT(_q_playlistDestroyed()));
- q->unbind(playlist);
- }
-}
-
-void QMediaPlayerPrivate::connectPlaylist()
-{
- Q_Q(QMediaPlayer);
- if (playlist) {
- q->bind(playlist);
- QObject::connect(playlist, SIGNAL(currentMediaChanged(QMediaContent)),
- q, SLOT(_q_updateMedia(QMediaContent)));
- QObject::connect(playlist, SIGNAL(destroyed()), q, SLOT(_q_playlistDestroyed()));
- }
+ qrcFile.swap(file); // Cleans up any previous file
}
-void QMediaPlayerPrivate::_q_handlePlaylistLoaded()
+QList<QMediaMetaData> QMediaPlayerPrivate::trackMetaData(QPlatformMediaPlayer::TrackType s) const
{
- Q_Q(QMediaPlayer);
-
- if (pendingPlaylist.playlist()) {
- Q_ASSERT(!q->currentMedia().playlist());
- // if there is an active playlist
- if (playlist) {
- Q_ASSERT(playlist->currentIndex() >= 0);
- disconnectPlaylist();
- playlist->insertMedia(playlist->currentIndex() + 1, pendingPlaylist);
- playlist->removeMedia(playlist->currentIndex());
- nestedPlaylists++;
- } else {
- Q_ASSERT(!rootMedia.playlist());
- rootMedia = pendingPlaylist;
- emit q->mediaChanged(rootMedia);
+ QList<QMediaMetaData> tracks;
+ if (control) {
+ int count = control->trackCount(s);
+ for (int i = 0; i < count; ++i) {
+ tracks.append(control->trackMetaData(s, i));
}
-
- playlist = pendingPlaylist.playlist();
- emit q->currentMediaChanged(pendingPlaylist);
}
- pendingPlaylist = QMediaContent();
-
- playlist->next();
- setPlaylistMedia();
-
- switch (state) {
- case QMediaPlayer::PausedState:
- control->pause();
- break;
- case QMediaPlayer::PlayingState:
- control->play();
- break;
- case QMediaPlayer::StoppedState:
- break;
- }
-}
-
-void QMediaPlayerPrivate::_q_handlePlaylistLoadFailed()
-{
- pendingPlaylist = QMediaContent();
-
- if (!control)
- return;
-
- if (playlist)
- playlist->next();
- else
- setMedia(QMediaContent(), nullptr);
+ return tracks;
}
-static QMediaService *playerService(QMediaPlayer::Flags flags)
-{
- QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider();
- if (flags) {
- QMediaServiceProviderHint::Features features;
- if (flags & QMediaPlayer::LowLatency)
- features |= QMediaServiceProviderHint::LowLatencyPlayback;
-
- if (flags & QMediaPlayer::StreamPlayback)
- features |= QMediaServiceProviderHint::StreamPlayback;
-
- if (flags & QMediaPlayer::VideoSurface)
- features |= QMediaServiceProviderHint::VideoSurface;
-
- return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER,
- QMediaServiceProviderHint(features));
- }
-
- return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER);
-}
-
-
/*!
- Construct a QMediaPlayer instance
- parented to \a parent and with \a flags.
+ Constructs a QMediaPlayer instance as a child of \a{parent}.
*/
-QMediaPlayer::QMediaPlayer(QObject *parent, QMediaPlayer::Flags flags):
- QMediaObject(*new QMediaPlayerPrivate,
- parent,
- playerService(flags))
+QMediaPlayer::QMediaPlayer(QObject *parent)
+ : QObject(*new QMediaPlayerPrivate, parent)
{
Q_D(QMediaPlayer);
- d->provider = QMediaServiceProvider::defaultServiceProvider();
- if (d->service == nullptr) {
- d->error = ServiceMissingError;
+ auto maybeControl = QPlatformMediaIntegration::instance()->createPlayer(this);
+ if (maybeControl) {
+ d->control = maybeControl.value();
+ d->state = d->control->state();
} else {
- d->control = qobject_cast<QMediaPlayerControl*>(d->service->requestControl(QMediaPlayerControl_iid));
- if (d->control != nullptr) {
- connect(d->control, SIGNAL(mediaChanged(QMediaContent)), SLOT(_q_handleMediaChanged(QMediaContent)));
- connect(d->control, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(_q_stateChanged(QMediaPlayer::State)));
- connect(d->control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
- SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
- connect(d->control, SIGNAL(error(int,QString)), SLOT(_q_error(int,QString)));
-
- connect(d->control, &QMediaPlayerControl::durationChanged, this, &QMediaPlayer::durationChanged);
- connect(d->control, &QMediaPlayerControl::positionChanged, this, &QMediaPlayer::positionChanged);
- connect(d->control, &QMediaPlayerControl::audioAvailableChanged, this, &QMediaPlayer::audioAvailableChanged);
- connect(d->control, &QMediaPlayerControl::videoAvailableChanged, this, &QMediaPlayer::videoAvailableChanged);
- connect(d->control, &QMediaPlayerControl::volumeChanged, this, &QMediaPlayer::volumeChanged);
- connect(d->control, &QMediaPlayerControl::mutedChanged, this, &QMediaPlayer::mutedChanged);
- connect(d->control, &QMediaPlayerControl::seekableChanged, this, &QMediaPlayer::seekableChanged);
- connect(d->control, &QMediaPlayerControl::playbackRateChanged, this, &QMediaPlayer::playbackRateChanged);
- connect(d->control, &QMediaPlayerControl::bufferStatusChanged, this, &QMediaPlayer::bufferStatusChanged);
-
- d->state = d->control->state();
- d->status = d->control->mediaStatus();
-
- if (d->state == PlayingState)
- addPropertyWatch("position");
-
- if (d->status == StalledMedia || d->status == BufferingMedia)
- addPropertyWatch("bufferStatus");
-
- d->hasStreamPlaybackFeature = d->provider->supportedFeatures(d->service).testFlag(QMediaServiceProviderHint::StreamPlayback);
-
- d->audioRoleControl = qobject_cast<QAudioRoleControl*>(d->service->requestControl(QAudioRoleControl_iid));
- if (d->audioRoleControl) {
- connect(d->audioRoleControl, &QAudioRoleControl::audioRoleChanged,
- this, &QMediaPlayer::audioRoleChanged);
-
- d->customAudioRoleControl = qobject_cast<QCustomAudioRoleControl *>(
- d->service->requestControl(QCustomAudioRoleControl_iid));
- if (d->customAudioRoleControl) {
- connect(d->customAudioRoleControl,
- &QCustomAudioRoleControl::customAudioRoleChanged,
- this,
- &QMediaPlayer::customAudioRoleChanged);
- }
- }
- }
+ qWarning() << "Failed to initialize QMediaPlayer" << maybeControl.error();
+ d->setError(QMediaPlayer::ResourceError, maybeControl.error());
}
}
@@ -651,86 +241,56 @@ QMediaPlayer::~QMediaPlayer()
{
Q_D(QMediaPlayer);
- d->disconnectPlaylist();
- // Disconnect everything to prevent notifying
- // when a receiver is already destroyed.
- disconnect();
+ // prevents emitting audioOutputChanged and videoOutputChanged.
+ QSignalBlocker blocker(this);
- if (d->service) {
- if (d->control)
- d->service->releaseControl(d->control);
- if (d->audioRoleControl)
- d->service->releaseControl(d->audioRoleControl);
- if (d->customAudioRoleControl)
- d->service->releaseControl(d->customAudioRoleControl);
+ // Reset audio output and video sink to ensure proper unregistering of the source
+ // To be investigated: registering of the source might be removed after switching on the ffmpeg
+ // backend;
- d->provider->releaseService(d->service);
- }
+ setAudioOutput(nullptr);
+
+ d->setVideoSink(nullptr);
+ delete d->control;
}
-QMediaContent QMediaPlayer::media() const
+QUrl QMediaPlayer::source() const
{
Q_D(const QMediaPlayer);
- return d->rootMedia;
+ return d->source;
}
/*!
Returns the stream source of media data.
- This is only valid if a stream was passed to setMedia().
+ This is only valid if a stream was passed to setSource().
- \sa setMedia()
+ \sa setSource()
*/
-const QIODevice *QMediaPlayer::mediaStream() const
-{
- Q_D(const QMediaPlayer);
-
- // When playing a resource file, we might have passed a QFile to the backend. Hide it from
- // the user.
- if (d->control && d->qrcMedia.isNull())
- return d->control->mediaStream();
-
- return nullptr;
-}
-
-QMediaPlaylist *QMediaPlayer::playlist() const
+const QIODevice *QMediaPlayer::sourceDevice() const
{
Q_D(const QMediaPlayer);
- return d->rootMedia.playlist();
+ return d->stream;
}
-QMediaContent QMediaPlayer::currentMedia() const
-{
- Q_D(const QMediaPlayer);
-
- // When playing a resource file, don't return the backend's current media, which
- // can be a temporary file.
- if (!d->qrcMedia.isNull())
- return d->qrcMedia;
-
- if (d->control)
- return d->control->media();
-
- return QMediaContent();
-}
+/*!
+ \property QMediaPlayer::playbackState
-void QMediaPlayer::setPlaylist(QMediaPlaylist *playlist)
-{
- QMediaContent m(playlist, QUrl(), false);
- setMedia(m);
-}
+ Returns the \l{QMediaPlayer::}{PlaybackState}.
-QMediaPlayer::State QMediaPlayer::state() const
+ \sa playing
+*/
+QMediaPlayer::PlaybackState QMediaPlayer::playbackState() const
{
Q_D(const QMediaPlayer);
// In case if EndOfMedia status is already received
// but state is not.
- if (d->control != nullptr
- && d->status == QMediaPlayer::EndOfMedia
+ if (d->control
+ && d->control->mediaStatus() == QMediaPlayer::EndOfMedia
&& d->state != d->control->state()) {
return d->control->state();
}
@@ -740,546 +300,745 @@ QMediaPlayer::State QMediaPlayer::state() const
QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const
{
- return d_func()->status;
+ Q_D(const QMediaPlayer);
+ return d->control ? d->control->mediaStatus() : NoMedia;
}
+/*!
+ Returns the duration of the current media in ms.
+
+ Returns 0 if the media player doesn't have a valid media file or stream.
+ For live streams, the duration usually changes during playback as more
+ data becomes available.
+*/
qint64 QMediaPlayer::duration() const
{
Q_D(const QMediaPlayer);
-
- if (d->control != nullptr)
- return d->control->duration();
-
- return -1;
+ return d->control ? d->control->duration() : 0;
}
+/*!
+ Returns the current position inside the media being played back in ms.
+
+ Returns 0 if the media player doesn't have a valid media file or stream.
+ For live streams, the duration usually changes during playback as more
+ data becomes available.
+*/
qint64 QMediaPlayer::position() const
{
Q_D(const QMediaPlayer);
+ return d->control ? d->control->position() : 0;
+}
- if (d->control != nullptr)
- return d->control->position();
+/*!
+ Returns a number between 0 and 1 when buffering data.
- return 0;
-}
+ 0 means that there is no buffered data available, playback is usually
+ stalled in this case. Playback will resume once the buffer reaches 1,
+ meaning enough data has been buffered to be able to resume playback.
-int QMediaPlayer::volume() const
+ bufferProgress() will always return 1 for local files.
+*/
+float QMediaPlayer::bufferProgress() const
{
Q_D(const QMediaPlayer);
+ return d->control ? d->control->bufferProgress() : 0;
+}
- if (d->control != nullptr)
- return d->control->volume();
+/*!
+ Returns a QMediaTimeRange describing the currently buffered data.
- return 0;
-}
+ When streaming media from a remote source, different parts of the media
+ file can be available locally. The returned QMediaTimeRange object describes
+ the time ranges that are buffered and available for immediate playback.
-bool QMediaPlayer::isMuted() const
+ \sa QMediaTimeRange
+*/
+QMediaTimeRange QMediaPlayer::bufferedTimeRange() const
{
Q_D(const QMediaPlayer);
+ return d->control ? d->control->availablePlaybackRanges() : QMediaTimeRange{};
+}
- if (d->control != nullptr)
- return d->control->isMuted();
+/*!
+ \qmlproperty bool QtMultimedia::MediaPlayer::hasAudio
- return false;
-}
+ This property holds whether the media contains audio.
+*/
-int QMediaPlayer::bufferStatus() const
+/*!
+ \property QMediaPlayer::hasAudio
+ \brief This property holds whether the media contains audio.
+*/
+bool QMediaPlayer::hasAudio() const
{
Q_D(const QMediaPlayer);
+ return d->control && d->control->isAudioAvailable();
+}
- if (d->control != nullptr)
- return d->control->bufferStatus();
+/*!
+ \qmlproperty bool QtMultimedia::MediaPlayer::hasVideo
- return 0;
-}
+ This property holds whether the media contains video.
+*/
-bool QMediaPlayer::isAudioAvailable() const
+/*!
+ \property QMediaPlayer::hasVideo
+ \brief This property holds whether the media contains video.
+*/
+bool QMediaPlayer::hasVideo() const
{
Q_D(const QMediaPlayer);
+ return d->control && d->control->isVideoAvailable();
+}
- if (d->control != nullptr)
- return d->control->isAudioAvailable();
+/*!
+ Returns true if the media is seekable. Most file based media files are seekable,
+ but live streams usually are not.
- return false;
+ \sa position
+*/
+bool QMediaPlayer::isSeekable() const
+{
+ Q_D(const QMediaPlayer);
+ return d->control && d->control->isSeekable();
}
-bool QMediaPlayer::isVideoAvailable() const
+bool QMediaPlayer::isPlaying() const
{
Q_D(const QMediaPlayer);
-
- if (d->control != nullptr)
- return d->control->isVideoAvailable();
-
- return false;
+ return d->state == QMediaPlayer::PlayingState;
}
-bool QMediaPlayer::isSeekable() const
+/*!
+ Returns the current playback rate.
+*/
+qreal QMediaPlayer::playbackRate() const
{
Q_D(const QMediaPlayer);
+ return d->control ? d->control->playbackRate() : 0.;
+}
- if (d->control != nullptr)
- return d->control->isSeekable();
+/*!
+ \enum QMediaPlayer::Loops
- return false;
-}
+ Some predefined constants for the \l loops property.
-qreal QMediaPlayer::playbackRate() const
+ \value Infinite Loop forever.
+ \value Once Play the media once (the default).
+*/
+
+/*!
+ \property QMediaPlayer::loops
+
+ Determines how often the media is played before the player stops.
+ Set to QMediaPlayer::Infinite to loop the current media file forever.
+
+ The default value is \c 1. Setting this property to \c 0 has no effect.
+*/
+
+/*!
+ \qmlproperty int QtMultimedia::MediaPlayer::loops
+
+ Determines how often the media is played before the player stops.
+ Set to MediaPlayer::Infinite to loop the current media file forever.
+
+ The default value is \c 1. Setting this property to \c 0 has no effect.
+*/
+int QMediaPlayer::loops() const
{
Q_D(const QMediaPlayer);
+ return d->control ? d->control->loops() : 1;
+}
- if (d->control != nullptr)
- return d->control->playbackRate();
-
- return 0.0;
+void QMediaPlayer::setLoops(int loops)
+{
+ Q_D(QMediaPlayer);
+ if (loops == 0)
+ return;
+ if (d->control)
+ d->control->setLoops(loops);
}
/*!
Returns the current error state.
*/
-
QMediaPlayer::Error QMediaPlayer::error() const
{
- return d_func()->error;
+ return d_func()->error.code();
}
+/*!
+ \qmlproperty string QtMultimedia::MediaPlayer::errorString
+
+ This property holds a string describing the current error condition in more
+ detail.
+*/
+
+/*!
+ \property QMediaPlayer::errorString
+ \brief This property holds a string describing the current error condition in
+ more detail.
+*/
QString QMediaPlayer::errorString() const
{
- return d_func()->errorString;
+ return d_func()->error.description();
}
-//public Q_SLOTS:
/*!
- Start or resume playing the current source.
+ \qmlmethod QtMultimedia::MediaPlayer::play()
+
+ Starts or resumes playback of the media.
+
+ Sets the \l playbackState property to PlayingState, and changes
+ \l playing to \c true.
*/
+/*!
+ Start or resume playing the current source.
+
+ \sa pause(), stop()
+*/
void QMediaPlayer::play()
{
Q_D(QMediaPlayer);
- if (d->control == nullptr) {
- QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection,
- Q_ARG(int, QMediaPlayer::ServiceMissingError),
- Q_ARG(QString, tr("The QMediaPlayer object does not have a valid service")));
+ if (!d->control)
return;
- }
-
- //if playlist control is available, the service should advance itself
- if (d->rootMedia.playlist() && !d->rootMedia.playlist()->isEmpty()) {
- // switch to playing state
- if (d->state != QMediaPlayer::PlayingState)
- d->_q_stateChanged(QMediaPlayer::PlayingState);
-
- if (d->rootMedia.playlist()->currentIndex() == -1) {
- if (d->playlist != d->rootMedia.playlist())
- d->setPlaylist(d->rootMedia.playlist());
- Q_ASSERT(d->playlist == d->rootMedia.playlist());
-
- emit currentMediaChanged(d->rootMedia);
- d->playlist->setCurrentIndex(0);
- }
- }
// Reset error conditions
- d->error = NoError;
- d->errorString = QString();
+ d->setError(NoError, QString());
d->control->play();
}
/*!
- Pause playing the current source.
+ \qmlmethod QtMultimedia::MediaPlayer::pause()
+
+ Pauses playback of the media.
+
+ Sets the \l playbackState property to PausedState,
+ and changes \l playing to \c false.
*/
+/*!
+ Pause playing the current source.
+
+ \sa play(), stop()
+*/
void QMediaPlayer::pause()
{
Q_D(QMediaPlayer);
- if (d->control != nullptr)
+ if (d->control)
d->control->pause();
}
/*!
- Stop playing, and reset the play position to the beginning.
+ \qmlmethod QtMultimedia::MediaPlayer::stop()
+
+ Stops playback of the media.
+
+ Sets the \l playbackState property to StoppedState,
+ and changes \l playing to \c false.
*/
+/*!
+ Stop playing, and reset the play position to the beginning.
+
+ \sa play(), pause()
+*/
void QMediaPlayer::stop()
{
Q_D(QMediaPlayer);
- if (d->control != nullptr)
+ if (d->control)
d->control->stop();
-
- // If media player didn't stop in response to control.
- // This happens if we have an active playlist and control
- // media status is
- // QMediaPlayer::LoadingMedia, QMediaPlayer::InvalidMedia, or QMediaPlayer::EndOfMedia
- // see QMediaPlayerPrivate::_q_stateChanged()
- if (d->playlist && d->state != QMediaPlayer::StoppedState) {
- d->state = QMediaPlayer::StoppedState;
- removePropertyWatch("position");
- emit stateChanged(QMediaPlayer::StoppedState);
- }
}
void QMediaPlayer::setPosition(qint64 position)
{
Q_D(QMediaPlayer);
- if (d->control == nullptr)
+ if (!d->control)
+ return;
+ if (!d->control->isSeekable())
return;
-
d->control->setPosition(qMax(position, 0ll));
}
-void QMediaPlayer::setVolume(int v)
+void QMediaPlayer::setPlaybackRate(qreal rate)
{
Q_D(QMediaPlayer);
- if (d->control == nullptr)
- return;
-
- int clamped = qBound(0, v, 100);
- if (clamped == volume())
- return;
-
- d->control->setVolume(clamped);
+ if (d->control)
+ d->control->setPlaybackRate(rate);
}
-void QMediaPlayer::setMuted(bool muted)
-{
- Q_D(QMediaPlayer);
-
- if (d->control == nullptr || muted == isMuted())
- return;
+/*!
+ \qmlproperty url QtMultimedia::MediaPlayer::source
- d->control->setMuted(muted);
-}
+ This property holds the source URL of the media.
-void QMediaPlayer::setPlaybackRate(qreal rate)
-{
- Q_D(QMediaPlayer);
+ \snippet multimedia-snippets/qtvideosink.qml complete
- if (d->control != nullptr)
- d->control->setPlaybackRate(rate);
-}
+ \sa QMediaPlayer::setSource()
+*/
/*!
- Sets the current \a media source.
+ Sets the current \a source.
- If a \a stream is supplied; media data will be read from it instead of resolving the media
- source. In this case the url should be provided to resolve additional information
- about the media such as mime type. The \a stream must be open and readable.
- For macOS the \a stream should be also seekable.
-
- Setting the media to a null QMediaContent will cause the player to discard all
+ Setting the media to a null QUrl will cause the player to discard all
information relating to the current media source and to cease all I/O operations related
- to that media.
+ to that media. Setting the media will stop the playback.
\note This function returns immediately after recording the specified source of the media.
It does not wait for the media to finish loading and does not check for errors. Listen for
the mediaStatusChanged() and error() signals to be notified when the media is loaded and
when an error occurs during loading.
- Since Qt 5.12.2, the url scheme \c gst-pipeline provides custom pipelines
- for the GStreamer backend.
+ \note FFmpeg, used by the FFmpeg media backend, restricts use of nested protocols for
+ security reasons. In controlled environments where all inputs are trusted, the list of
+ approved protocols can be overridden using the QT_FFMPEG_PROTOCOL_WHITELIST environment
+ variable. This environment variable is Qt's private API and can change between patch
+ releases without notice.
+*/
+
+void QMediaPlayer::setSource(const QUrl &source)
+{
+ Q_D(QMediaPlayer);
+ stop();
- \snippet multimedia-snippets/media.cpp Pipeline
+ if (d->source == source && d->stream == nullptr)
+ return;
- If QAbstractVideoSurface is used as the video output,
- \c qtvideosink can be used as a video sink element directly in the pipeline.
- After that the surface will receive the video frames in QAbstractVideoSurface::present().
+ d->source = source;
+ d->stream = nullptr;
- \snippet multimedia-snippets/media.cpp Pipeline Surface
+ d->setMedia(source, nullptr);
+ emit sourceChanged(d->source);
+}
- If QVideoWidget is used as the video output
- and the pipeline contains a video sink element named \c qtvideosink,
- current QVideoWidget will be used to render the video.
+/*!
+ Sets the current source \a device.
- \snippet multimedia-snippets/media.cpp Pipeline Widget
+ The media data will be read from \a device. The \a sourceUrl can be provided
+ to resolve additional information about the media, mime type etc. The
+ \a device must be open and readable.
- If the pipeline contains appsrc element, it will be used to push data from \a stream.
+ For macOS the \a device should also be seek-able.
- \snippet multimedia-snippets/media.cpp Pipeline appsrc
+ \note This function returns immediately after recording the specified source
+ of the media. It does not wait for the media to finish loading and does not
+ check for errors. Listen for the mediaStatusChanged() and error() signals to
+ be notified when the media is loaded, and if an error occurs during loading.
*/
-
-void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream)
+void QMediaPlayer::setSourceDevice(QIODevice *device, const QUrl &sourceUrl)
{
Q_D(QMediaPlayer);
stop();
- QMediaContent oldMedia = d->rootMedia;
- d->disconnectPlaylist();
- d->playlist = nullptr;
- d->rootMedia = media;
- d->nestedPlaylists = 0;
+ if (d->source == sourceUrl && d->stream == device)
+ return;
- if (oldMedia != media)
- emit mediaChanged(d->rootMedia);
+ d->source = sourceUrl;
+ d->stream = device;
- if (media.playlist()) {
- // reset playlist to the 1st item
- media.playlist()->setCurrentIndex(0);
- d->setPlaylist(media.playlist());
- } else {
- d->setMedia(media, stream);
- }
+ d->setMedia(d->source, device);
+ emit sourceChanged(d->source);
}
/*!
- \internal
+ \qmlproperty AudioOutput QtMultimedia::MediaPlayer::audioOutput
+
+ This property holds the target audio output.
+ Accepts one AudioOutput elements.
+
+ \sa QMediaPlayer::setAudioOutput()
*/
-bool QMediaPlayer::bind(QObject *obj)
-{
- return QMediaObject::bind(obj);
-}
/*!
- \internal
+ \property QMediaPlayer::audioOutput
+ \brief The audio output device used by the media player.
+
+ The current audio output to be used when playing back media. Setting
+ a new audio output will replace the currently used output.
+
+ Setting this property to \c nullptr will disable any audio output.
*/
+void QMediaPlayer::setAudioOutput(QAudioOutput *output)
+{
+ Q_D(QMediaPlayer);
+ auto oldOutput = d->audioOutput;
+ if (oldOutput == output)
+ return;
+ d->audioOutput = output;
+ if (d->control)
+ d->control->setAudioOutput(nullptr);
+ if (oldOutput)
+ oldOutput->setDisconnectFunction({});
+ if (output) {
+ output->setDisconnectFunction([this](){ setAudioOutput(nullptr); });
+ if (d->control)
+ d->control->setAudioOutput(output->handle());
+ }
+ emit audioOutputChanged();
+}
-void QMediaPlayer::unbind(QObject *obj)
+QAudioOutput *QMediaPlayer::audioOutput() const
{
- QMediaObject::unbind(obj);
+ Q_D(const QMediaPlayer);
+ return d->audioOutput;
}
/*!
- Returns the level of support a media player has for a \a mimeType and a set of \a codecs.
+ \qmlproperty list<mediaMetaData> QtMultimedia::MediaPlayer::audioTracks
- The \a flags argument allows additional requirements such as performance indicators to be
- specified.
+ This property holds a list of metadata.
+ Each index refers to an audio track.
+
+ The metadata holds properties describing the individual tracks. For
+ audio tracks the \l{QMediaMetaData}{Language} is usually the most
+ important property.
+
+ \sa mediaMetaData
*/
-QMultimedia::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
- const QStringList& codecs,
- Flags flags)
-{
- return QMediaServiceProvider::defaultServiceProvider()->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
- mimeType,
- codecs,
- flags);
-}
/*!
- \deprecated
- Returns a list of MIME types supported by the media player.
+ \property QMediaPlayer::audioTracks
- The \a flags argument causes the resultant list to be restricted to MIME types which can be supported
- given additional requirements, such as performance indicators.
+ Lists the set of available audio tracks inside the media.
- This function may not return useful results on some platforms, and support for a specific file of a
- given mime type is not guaranteed even if the mime type is in general supported. In addition, in some
- cases this function will need to load all available media plugins and query them for their support, which
- may take some time.
+ The QMediaMetaData returned describes the properties of individual
+ tracks.
+
+ Different audio tracks can for example contain audio in different languages.
*/
-QStringList QMediaPlayer::supportedMimeTypes(Flags flags)
+QList<QMediaMetaData> QMediaPlayer::audioTracks() const
{
- return QMediaServiceProvider::defaultServiceProvider()->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
- flags);
+ Q_D(const QMediaPlayer);
+ return d->trackMetaData(QPlatformMediaPlayer::AudioStream);
}
/*!
- \fn void QMediaPlayer::setVideoOutput(QVideoWidget* output)
+ \qmlproperty list<mediaMetaData> QtMultimedia::MediaPlayer::videoTracks
- Attach a QVideoWidget video \a output to the media player.
+ This property holds a list of metadata.
+ Each index refers to a video track.
- If the media player has already video output attached,
- it will be replaced with a new one.
+ The metadata holds properties describing the individual tracks.
+
+ \sa mediaMetaData
*/
-void QMediaPlayer::setVideoOutput(QVideoWidget *output)
-{
- Q_D(QMediaPlayer);
- if (d->videoOutput)
- unbind(d->videoOutput);
+/*!
+ \property QMediaPlayer::videoTracks
- // We don't know (in this library) that QVideoWidget inherits QObject
- QObject *outputObject = reinterpret_cast<QObject*>(output);
+ Lists the set of available video tracks inside the media.
- d->videoOutput = outputObject && bind(outputObject) ? outputObject : nullptr;
+ The QMediaMetaData returned describes the properties of individual
+ tracks.
+*/
+QList<QMediaMetaData> QMediaPlayer::videoTracks() const
+{
+ Q_D(const QMediaPlayer);
+ return d->trackMetaData(QPlatformMediaPlayer::VideoStream);
}
/*!
- \fn void QMediaPlayer::setVideoOutput(QGraphicsVideoItem* output)
+ \qmlproperty list<mediaMetaData> QtMultimedia::MediaPlayer::subtitleTracks
+
+ This property holds a list of metadata.
+ Each index refers to a subtitle track.
- Attach a QGraphicsVideoItem video \a output to the media player.
+ The metadata holds properties describing the individual tracks. For
+ subtitle tracks the \l{QMediaMetaData}{Language} is usually the most
+ important property.
- If the media player has already video output attached,
- it will be replaced with a new one.
+ \sa mediaMetaData
*/
-void QMediaPlayer::setVideoOutput(QGraphicsVideoItem *output)
-{
- Q_D(QMediaPlayer);
- if (d->videoOutput)
- unbind(d->videoOutput);
+/*!
+ \property QMediaPlayer::subtitleTracks
- // We don't know (in this library) that QGraphicsVideoItem (multiply) inherits QObject
- // but QObject inheritance depends on QObject coming first, so try this out.
- QObject *outputObject = reinterpret_cast<QObject*>(output);
+ Lists the set of available subtitle tracks inside the media.
- d->videoOutput = outputObject && bind(outputObject) ? outputObject : nullptr;
+ The QMediaMetaData returned describes the properties of individual
+ tracks.
+*/
+QList<QMediaMetaData> QMediaPlayer::subtitleTracks() const
+{
+ Q_D(const QMediaPlayer);
+ return d->trackMetaData(QPlatformMediaPlayer::SubtitleStream);
}
/*!
- Sets a video \a surface as the video output of a media player.
+ \qmlproperty int QtMultimedia::MediaPlayer::activeAudioTrack
- If a video output has already been set on the media player the new surface
- will replace it.
+ This property holds the track number of the currently active audio track.
+ Set to \c{-1} to disable audio track.
+
+ The default property value is \c{0}: the first audio track.
*/
-void QMediaPlayer::setVideoOutput(QAbstractVideoSurface *surface)
+/*!
+ \property QMediaPlayer::activeAudioTrack
+ \brief Returns the currently active audio track.
+
+ By default, the first available audio track will be chosen.
+
+ Set \a index to \c -1 to disable all audio tracks.
+*/
+int QMediaPlayer::activeAudioTrack() const
{
- Q_D(QMediaPlayer);
+ Q_D(const QMediaPlayer);
+ return d->control ? d->control->activeTrack(QPlatformMediaPlayer::AudioStream) : 0;
+}
+
+/*!
+ \since 6.2
+ \qmlproperty int QtMultimedia::MediaPlayer::activeVideoTrack
- d->surfaceOutput.setVideoSurface(surface);
+ This property holds the track number of the currently active video audio track.
+ Set to \c{-1} to disable video track.
- if (d->videoOutput != &d->surfaceOutput) {
- if (d->videoOutput)
- unbind(d->videoOutput);
+ The default property value is \c{0}: the first video track.
+*/
+
+/*!
+ \property QMediaPlayer::activeVideoTrack
+ \brief Returns the currently active video track.
- d->videoOutput = nullptr;
+ By default, the first available audio track will be chosen.
- if (surface && bind(&d->surfaceOutput))
- d->videoOutput = &d->surfaceOutput;
- } else if (!surface) {
- //unbind the surfaceOutput if null surface is set
- unbind(&d->surfaceOutput);
- d->videoOutput = nullptr;
- }
+ Set \a index to \c -1 to disable all video tracks.
+*/
+int QMediaPlayer::activeVideoTrack() const
+{
+ Q_D(const QMediaPlayer);
+ return d->control ? d->control->activeTrack(QPlatformMediaPlayer::VideoStream) : -1;
}
/*!
- \since 5.15
- Sets multiple video surfaces as the video output of a media player.
- This allows the media player to render video frames on different surfaces.
+ \since 6.2
+ \qmlproperty int QtMultimedia::MediaPlayer::activeSubtitleTrack
- All video surfaces must support at least one shared \c QVideoFrame::PixelFormat.
+ This property holds the track number of the currently active subtitle track.
+ Set to \c{-1} to disable subtitle track.
- If a video output has already been set on the media player the new surfaces
- will replace it.
-
- \sa QAbstractVideoSurface::supportedPixelFormats
+ The default property value is \c{-1}: no subtitles active.
*/
-void QMediaPlayer::setVideoOutput(const QList<QAbstractVideoSurface *> &surfaces)
-{
- setVideoOutput(!surfaces.empty() ? new QVideoSurfaces(surfaces, this) : nullptr);
-}
+/*!
+ \property QMediaPlayer::activeSubtitleTrack
+ \brief Returns the currently active subtitle track.
-/*! \reimp */
-QMultimedia::AvailabilityStatus QMediaPlayer::availability() const
+ Set \a index to \c -1 to disable subtitles.
+
+ Subtitles are disabled by default.
+*/
+int QMediaPlayer::activeSubtitleTrack() const
{
Q_D(const QMediaPlayer);
+ return d->control ? d->control->activeTrack(QPlatformMediaPlayer::SubtitleStream) : -1;
+}
+void QMediaPlayer::setActiveAudioTrack(int index)
+{
+ Q_D(QMediaPlayer);
if (!d->control)
- return QMultimedia::ServiceMissing;
+ return;
- return QMediaObject::availability();
+ if (activeAudioTrack() == index)
+ return;
+ d->control->setActiveTrack(QPlatformMediaPlayer::AudioStream, index);
}
-QAudio::Role QMediaPlayer::audioRole() const
+void QMediaPlayer::setActiveVideoTrack(int index)
{
- Q_D(const QMediaPlayer);
-
- if (d->audioRoleControl != nullptr)
- return d->audioRoleControl->audioRole();
+ Q_D(QMediaPlayer);
+ if (!d->control)
+ return;
- return QAudio::UnknownRole;
+ if (activeVideoTrack() == index)
+ return;
+ d->control->setActiveTrack(QPlatformMediaPlayer::VideoStream, index);
}
-void QMediaPlayer::setAudioRole(QAudio::Role audioRole)
+void QMediaPlayer::setActiveSubtitleTrack(int index)
{
Q_D(QMediaPlayer);
+ if (!d->control)
+ return;
- if (d->audioRoleControl) {
- if (d->customAudioRoleControl != nullptr && d->audioRoleControl->audioRole() != audioRole) {
- d->customAudioRoleControl->setCustomAudioRole(QString());
- }
-
- d->audioRoleControl->setAudioRole(audioRole);
- }
+ if (activeSubtitleTrack() == index)
+ return;
+ d->control->setActiveTrack(QPlatformMediaPlayer::SubtitleStream, index);
}
/*!
- Returns a list of supported audio roles.
+ \qmlproperty VideoOutput QtMultimedia::MediaPlayer::videoOutput
+
+ This property holds the target video output.
+ Accepts one VideoOutput elements.
+
+ \sa QMediaPlayer::setVideoOutput()
+*/
+
+/*!
+ \property QMediaPlayer::videoOutput
+ \brief The video output to be used by the media player.
- If setting the audio role is not supported, an empty list is returned.
+ A media player can only have one video output attached, so
+ setting this property will replace the previously connected
+ video output.
- \since 5.6
- \sa audioRole
+ Setting this property to \c nullptr will disable video output.
*/
-QList<QAudio::Role> QMediaPlayer::supportedAudioRoles() const
+QObject *QMediaPlayer::videoOutput() const
{
Q_D(const QMediaPlayer);
+ return d->videoOutput;
+}
- if (d->audioRoleControl)
- return d->audioRoleControl->supportedAudioRoles();
+void QMediaPlayer::setVideoOutput(QObject *output)
+{
+ Q_D(QMediaPlayer);
+ if (d->videoOutput == output)
+ return;
- return QList<QAudio::Role>();
+ auto *sink = qobject_cast<QVideoSink *>(output);
+ if (!sink && output) {
+ auto *mo = output->metaObject();
+ mo->invokeMethod(output, "videoSink", Q_RETURN_ARG(QVideoSink *, sink));
+ }
+ d->videoOutput = output;
+ d->setVideoSink(sink);
}
-QString QMediaPlayer::customAudioRole() const
+/*!
+ Sets \a sink to be the QVideoSink instance to
+ retrieve video data.
+*/
+void QMediaPlayer::setVideoSink(QVideoSink *sink)
+{
+ Q_D(QMediaPlayer);
+ d->videoOutput = nullptr;
+ d->setVideoSink(sink);
+}
+
+/*!
+ Returns the QVideoSink instance.
+*/
+QVideoSink *QMediaPlayer::videoSink() const
{
Q_D(const QMediaPlayer);
+ return d->videoSink;
+}
- if (audioRole() != QAudio::CustomRole)
- return QString();
- if (d->customAudioRoleControl != nullptr)
- return d->customAudioRoleControl->customAudioRole();
+#if 0
+/*
+ \since 5.15
+ Sets multiple video sinks as the video output of a media player.
+ This allows the media player to render video frames on several outputs.
- return QString();
+ If a video output has already been set on the media player the new surfaces
+ will replace it.
+*/
+void QMediaPlayer::setVideoOutput(const QList<QVideoSink *> &sinks)
+{
+ // ### IMPLEMENT ME
+ Q_UNUSED(sinks);
+// setVideoOutput(!surfaces.empty() ? new QVideoSurfaces(surfaces, this) : nullptr);
}
+#endif
-void QMediaPlayer::setCustomAudioRole(const QString &audioRole)
+/*!
+ Returns true if the media player is supported on this platform.
+*/
+bool QMediaPlayer::isAvailable() const
{
- Q_D(QMediaPlayer);
-
- if (d->customAudioRoleControl) {
- Q_ASSERT(d->audioRoleControl);
- setAudioRole(QAudio::CustomRole);
- d->customAudioRoleControl->setCustomAudioRole(audioRole);
- }
+ Q_D(const QMediaPlayer);
+ return bool(d->control);
}
/*!
- Returns a list of supported custom audio roles. An empty list may
- indicate that the supported custom audio roles aren't known. The
- list may not be complete.
+ \qmlproperty mediaMetaData QtMultimedia::MediaPlayer::metaData
+
+ Returns meta data for the current media used by the media player.
+
+ Meta data can contain information such as the title of the video or its creation date.
- \since 5.11
- \sa customAudioRole
+ \note The Windows implementation provides metadata only for media located on the local file
+ system.
*/
-QStringList QMediaPlayer::supportedCustomAudioRoles() const
-{
- Q_D(const QMediaPlayer);
- if (d->customAudioRoleControl)
- return d->customAudioRoleControl->supportedCustomAudioRoles();
+/*!
+ \property QMediaPlayer::metaData
+
+ Returns meta data for the current media used by the media player.
- return QStringList();
+ Meta data can contain information such as the title of the video or its creation date.
+
+ \note The Windows implementation provides metadata only for media located on the local file
+ system.
+*/
+QMediaMetaData QMediaPlayer::metaData() const
+{
+ Q_D(const QMediaPlayer);
+ return d->control ? d->control->metaData() : QMediaMetaData{};
}
// Enums
/*!
- \enum QMediaPlayer::State
+ \enum QMediaPlayer::PlaybackState
Defines the current state of a media player.
\value StoppedState The media player is not playing content, playback will begin from the start
of the current track.
- \value PlayingState The media player is currently playing content.
+ \value PlayingState The media player is currently playing content. This indicates the same as the \l playing property.
\value PausedState The media player has paused playback, playback of the current track will
resume from the position the player was paused at.
*/
/*!
+ \qmlproperty enumeration QtMultimedia::MediaPlayer::playbackState
+
+ This property holds the state of media playback. It can be one of the following:
+
+ \table
+ \header \li Property value
+ \li Description
+ \row \li PlayingState
+ \li The media is currently playing. This indicates the same as the \l playing property.
+ \row \li PausedState
+ \li Playback of the media has been suspended.
+ \row \li StoppedState
+ \li Playback of the media is yet to begin.
+ \endtable
+*/
+
+/*!
+ \qmlsignal QtMultimedia::MediaPlayer::playbackStateChanged()
+
+ This signal is emitted when the \l playbackState property is altered.
+*/
+
+/*!
+ \qmlsignal QtMultimedia::MediaPlayer::playingChanged()
+
+ This signal is emitted when the \l playing property changes.
+*/
+
+/*!
\enum QMediaPlayer::MediaStatus
Defines the status of a media player's current media.
- \value UnknownMediaStatus The status of the media cannot be determined.
- \value NoMedia There is no current media. The player is in the StoppedState.
+ \value NoMedia The is no current media. The player is in the StoppedState.
\value LoadingMedia The current media is being loaded. The player may be in any state.
\value LoadedMedia The current media has been loaded. The player is in the StoppedState.
\value StalledMedia Playback of the current media has stalled due to insufficient buffering or
@@ -1294,6 +1053,54 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
*/
/*!
+ \qmlproperty enumeration QtMultimedia::MediaPlayer::mediaStatus
+
+ This property holds the status of media loading. It can be one of the following:
+
+ \table
+ \header
+ \li Property value
+ \li Description
+ \row \li NoMedia
+ \li No media has been set.
+ \row \li LoadingMedia
+ \li The media is currently being loaded.
+ \row \li LoadedMedia
+ \li The media has been loaded.
+ \row \li BufferingMedia
+ \li The media is buffering data.
+ \row \li StalledMedia
+ \li Playback has been interrupted while the media is buffering data.
+ \row \li BufferedMedia
+ \li The media has buffered data.
+ \row \li EndOfMedia
+ \li The media has played to the end.
+ \row \li InvalidMedia
+ \li The media cannot be played.
+ \endtable
+*/
+
+/*!
+ \qmlproperty enumeration QtMultimedia::MediaPlayer::error
+
+ This property holds the error state of the audio. It can be one of the following.
+
+ \table
+ \header \li Value \li Description
+ \row \li NoError
+ \li There is no current error.
+ \row \li ResourceError
+ \li The audio cannot be played due to a problem allocating resources.
+ \row \li FormatError
+ \li The audio format is not supported.
+ \row \li NetworkError
+ \li The audio cannot be played due to network issues.
+ \row \li AccessDeniedError
+ \li The audio cannot be played due to insufficient permissions.
+ \endtable
+*/
+
+/*!
\enum QMediaPlayer::Error
Defines a media player error condition.
@@ -1304,23 +1111,24 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
be possible, but without an audio or video component.
\value NetworkError A network error occurred.
\value AccessDeniedError There are not the appropriate permissions to play a media resource.
- \value ServiceMissingError A valid playback service was not found, playback cannot proceed.
- \omitvalue MediaIsPlaylist
*/
-// Signals
/*!
- \fn QMediaPlayer::error(QMediaPlayer::Error error)
+ \qmlsignal QtMultimedia::MediaPlayer::errorOccurred(error, errorString)
- Signals that an \a error condition has occurred.
+ This signal is emitted when an \a error has occurred. The \a errorString
+ parameter may contain more detailed information about the error.
- \sa errorString()
+ \sa QMediaPlayer::Error
*/
/*!
- \fn void QMediaPlayer::stateChanged(State state)
+ \fn QMediaPlayer::errorOccurred(QMediaPlayer::Error error, const QString &errorString)
- Signal the \a state of the Player object has changed.
+ Signals that an \a error condition has occurred, with \a errorString
+ containing a description of the error.
+
+ \sa errorString()
*/
/*!
@@ -1332,19 +1140,9 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
*/
/*!
- \fn void QMediaPlayer::mediaChanged(const QMediaContent &media);
+ \fn void QMediaPlayer::sourceChanged(const QUrl &media);
Signals that the media source has been changed to \a media.
-
- \sa media(), currentMediaChanged()
-*/
-
-/*!
- \fn void QMediaPlayer::currentMediaChanged(const QMediaContent &media);
-
- Signals that the current playing content has been changed to \a media.
-
- \sa currentMedia(), mediaChanged()
*/
/*!
@@ -1359,33 +1157,8 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
Signals the \a seekable status of the player object has changed.
*/
-/*!
- \fn void QMediaPlayer::audioRoleChanged(QAudio::Role role)
-
- Signals that the audio \a role of the media player has changed.
-
- \since 5.6
-*/
-
-/*!
- \fn void QMediaPlayer::customAudioRoleChanged(const QString &role)
-
- Signals that the audio \a role of the media player has changed.
-
- \since 5.11
-*/
-
// Properties
/*!
- \property QMediaPlayer::state
- \brief the media player's playback state.
-
- By default this property is QMediaPlayer::Stopped
-
- \sa mediaStatus(), play(), pause(), stop()
-*/
-
-/*!
\property QMediaPlayer::error
\brief a string describing the last error condition.
@@ -1393,50 +1166,22 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
*/
/*!
- \property QMediaPlayer::media
+ \property QMediaPlayer::source
\brief the active media source being used by the player object.
- The player object will use the QMediaContent for selection of the content to
+ The player object will use the QUrl for selection of the content to
be played.
- By default this property has a null QMediaContent.
+ By default this property has a null QUrl.
- Setting this property to a null QMediaContent will cause the player to discard all
+ Setting this property to a null QUrl will cause the player to discard all
information relating to the current media source and to cease all I/O operations related
to that media.
- \sa QMediaContent, currentMedia()
+ \sa QUrl
*/
/*!
- \property QMediaPlayer::currentMedia
- \brief the current active media content being played by the player object.
- This value could be different from QMediaPlayer::media property if a playlist is used.
- In this case currentMedia indicates the current media content being processed
- by the player, while QMediaPlayer::media property contains the original playlist.
-
- \sa QMediaContent, media()
-*/
-
-/*!
- \property QMediaPlayer::playlist
- \brief the media playlist being used by the player object.
-
- The player object will use the current playlist item for selection of the content to
- be played.
-
- By default this property is set to null.
-
- If the media playlist is used as a source, QMediaPlayer::currentMedia is updated with
- a current playlist item. The current source should be selected with
- QMediaPlaylist::setCurrentIndex(int) instead of QMediaPlayer::setMedia(),
- otherwise the current playlist will be discarded.
-
- \sa QMediaContent
-*/
-
-
-/*!
\property QMediaPlayer::mediaStatus
\brief the status of the current media stream.
@@ -1445,7 +1190,15 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
By default this property is QMediaPlayer::NoMedia
- \sa state
+*/
+
+/*!
+ \qmlproperty int QtMultimedia::MediaPlayer::duration
+
+ This property holds the duration of the media in milliseconds.
+
+ If the media doesn't have a fixed duration (a live stream for example) this
+ will be set to \c{0}.
*/
/*!
@@ -1459,40 +1212,47 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
*/
/*!
- \property QMediaPlayer::position
- \brief the playback position of the current media.
+ \qmlproperty int QtMultimedia::MediaPlayer::position
The value is the current playback position, expressed in milliseconds since
the beginning of the media. Periodically changes in the position will be
- indicated with the signal positionChanged(), the interval between updates
- can be set with QMediaObject's method setNotifyInterval().
+ indicated with the positionChanged() signal.
+
+ If the \l seekable property is true, this property can be set to milliseconds.
*/
/*!
- \property QMediaPlayer::volume
- \brief the current playback volume.
-
- The playback volume is scaled linearly, ranging from \c 0 (silence) to \c 100 (full volume).
- Values outside this range will be clamped.
+ \property QMediaPlayer::position
+ \brief the playback position of the current media.
- By default the volume is \c 100.
+ The value is the current playback position, expressed in milliseconds since
+ the beginning of the media. Periodically changes in the position will be
+ indicated with the positionChanged() signal.
- UI volume controls should usually be scaled nonlinearly. For example, using a logarithmic scale
- will produce linear changes in perceived loudness, which is what a user would normally expect
- from a volume control. See QAudio::convertVolume() for more details.
+ If the \l seekable property is true, this property can be set to milliseconds.
*/
/*!
- \property QMediaPlayer::muted
- \brief the muted state of the current media.
+ \qmlproperty real QtMultimedia::MediaPlayer::bufferProgress
- The value will be true if the playback volume is muted; otherwise false.
-*/
+ This property holds how much of the data buffer is currently filled,
+ from \c 0.0 (empty) to \c 1.0 (full).
+
+ Playback can start or resume only when the buffer is entirely filled.
+ When the buffer is filled, \c MediaPlayer.Buffered is true.
+ When buffer progress is between \c 0.0 and \c 1.0, \c MediaPlayer.Buffering
+ is set to \c{true}.
+
+ A value lower than \c 1.0 implies that the property \c MediaPlayer.StalledMedia
+ is \c{true}.
+
+ \sa mediaStatus
+ */
/*!
- \property QMediaPlayer::bufferStatus
+ \property QMediaPlayer::bufferProgress
\brief the percentage of the temporary buffer filled before playback begins or resumes, from
- \c 0 (empty) to \c 100 (full).
+ \c 0. (empty) to \c 1. (full).
When the player object is buffering; this property holds the percentage of
the temporary buffer that is filled. The buffer will need to reach 100%
@@ -1504,24 +1264,9 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
*/
/*!
- \property QMediaPlayer::audioAvailable
- \brief the audio availabilty status for the current media.
-
- As the life time of QMediaPlayer can be longer than the playback of one
- QMediaContent, this property may change over time, the
- audioAvailableChanged signal can be used to monitor it's status.
-*/
-
-/*!
- \property QMediaPlayer::videoAvailable
- \brief the video availability status for the current media.
-
- If available, the QVideoWidget class can be used to view the video. As the
- life time of QMediaPlayer can be longer than the playback of one
- QMediaContent, this property may change over time, the
- videoAvailableChanged signal can be used to monitor it's status.
+ \qmlproperty bool QtMultimedia::MediaPlayer::seekable
- \sa QVideoWidget, QMediaContent
+ This property holds whether the \l position of the media can be changed.
*/
/*!
@@ -1534,108 +1279,77 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
*/
/*!
- \property QMediaPlayer::playbackRate
- \brief the playback rate of the current media.
+ \qmlproperty bool QtMultimedia::MediaPlayer::playing
+ \since 6.5
- This value is a multiplier applied to the media's standard play rate. By
- default this value is 1.0, indicating that the media is playing at the
- standard pace. Values higher than 1.0 will increase the rate of play.
- Values less than zero can be set and indicate the media should rewind at the
- multiplier of the standard pace.
+ Indicates whether the media is currently playing.
- Not all playback services support change of the playback rate. It is
- framework defined as to the status and quality of audio and video
- while fast forwarding or rewinding.
+ \sa playbackState
*/
/*!
- \property QMediaPlayer::audioRole
- \brief the role of the audio stream played by the media player.
-
- It can be set to specify the type of audio being played, allowing the system to make
- appropriate decisions when it comes to volume, routing or post-processing.
+ \property QMediaPlayer::playing
+ \brief Whether the media is playing.
+ \since 6.5
- The audio role must be set before calling setMedia().
-
- customAudioRole is cleared when this property is set to anything other than
- QAudio::CustomRole.
-
- \since 5.6
- \sa supportedAudioRoles()
+ \sa playbackState, PlayingState
*/
/*!
- \property QMediaPlayer::customAudioRole
- \brief the role of the audio stream played by the media player.
+ \qmlproperty real QtMultimedia::MediaPlayer::playbackRate
- It can be set to specify the type of audio being played when the backend supports
- audio roles unknown to Qt. Specifying a role allows the system to make appropriate
- decisions when it comes to volume, routing or post-processing.
+ This property holds the rate at which media is played at as a multiple of
+ the normal rate.
- The audio role must be set before calling setMedia().
+ For more information, see \l{QMediaPlayer::playbackRate}.
- audioRole is set to QAudio::CustomRole when this property is set.
-
- \since 5.11
- \sa supportedCustomAudioRoles()
+ Defaults to \c{1.0}.
*/
/*!
- \fn void QMediaPlayer::durationChanged(qint64 duration)
+ \property QMediaPlayer::playbackRate
+ \brief the playback rate of the current media.
- Signal the duration of the content has changed to \a duration, expressed in milliseconds.
-*/
+ This value is a multiplier applied to the media's standard playback
+ rate. By default this value is 1.0, indicating that the media is
+ playing at the standard speed. Values higher than 1.0 will increase
+ the playback speed, while values between 0.0 and 1.0 results in
+ slower playback. Negative playback rates are not supported.
-/*!
- \fn void QMediaPlayer::positionChanged(qint64 position)
-
- Signal the position of the content has changed to \a position, expressed in
- milliseconds.
+ Not all playback services support change of the playback rate. It is
+ framework defined as to the status and quality of audio and video
+ while fast forwarding or rewinding.
*/
/*!
- \fn void QMediaPlayer::volumeChanged(int volume)
+ \fn void QMediaPlayer::durationChanged(qint64 duration)
- Signal the playback volume has changed to \a volume.
+ Signals the duration of the content has changed to \a duration, expressed in milliseconds.
*/
/*!
- \fn void QMediaPlayer::mutedChanged(bool muted)
+ \fn void QMediaPlayer::positionChanged(qint64 position)
- Signal the mute state has changed to \a muted.
+ Signals the position of the content has changed to \a position, expressed in
+ milliseconds.
*/
/*!
- \fn void QMediaPlayer::videoAvailableChanged(bool videoAvailable)
+ \fn void QMediaPlayer::hasVideoChanged(bool videoAvailable)
- Signal the availability of visual content has changed to \a videoAvailable.
+ Signals the availability of visual content has changed to \a videoAvailable.
*/
/*!
- \fn void QMediaPlayer::audioAvailableChanged(bool available)
+ \fn void QMediaPlayer::hasAudioChanged(bool available)
Signals the availability of audio content has changed to \a available.
*/
/*!
- \fn void QMediaPlayer::bufferStatusChanged(int percentFilled)
-
- Signal the amount of the local buffer filled as a percentage by \a percentFilled.
-*/
-
-/*!
- \enum QMediaPlayer::Flag
-
- \value LowLatency The player is expected to be used with simple audio formats,
- but playback should start without significant delay.
- Such playback service can be used for beeps, ringtones, etc.
-
- \value StreamPlayback The player is expected to play QIODevice based streams.
- If passed to QMediaPlayer constructor, the service supporting
- streams playback will be chosen.
+ \fn void QMediaPlayer::bufferProgressChanged(float filled)
- \value VideoSurface The player is expected to be able to render to a
- QAbstractVideoSurface \l {setVideoOutput()}{output}.
+ Signals the amount of the local buffer \a filled as a number between 0 and 1.
*/
QT_END_NAMESPACE