diff options
author | Samuel Mira <samuel.mira@qt.io> | 2021-08-25 09:47:52 +0300 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-08-30 13:19:55 +0000 |
commit | 4ec2f409a7e7e4df5c3300bc22fa05ec36940fa0 (patch) | |
tree | 8272257b46bbe9990470bf8ae57dd07956f96a42 | |
parent | cacc94e9601dd6b2fc9c9f70882c64dceaff6582 (diff) |
Implement audio and video track disable in Android
Android mediaplayer does not have allow to deselect video and audio tracks
To implement:
. audio tracks, the audio is forcely muted, and cannot be unmuted
unless the audio track changes.
. video tracks, the android mediaplayer display is nulled and it maintains
null until the video track changes.
Change-Id: I0fe421d1775b69d648ca938b5a7dfecc955776c0
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 45a17315503b2b6b41b8782e7a68e61c4922f46c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
6 files changed, 111 insertions, 29 deletions
diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp index 5ea0fcab8..5d790bda8 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp @@ -46,6 +46,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcMediaPlayer, "qt.multimedia.mediaplayer.android") + class StateChangeNotifier { public: @@ -300,10 +302,6 @@ void QAndroidMediaPlayer::setMedia(const QUrl &mediaContent, mMediaStream = stream; } - // Release the mediaplayer if it's not in in Idle or Uninitialized state - if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized)) == 0) - mMediaPlayer->release(); - if (mediaContent.isEmpty()) { setMediaStatus(QMediaPlayer::NoMedia); } else { @@ -683,10 +681,16 @@ QPlatformMediaPlayer::TrackType convertTrackType(AndroidMediaPlayer::TrackType t int QAndroidMediaPlayer::activeTrack(TrackType trackType) { switch (trackType) { - case QPlatformMediaPlayer::TrackType::VideoStream: + case QPlatformMediaPlayer::TrackType::VideoStream: { + if (!mIsVideoTrackEnabled) + return -1; return mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::Video); - case QPlatformMediaPlayer::TrackType::AudioStream: + } + case QPlatformMediaPlayer::TrackType::AudioStream: { + if (!mIsAudioTrackEnabled) + return -1; return mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::Audio); + } case QPlatformMediaPlayer::TrackType::SubtitleStream: { int timedTextSelectedTrack = mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::TimedText); @@ -707,21 +711,28 @@ int QAndroidMediaPlayer::activeTrack(TrackType trackType) return -1; } -void QAndroidMediaPlayer::setActiveTrack(TrackType trackType, int streamNumber) +void QAndroidMediaPlayer::disableTrack(TrackType trackType) { - if (!mTracksMetadata.contains(trackType)) { - qDebug() << "Trying to set a active track of a type that does not exist"; - return; - } + const auto track = activeTrack(trackType); - const auto &tracks = mTracksMetadata.value(trackType); - if (streamNumber > tracks.count()) { - return; + switch (trackType) { + case VideoStream: { + if (track > -1) { + mMediaPlayer->setDisplay(nullptr); + mIsVideoTrackEnabled = false; + } + break; } - - if (trackType == TrackType::SubtitleStream) { - // subtitles and timedtext tracks can be selected at the same time so deselect both before - // selection + case AudioStream: { + if (track > -1) { + mMediaPlayer->setMuted(true); + mMediaPlayer->blockAudio(); + mIsAudioTrackEnabled = false; + } + break; + } + case SubtitleStream: { + // subtitles and timedtext tracks can be selected at the same time so deselect both int subtitleSelectedTrack = mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::Subtitle); if (subtitleSelectedTrack > -1) @@ -732,13 +743,61 @@ void QAndroidMediaPlayer::setActiveTrack(TrackType trackType, int streamNumber) if (timedTextSelectedTrack > -1) mMediaPlayer->deselectTrack(timedTextSelectedTrack); - // in case of < 0 just deselect all - no subtitle selected. - if (streamNumber < 0) - return; + break; + } + case NTrackTypes: + break; + } +} + +void QAndroidMediaPlayer::setActiveTrack(TrackType trackType, int streamNumber) +{ + + if (!mTracksMetadata.contains(trackType)) { + qCWarning(lcMediaPlayer) + << "Trying to set a active track which type has no available tracks."; + return; + } + + const auto &tracks = mTracksMetadata.value(trackType); + if (streamNumber > tracks.count()) { + qCWarning(lcMediaPlayer) << "Trying to set a active track that does not exist."; + return; + } + + // in case of < 0 deselect tracktype + if (streamNumber < 0) { + disableTrack(trackType); + return; + } + + const auto currentTrack = activeTrack(trackType); + if (streamNumber == currentTrack) { + return; + } + + if (trackType == TrackType::VideoStream && !mIsVideoTrackEnabled) { + // enable video stream + mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); + mIsVideoTrackEnabled = true; + } + + if (trackType == TrackType::AudioStream && !mIsAudioTrackEnabled) { + // enable audio stream + mMediaPlayer->unblockAudio(); + mMediaPlayer->setMuted(false); + mIsAudioTrackEnabled = true; + } + + if (trackType == TrackType::SubtitleStream) { + // subtitles and timedtext tracks can be selected at the same time so deselect both before + // selecting a new one + disableTrack(TrackType::SubtitleStream); } - auto trackInfo = tracks.at(streamNumber); - mMediaPlayer->selectTrack(trackInfo.androidTrackNumber()); + const auto &trackInfo = tracks.at(streamNumber); + const auto &trackNumber = trackInfo.androidTrackNumber(); + mMediaPlayer->selectTrack(trackNumber); } void QAndroidMediaPlayer::positionChanged(qint64 position) diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h index 2d316876a..315659559 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h @@ -139,6 +139,9 @@ private: bool mHasPendingPlaybackRate = false; // we need this because the rate can theoretically be negative QMap<TrackType, QList<QAndroidMetaData>> mTracksMetadata; + bool mIsVideoTrackEnabled = true; + bool mIsAudioTrackEnabled = true; + void setMediaStatus(QMediaPlayer::MediaStatus status); void setAudioAvailable(bool available); void setVideoAvailable(bool available); @@ -148,6 +151,7 @@ private: void updateBufferStatus(); void updateTrackInfo(); void setSubtitle(QString subtitle); + void disableTrack(TrackType trackType); friend class StateChangeNotifier; }; diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp index 8f7d39efa..059b62b52 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp +++ b/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp @@ -184,17 +184,17 @@ QAndroidMetaData::QAndroidMetaData(int trackType, int androidTrackType, int andr insert(QMediaMetaData::Language, getLocaleLanguage(language)); } -int QAndroidMetaData::trackType() +int QAndroidMetaData::trackType() const { return mTrackType; } -int QAndroidMetaData::androidTrackType() +int QAndroidMetaData::androidTrackType() const { return mAndroidTrackType; } -int QAndroidMetaData::androidTrackNumber() +int QAndroidMetaData::androidTrackNumber() const { return mAndroidTrackNumber; } diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h index 2346806bb..812edb062 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h +++ b/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h @@ -68,9 +68,9 @@ public: QAndroidMetaData(int trackType, int androidTrackType, int androidTrackNumber, const QString &mimeType, const QString &language); - int trackType(); - int androidTrackType(); - int androidTrackNumber(); + int trackType() const; + int androidTrackType() const; + int androidTrackNumber() const; private: int mTrackType; diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp b/src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp index d8d1e51db..f28622d6c 100644 --- a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp +++ b/src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp @@ -243,6 +243,9 @@ void AndroidMediaPlayer::seekTo(qint32 msec) void AndroidMediaPlayer::setMuted(bool mute) { + if (mAudioBlocked) + return; + mMediaPlayer.callMethod<void>("mute", "(Z)V", jboolean(mute)); } @@ -268,9 +271,22 @@ void AndroidMediaPlayer::prepareAsync() void AndroidMediaPlayer::setVolume(int volume) { + if (mAudioBlocked) + return; + mMediaPlayer.callMethod<void>("setVolume", "(I)V", jint(volume)); } +void AndroidMediaPlayer::blockAudio() +{ + mAudioBlocked = true; +} + +void AndroidMediaPlayer::unblockAudio() +{ + mAudioBlocked = false; +} + bool AndroidMediaPlayer::setPlaybackRate(qreal rate) { if (QNativeInterface::QAndroidApplication::sdkVersion() < 23) { diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h b/src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h index 5539a709f..d5cf07f9c 100644 --- a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h +++ b/src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h @@ -146,6 +146,8 @@ public: static bool registerNativeMethods(); + void blockAudio(); + void unblockAudio(); Q_SIGNALS: void error(qint32 what, qint32 extra); void bufferingChanged(qint32 percent); @@ -159,6 +161,7 @@ Q_SIGNALS: private: QJniObject mMediaPlayer; + bool mAudioBlocked = false; }; QT_END_NAMESPACE |