diff options
author | James McDonnell <jmcdonnell@blackberry.com> | 2017-03-28 17:23:25 -0400 |
---|---|---|
committer | James McDonnell <jmcdonnell@blackberry.com> | 2017-10-23 14:10:43 +0000 |
commit | 82694e41b1d37e04ecc911f420ad4317220f8180 (patch) | |
tree | 831804b09c5fc36be0e103444c596149771d4a78 | |
parent | 66c0334a3c4cb8deb63c67aa70da3f4ed94f89a4 (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.qml | 20 | ||||
-rw-r--r-- | src/imports/multimedia/multimedia.cpp | 4 | ||||
-rw-r--r-- | src/imports/multimedia/qdeclarativeaudio.cpp | 62 | ||||
-rw-r--r-- | src/imports/multimedia/qdeclarativeaudio_p.h | 6 | ||||
-rw-r--r-- | tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp | 150 |
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" |