Added ability to change playback speed for long audio files.

This commit is contained in:
23rd 2021-08-31 19:11:37 +03:00
parent b635a9d4a5
commit bcbab7ad8e
5 changed files with 45 additions and 14 deletions

View file

@ -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);
}

View file

@ -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;
};

View file

@ -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());
}

View file

@ -164,6 +164,8 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> 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(

View file

@ -75,6 +75,8 @@ private:
void updatePlayPrevNextPositions();
void updateLabelsGeometry();
void updateRepeatTrackIcon();
void updateControlsVisibility();
void updateControlsGeometry();
void updatePlaybackSpeedIcon();
void createPrevNextButtons();
void destroyPrevNextButtons();