summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames McDonnell <jmcdonnell@blackberry.com>2017-03-28 17:23:25 -0400
committerJames McDonnell <jmcdonnell@blackberry.com>2017-10-23 14:10:43 +0000
commit82694e41b1d37e04ecc911f420ad4317220f8180 (patch)
tree831804b09c5fc36be0e103444c596149771d4a78
parent66c0334a3c4cb8deb63c67aa70da3f4ed94f89a4 (diff)
Propagate customAudioRole into the QML classes
Propagate customAudioRole into the Audio, MediaPlayer and Video classes. [ChangeLog][Audio/Video/MediaPlayer] Added customAudioRole string property to enable use of audio roles beyond those available via the audioRole enum property. Change-Id: If3c4ec20f014653d31d1fa0d1ad925084f446478 Reviewed-by: Christian Stromme <christian.stromme@qt.io>
-rw-r--r--src/imports/multimedia/Video.qml20
-rw-r--r--src/imports/multimedia/multimedia.cpp4
-rw-r--r--src/imports/multimedia/qdeclarativeaudio.cpp62
-rw-r--r--src/imports/multimedia/qdeclarativeaudio_p.h6
-rw-r--r--tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp150
5 files changed, 241 insertions, 1 deletions
diff --git a/src/imports/multimedia/Video.qml b/src/imports/multimedia/Video.qml
index 66b86c74b..19c437869 100644
--- a/src/imports/multimedia/Video.qml
+++ b/src/imports/multimedia/Video.qml
@@ -38,7 +38,7 @@
****************************************************************************/
import QtQuick 2.0
-import QtMultimedia 5.9
+import QtMultimedia 5.11
/*!
\qmltype Video
@@ -302,13 +302,31 @@ Item {
\li MediaPlayer.AccessibilityRole - for accessibility, such as with a screen reader.
\li MediaPlayer.SonificationRole - sonification, such as with user interface sounds.
\li MediaPlayer.GameRole - game audio.
+ \li MediaPlayer.CustomRole - The role is specified by customAudioRole.
\endlist
+ customAudioRole is cleared when this property is set to anything other than CustomRole.
+
\since 5.6
*/
property alias audioRole: player.audioRole
/*!
+ \qmlproperty string Video::customAudioRole
+
+ This property holds the role of the audio stream when the backend supports audio roles
+ unknown to Qt. 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.
+
+ The audio role must be set before setting the source property.
+
+ audioRole is set to CustomRole when this property is set.
+
+ \since 5.11
+ */
+ property alias customAudioRole: player.customAudioRole
+
+ /*!
\qmlproperty bool Video::seekable
This property holds whether the playback position of the video can be
diff --git a/src/imports/multimedia/multimedia.cpp b/src/imports/multimedia/multimedia.cpp
index 6a316a298..a95ababfb 100644
--- a/src/imports/multimedia/multimedia.cpp
+++ b/src/imports/multimedia/multimedia.cpp
@@ -151,6 +151,10 @@ public:
qmlRegisterUncreatableType<QDeclarativeCameraFlash, 1>(uri, 5, 9, "CameraFlash",
trUtf8("CameraFlash is provided by Camera"));
+ // 5.11 types
+ qmlRegisterType<QDeclarativeAudio, 3>(uri, 5, 11, "Audio");
+ qmlRegisterType<QDeclarativeAudio, 3>(uri, 5, 11, "MediaPlayer");
+
qmlRegisterType<QDeclarativeMediaMetaData>();
qmlRegisterType<QAbstractVideoFilter>();
}
diff --git a/src/imports/multimedia/qdeclarativeaudio.cpp b/src/imports/multimedia/qdeclarativeaudio.cpp
index 652296509..65606b3cf 100644
--- a/src/imports/multimedia/qdeclarativeaudio.cpp
+++ b/src/imports/multimedia/qdeclarativeaudio.cpp
@@ -179,8 +179,11 @@ QDeclarativeAudio::Availability QDeclarativeAudio::availability() const
\li AccessibilityRole - for accessibility, such as with a screen reader.
\li SonificationRole - sonification, such as with user interface sounds.
\li GameRole - game audio.
+ \li CustomRole - The role is specified by customAudioRole.
\endlist
+ customAudioRole is cleared when this property is set to anything other than CustomRole.
+
\since 5.6
*/
QDeclarativeAudio::AudioRole QDeclarativeAudio::audioRole() const
@@ -196,12 +199,49 @@ void QDeclarativeAudio::setAudioRole(QDeclarativeAudio::AudioRole audioRole)
if (m_complete) {
m_player->setAudioRole(QAudio::Role(audioRole));
} else {
+ if (!m_customAudioRole.isEmpty()) {
+ m_customAudioRole.clear();
+ emit customAudioRoleChanged();
+ }
m_audioRole = audioRole;
emit audioRoleChanged();
}
}
/*!
+ \qmlproperty string QtMultimedia::Audio::customAudioRole
+
+ This property holds the role of the audio stream when the backend supports audio
+ roles unknown to Qt. 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.
+
+ The audio role must be set before setting the source property.
+
+ audioRole is set to CustomRole when this property is set.
+
+ \since 5.11
+*/
+QString QDeclarativeAudio::customAudioRole() const
+{
+ return !m_complete ? m_customAudioRole : m_player->customAudioRole();
+}
+
+void QDeclarativeAudio::setCustomAudioRole(const QString &audioRole)
+{
+ if (this->customAudioRole() == audioRole)
+ return;
+
+ if (m_complete) {
+ m_player->setCustomAudioRole(audioRole);
+ } else {
+ setAudioRole(QDeclarativeAudio::CustomRole);
+ m_customAudioRole = audioRole;
+ emit customAudioRoleChanged();
+ }
+}
+
+/*!
\qmlproperty int QtMultimedia::Audio::notifyInterval
The interval at which notifiable properties will update.
@@ -850,6 +890,8 @@ void QDeclarativeAudio::classBegin()
this, SIGNAL(hasVideoChanged()));
connect(m_player, SIGNAL(audioRoleChanged(QAudio::Role)),
this, SIGNAL(audioRoleChanged()));
+ connect(m_player, SIGNAL(customAudioRoleChanged(const QString &)),
+ this, SIGNAL(customAudioRoleChanged()));
connect(m_player, SIGNAL(notifyIntervalChanged(int)),
this, SIGNAL(notifyIntervalChanged()));
@@ -876,6 +918,8 @@ void QDeclarativeAudio::componentComplete()
m_player->setPlaybackRate(m_playbackRate);
if (m_audioRole != UnknownRole)
m_player->setAudioRole(QAudio::Role(m_audioRole));
+ if (!m_customAudioRole.isEmpty())
+ m_player->setCustomAudioRole(m_customAudioRole);
if (m_notifyInterval != m_player->notifyInterval())
m_player->setNotifyInterval(m_notifyInterval);
@@ -1181,12 +1225,30 @@ void QDeclarativeAudio::_q_mediaChanged(const QMediaContent &media)
\li AccessibilityRole - for accessibility, such as with a screen reader.
\li SonificationRole - sonification, such as with user interface sounds.
\li GameRole - game audio.
+ \li CustomRole - The role is specified by customAudioRole.
\endlist
+ customAudioRole is cleared when this property is set to anything other than CustomRole.
+
\since 5.6
*/
/*!
+ \qmlproperty string QtMultimedia::MediaPlayer::customAudioRole
+
+ This property holds the role of the audio stream when the backend supports audio
+ roles unknown to Qt. 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.
+
+ The audio role must be set before setting the source property.
+
+ audioRole is set to CustomRole when this property is set.
+
+ \since 5.11
+*/
+
+/*!
\qmlmethod list<int> QtMultimedia::MediaPlayer::supportedAudioRoles()
Returns a list of supported audio roles.
diff --git a/src/imports/multimedia/qdeclarativeaudio_p.h b/src/imports/multimedia/qdeclarativeaudio_p.h
index 4e2b94300..043b36042 100644
--- a/src/imports/multimedia/qdeclarativeaudio_p.h
+++ b/src/imports/multimedia/qdeclarativeaudio_p.h
@@ -95,6 +95,7 @@ class QDeclarativeAudio : public QObject, public QQmlParserStatus
Q_PROPERTY(QObject *mediaObject READ mediaObject NOTIFY mediaObjectChanged SCRIPTABLE false DESIGNABLE false)
Q_PROPERTY(Availability availability READ availability NOTIFY availabilityChanged)
Q_PROPERTY(AudioRole audioRole READ audioRole WRITE setAudioRole NOTIFY audioRoleChanged REVISION 1)
+ Q_PROPERTY(QString customAudioRole READ customAudioRole WRITE setCustomAudioRole NOTIFY customAudioRoleChanged REVISION 3)
Q_PROPERTY(int notifyInterval READ notifyInterval WRITE setNotifyInterval NOTIFY notifyIntervalChanged REVISION 2)
Q_ENUMS(Status)
Q_ENUMS(Error)
@@ -150,6 +151,7 @@ public:
UnknownRole = QAudio::UnknownRole,
AccessibilityRole = QAudio::AccessibilityRole,
AlarmRole = QAudio::AlarmRole,
+ CustomRole = QAudio::CustomRole,
GameRole = QAudio::GameRole,
MusicRole = QAudio::MusicRole,
NotificationRole = QAudio::NotificationRole,
@@ -179,6 +181,8 @@ public:
AudioRole audioRole() const;
void setAudioRole(AudioRole audioRole);
+ QString customAudioRole() const;
+ void setCustomAudioRole(const QString &audioRole);
QUrl source() const;
void setSource(const QUrl &url);
@@ -256,6 +260,7 @@ Q_SIGNALS:
void playbackRateChanged();
Q_REVISION(1) void audioRoleChanged();
+ Q_REVISION(3) void customAudioRoleChanged();
void availabilityChanged(Availability availability);
@@ -287,6 +292,7 @@ private:
qreal m_vol;
qreal m_playbackRate;
AudioRole m_audioRole;
+ QString m_customAudioRole;
QMediaPlayer::State m_playbackState;
QMediaPlayer::MediaStatus m_status;
diff --git a/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp b/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
index 5ff557ef6..b270e93eb 100644
--- a/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
+++ b/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
@@ -74,6 +74,13 @@ private slots:
void error();
void loops();
void audioRole();
+ void customAudioRole();
+
+private:
+ void enumerator(const QMetaObject *object, const char *name, QMetaEnum *result);
+ QMetaEnum enumerator(const QMetaObject *object, const char *name);
+ void keyToValue(const QMetaEnum &enumeration, const char *key, int *result);
+ int keyToValue(const QMetaEnum &enumeration, const char *key);
};
Q_DECLARE_METATYPE(QDeclarativeAudio::Error);
@@ -1051,6 +1058,149 @@ void tst_QDeclarativeAudio::audioRole()
}
}
+void tst_QDeclarativeAudio::customAudioRole()
+{
+ MockMediaPlayerService mockService;
+ MockMediaServiceProvider mockProvider(&mockService);
+ QMediaServiceProvider::setDefaultServiceProvider(&mockProvider);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0 \n import QtMultimedia 5.11 \n Audio { }", QUrl());
+
+ {
+ mockService.setHasCustomAudioRole(false);
+ QObject *audio = component.create();
+ QVERIFY(audio);
+
+ QMetaEnum audioRoleEnum = enumerator(audio->metaObject(), "AudioRole");
+ int AudioRole_UnknownRoleValue = keyToValue(audioRoleEnum, "UnknownRole");
+ QVERIFY(!QTest::currentTestFailed());
+
+ QVERIFY(audio->property("customAudioRole").toString().isEmpty());
+
+ QSignalSpy spyRole(audio, SIGNAL(audioRoleChanged()));
+ QSignalSpy spyCustomRole(audio, SIGNAL(customAudioRoleChanged()));
+ audio->setProperty("customAudioRole", QStringLiteral("customRole"));
+ QCOMPARE(audio->property("audioRole").toInt(), AudioRole_UnknownRoleValue);
+ QVERIFY(audio->property("customAudioRole").toString().isEmpty());
+ QCOMPARE(spyRole.count(), 0);
+ QCOMPARE(spyCustomRole.count(), 0);
+ }
+
+ {
+ mockService.reset();
+ mockService.setHasAudioRole(false);
+
+ QObject *audio = component.create();
+ QVERIFY(audio);
+
+ QMetaEnum audioRoleEnum = enumerator(audio->metaObject(), "AudioRole");
+ int AudioRole_UnknownRoleValue = keyToValue(audioRoleEnum, "UnknownRole");
+ QVERIFY(!QTest::currentTestFailed());
+
+ QVERIFY(audio->property("customAudioRole").toString().isEmpty());
+
+ QSignalSpy spyRole(audio, SIGNAL(audioRoleChanged()));
+ QSignalSpy spyCustomRole(audio, SIGNAL(customAudioRoleChanged()));
+ audio->setProperty("customAudioRole", QStringLiteral("customRole"));
+ QCOMPARE(audio->property("audioRole").toInt(), AudioRole_UnknownRoleValue);
+ QVERIFY(audio->property("customAudioRole").toString().isEmpty());
+ QCOMPARE(spyRole.count(), 0);
+ QCOMPARE(spyCustomRole.count(), 0);
+ }
+
+ {
+ mockService.reset();
+
+ QObject *audio = component.create();
+ QVERIFY(audio);
+
+ QMetaEnum audioRoleEnum = enumerator(audio->metaObject(), "AudioRole");
+ int AudioRole_UnknownRoleValue = keyToValue(audioRoleEnum, "UnknownRole");
+ int AudioRole_CustomRoleValue = keyToValue(audioRoleEnum, "CustomRole");
+ int AudioRole_MusicRoleValue = keyToValue(audioRoleEnum, "MusicRole");
+ QVERIFY(!QTest::currentTestFailed());
+
+ QSignalSpy spyRole(audio, SIGNAL(audioRoleChanged()));
+ QSignalSpy spyCustomRole(audio, SIGNAL(customAudioRoleChanged()));
+
+ QCOMPARE(audio->property("audioRole").toInt(), AudioRole_UnknownRoleValue);
+ QVERIFY(audio->property("customAudioRole").toString().isEmpty());
+
+ QString customRole(QStringLiteral("customRole"));
+ audio->setProperty("customAudioRole", customRole);
+ QCOMPARE(audio->property("audioRole").toInt(), AudioRole_CustomRoleValue);
+ QCOMPARE(audio->property("customAudioRole").toString(), customRole);
+ QCOMPARE(mockService.mockAudioRoleControl->audioRole(), QAudio::CustomRole);
+ QCOMPARE(mockService.mockCustomAudioRoleControl->customAudioRole(), customRole);
+ QCOMPARE(spyRole.count(), 1);
+ QCOMPARE(spyCustomRole.count(), 1);
+
+ spyRole.clear();
+ spyCustomRole.clear();
+
+ QString customRole2(QStringLiteral("customRole2"));
+ audio->setProperty("customAudioRole", customRole2);
+ QCOMPARE(audio->property("customAudioRole").toString(), customRole2);
+ QCOMPARE(mockService.mockCustomAudioRoleControl->customAudioRole(), customRole2);
+ QCOMPARE(spyRole.count(), 0);
+ QCOMPARE(spyCustomRole.count(), 1);
+
+ spyRole.clear();
+ spyCustomRole.clear();
+
+ audio->setProperty("audioRole", AudioRole_MusicRoleValue);
+ QCOMPARE(audio->property("audioRole").toInt(), AudioRole_MusicRoleValue);
+ QVERIFY(audio->property("customAudioRole").toString().isEmpty());
+ QCOMPARE(mockService.mockAudioRoleControl->audioRole(), QAudio::MusicRole);
+ QVERIFY(mockService.mockCustomAudioRoleControl->customAudioRole().isEmpty());
+ QCOMPARE(spyRole.count(), 1);
+ QCOMPARE(spyCustomRole.count(), 1);
+
+ spyRole.clear();
+ spyCustomRole.clear();
+
+ audio->setProperty("audioRole", AudioRole_CustomRoleValue);
+ QCOMPARE(audio->property("audioRole").toInt(), AudioRole_CustomRoleValue);
+ QVERIFY(audio->property("customAudioRole").toString().isEmpty());
+ QCOMPARE(mockService.mockAudioRoleControl->audioRole(), QAudio::CustomRole);
+ QVERIFY(mockService.mockCustomAudioRoleControl->customAudioRole().isEmpty());
+ QCOMPARE(spyRole.count(), 1);
+ QCOMPARE(spyCustomRole.count(), 0);
+ }
+}
+
+void tst_QDeclarativeAudio::enumerator(const QMetaObject *object,
+ const char *name,
+ QMetaEnum *result)
+{
+ int index = object->indexOfEnumerator(name);
+ QVERIFY(index >= 0);
+ *result = object->enumerator(index);
+}
+
+QMetaEnum tst_QDeclarativeAudio::enumerator(const QMetaObject *object, const char *name)
+{
+ QMetaEnum result;
+ enumerator(object, name, &result);
+ return result;
+}
+
+void tst_QDeclarativeAudio::keyToValue(const QMetaEnum &enumeration, const char *key, int *result)
+{
+ bool ok = false;
+ *result = enumeration.keyToValue(key, &ok);
+ QVERIFY(ok);
+}
+
+int tst_QDeclarativeAudio::keyToValue(const QMetaEnum &enumeration, const char *key)
+{
+ int result;
+ keyToValue(enumeration, key, &result);
+ return result;
+}
+
QTEST_MAIN(tst_QDeclarativeAudio)
#include "tst_qdeclarativeaudio.moc"