From bcbab7ad8e680a7b53e9052f223a73e8b94341b8 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 31 Aug 2021 19:11:37 +0300 Subject: [PATCH] Added ability to change playback speed for long audio files. --- .../SourceFiles/data/data_audio_msg_id.cpp | 15 +++++++++- Telegram/SourceFiles/data/data_audio_msg_id.h | 4 ++- .../media/player/media_player_instance.cpp | 8 +++-- .../media/player/media_player_widget.cpp | 30 +++++++++++++------ .../media/player/media_player_widget.h | 2 ++ 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/data/data_audio_msg_id.cpp b/Telegram/SourceFiles/data/data_audio_msg_id.cpp index ee5e271ba..4c95989ac 100644 --- a/Telegram/SourceFiles/data/data_audio_msg_id.cpp +++ b/Telegram/SourceFiles/data/data_audio_msg_id.cpp @@ -9,6 +9,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document.h" +namespace { + +constexpr auto kMinLengthForChangeablePlaybackSpeed = 20 * TimeId(60); // 20 minutes. + +} // namespace + AudioMsgId::AudioMsgId() { } @@ -18,7 +24,10 @@ AudioMsgId::AudioMsgId( uint32 externalPlayId) : _audio(audio) , _contextId(msgId) -, _externalPlayId(externalPlayId) { +, _externalPlayId(externalPlayId) +, _changeablePlaybackSpeed(_audio->isVoiceMessage() + || _audio->isVideoMessage() + || (_audio->getDuration() >= kMinLengthForChangeablePlaybackSpeed)) { setTypeFromAudio(); } @@ -62,6 +71,10 @@ uint32 AudioMsgId::externalPlayId() const { return _externalPlayId; } +bool AudioMsgId::changeablePlaybackSpeed() const { + return _changeablePlaybackSpeed; +} + AudioMsgId::operator bool() const { return (_audio != nullptr) || (_externalPlayId != 0); } diff --git a/Telegram/SourceFiles/data/data_audio_msg_id.h b/Telegram/SourceFiles/data/data_audio_msg_id.h index 406c3a7fe..2951587c2 100644 --- a/Telegram/SourceFiles/data/data_audio_msg_id.h +++ b/Telegram/SourceFiles/data/data_audio_msg_id.h @@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class DocumentData; -class AudioMsgId { +class AudioMsgId final { public: enum class Type { Unknown, @@ -31,6 +31,7 @@ public: [[nodiscard]] DocumentData *audio() const; [[nodiscard]] FullMsgId contextId() const; [[nodiscard]] uint32 externalPlayId() const; + [[nodiscard]] bool changeablePlaybackSpeed() const; [[nodiscard]] explicit operator bool() const; bool operator<(const AudioMsgId &other) const; @@ -44,5 +45,6 @@ private: Type _type = Type::Unknown; FullMsgId _contextId; uint32 _externalPlayId = 0; + bool _changeablePlaybackSpeed = false; }; diff --git a/Telegram/SourceFiles/media/player/media_player_instance.cpp b/Telegram/SourceFiles/media/player/media_player_instance.cpp index 86437fb22..b26c32092 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.cpp +++ b/Telegram/SourceFiles/media/player/media_player_instance.cpp @@ -519,8 +519,7 @@ Streaming::PlaybackOptions Instance::streamingOptions( result.mode = (document && document->isVideoMessage()) ? Streaming::Mode::Both : Streaming::Mode::Audio; - result.speed = (document - && (document->isVoiceMessage() || document->isVideoMessage())) + result.speed = audioId.changeablePlaybackSpeed() ? VoicePlaybackSpeed() : 1.; result.audioId = audioId; @@ -677,7 +676,10 @@ void Instance::cancelSeeking(AudioMsgId::Type type) { } void Instance::updateVoicePlaybackSpeed() { - if (const auto data = getData(AudioMsgId::Type::Voice)) { + if (const auto data = getData(getActiveType())) { + if (!data->current.changeablePlaybackSpeed()) { + return; + } if (const auto streamed = data->streamed.get()) { streamed->instance.setSpeed(VoicePlaybackSpeed()); } diff --git a/Telegram/SourceFiles/media/player/media_player_widget.cpp b/Telegram/SourceFiles/media/player/media_player_widget.cpp index 1ba44ca21..ffc0421ad 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.cpp +++ b/Telegram/SourceFiles/media/player/media_player_widget.cpp @@ -164,6 +164,8 @@ Widget::Widget(QWidget *parent, not_null session) subscribe(instance()->trackChangedNotifier(), [this](AudioMsgId::Type type) { if (type == _type) { handleSongChange(); + updateControlsVisibility(); + updateLabelsGeometry(); } }); subscribe(instance()->tracksFinishedNotifier(), [this](AudioMsgId::Type type) { @@ -278,6 +280,10 @@ void Widget::handleSeekFinished(float64 progress) { } void Widget::resizeEvent(QResizeEvent *e) { + updateControlsGeometry(); +} + +void Widget::updateControlsGeometry() { auto right = st::mediaPlayerCloseRight; _close->moveToRight(right, st::mediaPlayerPlayTop); right += _close->width(); if (hasPlaybackSpeedControl()) { @@ -371,7 +377,8 @@ int Widget::getLabelsRight() const { auto result = st::mediaPlayerCloseRight + _close->width(); if (_type == AudioMsgId::Type::Song) { result += _repeatTrack->width() + _volumeToggle->width(); - } else if (hasPlaybackSpeedControl()) { + } + if (hasPlaybackSpeedControl()) { result += _playbackSpeed->width(); } result += st::mediaPlayerPadding; @@ -421,21 +428,26 @@ void Widget::checkForTypeChange() { } bool Widget::hasPlaybackSpeedControl() const { - return (_type == AudioMsgId::Type::Voice) + return _lastSongId.changeablePlaybackSpeed() && Media::Audio::SupportsSpeedControl(); } +void Widget::updateControlsVisibility() { + _repeatTrack->setVisible(_type == AudioMsgId::Type::Song); + _volumeToggle->setVisible(_type == AudioMsgId::Type::Song); + _playbackSpeed->setVisible(hasPlaybackSpeedControl()); + if (!_shadow->isHidden()) { + _playbackSlider->setVisible(_type == AudioMsgId::Type::Song); + } + updateControlsGeometry(); +} + void Widget::setType(AudioMsgId::Type type) { if (_type != type) { _type = type; - _repeatTrack->setVisible(_type == AudioMsgId::Type::Song); - _volumeToggle->setVisible(_type == AudioMsgId::Type::Song); - _playbackSpeed->setVisible(hasPlaybackSpeedControl()); - if (!_shadow->isHidden()) { - _playbackSlider->setVisible(_type == AudioMsgId::Type::Song); - } - updateLabelsGeometry(); handleSongChange(); + updateControlsVisibility(); + updateLabelsGeometry(); handleSongUpdate(instance()->getState(_type)); updateOverLabelsState(_labelsOver); _playlistChangesLifetime = instance()->playlistChanges( diff --git a/Telegram/SourceFiles/media/player/media_player_widget.h b/Telegram/SourceFiles/media/player/media_player_widget.h index 51c3421b8..e9d3bd747 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.h +++ b/Telegram/SourceFiles/media/player/media_player_widget.h @@ -75,6 +75,8 @@ private: void updatePlayPrevNextPositions(); void updateLabelsGeometry(); void updateRepeatTrackIcon(); + void updateControlsVisibility(); + void updateControlsGeometry(); void updatePlaybackSpeedIcon(); void createPrevNextButtons(); void destroyPrevNextButtons();