Add video speed control slider.

This commit is contained in:
John Preston 2020-01-28 15:41:08 +03:00
parent b88219902f
commit 87cc18aff8
8 changed files with 74 additions and 5 deletions

View File

@ -23,6 +23,14 @@ constexpr auto kVersionTag = -1;
constexpr auto kVersion = 1;
constexpr auto kMaxSavedPlaybackPositions = 16;
[[nodiscard]] qint32 SerializePlaybackSpeed(float64 speed) {
return int(std::round(std::clamp(speed * 4., 2., 8.))) - 2;
}
float64 DeserializePlaybackSpeed(qint32 speed) {
return (std::clamp(speed, 0, 6) + 2) / 4.;
}
} // namespace
Settings::Variables::Variables()
@ -98,6 +106,7 @@ QByteArray Settings::serialize() const {
for (const auto &[id, time] : _variables.mediaLastPlaybackPosition) {
stream << quint64(id) << qint64(time);
}
stream << qint32(SerializePlaybackSpeed(_variables.videoPlaybackSpeed.current()));
}
return result;
}
@ -148,6 +157,7 @@ void Settings::constructFromSerialized(const QByteArray &serialized) {
qint32 suggestStickersByEmoji = _variables.suggestStickersByEmoji ? 1 : 0;
qint32 spellcheckerEnabled = _variables.spellcheckerEnabled.current() ? 1 : 0;
std::vector<std::pair<DocumentId, crl::time>> mediaLastPlaybackPosition;
qint32 videoPlaybackSpeed = SerializePlaybackSpeed(_variables.videoPlaybackSpeed.current());
stream >> versionTag;
if (versionTag == kVersionTag) {
@ -268,6 +278,9 @@ void Settings::constructFromSerialized(const QByteArray &serialized) {
}
}
}
if (!stream.atEnd()) {
stream >> videoPlaybackSpeed;
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for Main::Settings::constructFromSerialized()"));
@ -355,6 +368,7 @@ void Settings::constructFromSerialized(const QByteArray &serialized) {
_variables.suggestStickersByEmoji = (suggestStickersByEmoji == 1);
_variables.spellcheckerEnabled = (spellcheckerEnabled == 1);
_variables.mediaLastPlaybackPosition = std::move(mediaLastPlaybackPosition);
_variables.videoPlaybackSpeed = DeserializePlaybackSpeed(videoPlaybackSpeed);
}
void Settings::setSupportChatsTimeSlice(int slice) {

View File

@ -241,6 +241,13 @@ public:
return _variables.spellcheckerEnabled.changes();
}
[[nodiscard]] float64 videoPlaybackSpeed() const {
return _variables.videoPlaybackSpeed.current();
}
void setVideoPlaybackSpeed(float64 speed) {
_variables.videoPlaybackSpeed = speed;
}
private:
struct Variables {
Variables();
@ -281,6 +288,7 @@ private:
bool suggestStickersByEmoji = true;
rpl::variable<bool> spellcheckerEnabled = true;
std::vector<std::pair<DocumentId, crl::time>> mediaLastPlaybackPosition;
rpl::variable<float64> videoPlaybackSpeed = 1.;
static constexpr auto kDefaultSupportChatsLimitSlice
= 7 * 24 * 60 * 60;

View File

@ -958,6 +958,7 @@ void Player::unlock() {
--_locks;
if (!_locks) {
stopAudio();
setSpeed(1.);
setWaitForMarkAsShown(true);
}
}

View File

@ -2361,8 +2361,11 @@ void OverlayWidget::restartAtSeekPosition(crl::time position) {
if (!_streamed->withSound) {
options.mode = Streaming::Mode::Video;
options.loop = true;
} else if (_pip) {
_pip = nullptr;
} else {
options.speed = _doc->session().settings().videoPlaybackSpeed();
if (_pip) {
_pip = nullptr;
}
}
_streamed->instance.play(options);
if (_streamingStartPaused) {
@ -2397,13 +2400,29 @@ void OverlayWidget::playbackControlsVolumeChanged(float64 volume) {
Global::SetVideoVolume(volume);
updateMixerVideoVolume();
Global::RefVideoVolumeChanged().notify();
Auth().saveSettingsDelayed();
if (_doc) {
_doc->session().saveSettingsDelayed();
}
}
float64 OverlayWidget::playbackControlsCurrentVolume() {
return Global::VideoVolume();
}
void OverlayWidget::playbackControlsSpeedChanged(float64 speed) {
if (_doc) {
_doc->session().settings().setVideoPlaybackSpeed(speed);
_doc->session().saveSettingsDelayed();
}
if (_streamed && !videoIsGifv()) {
_streamed->instance.setSpeed(speed);
}
}
float64 OverlayWidget::playbackControlsCurrentSpeed() {
return _doc ? _doc->session().settings().videoPlaybackSpeed() : 1.;
}
void OverlayWidget::switchToPip() {
const auto document = _doc;
const auto msgId = _msgid;

View File

@ -172,6 +172,8 @@ private:
void playbackControlsSeekFinished(crl::time position) override;
void playbackControlsVolumeChanged(float64 volume) override;
float64 playbackControlsCurrentVolume() override;
void playbackControlsSpeedChanged(float64 speed);
float64 playbackControlsCurrentSpeed() override;
void playbackControlsToFullScreen() override;
void playbackControlsFromFullScreen() override;
void playbackControlsToPictureInPicture() override;

View File

@ -11,6 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/streaming/media_streaming_document.h"
#include "media/streaming/media_streaming_utility.h"
#include "media/audio/media_audio.h"
#include "main/main_session.h"
#include "main/main_settings.h"
#include "data/data_document.h"
#include "core/application.h"
#include "ui/platform/ui_platform_utility.h"
#include "ui/widgets/buttons.h"
@ -721,6 +724,9 @@ void Pip::restartAtSeekPosition(crl::time position) {
auto options = Streaming::PlaybackOptions();
options.position = position;
options.audioId = _instance.player().prepareLegacyState().id;
options.speed = options.audioId.audio()
? options.audioId.audio()->session().settings().videoPlaybackSpeed()
: 1.;
_instance.play(options);
updatePlaybackState();
}

View File

@ -30,6 +30,7 @@ PlaybackControls::PlaybackControls(
, _playbackSlider(this, st::mediaviewPlayback)
, _playbackProgress(std::make_unique<PlaybackProgress>())
, _volumeController(this, st::mediaviewPlayback)
, _speedController(this, st::mediaviewPlayback)
, _fullScreenToggle(this, st::mediaviewFullScreenButton)
, _pictureInPicture(this, st::mediaviewFullScreenButton)
, _playedAlready(this, st::mediaviewPlayProgressLabel)
@ -54,6 +55,12 @@ PlaybackControls::PlaybackControls(
_volumeController->setChangeProgressCallback([=](float64 value) {
_delegate->playbackControlsVolumeChanged(value);
});
_speedController->setPseudoDiscrete(
7,
[=](int index) { return (index + 2) / 4.; },
_delegate->playbackControlsCurrentSpeed(),
[=](float64 speed) { _delegate->playbackControlsSpeedChanged(speed); });
_speedController->setAlwaysDisplayMarker(false);
_playPauseResume->addClickHandler([=] {
if (_showPause) {
@ -121,6 +128,7 @@ void PlaybackControls::startFading(Callback start) {
showChildren();
_playbackSlider->disablePaint(true);
_volumeController->disablePaint(true);
_speedController->disablePaint(true);
_childrenHidden = false;
}
start();
@ -128,7 +136,8 @@ void PlaybackControls::startFading(Callback start) {
for (const auto child : children()) {
if (child->isWidgetType()
&& child != _playbackSlider
&& child != _volumeController) {
&& child != _volumeController
&& child != _speedController) {
static_cast<QWidget*>(child)->hide();
}
}
@ -138,6 +147,7 @@ void PlaybackControls::startFading(Callback start) {
}
_playbackSlider->disablePaint(false);
_volumeController->disablePaint(false);
_speedController->disablePaint(false);
}
void PlaybackControls::showAnimated() {
@ -159,6 +169,7 @@ void PlaybackControls::fadeFinished() {
void PlaybackControls::fadeUpdated(float64 opacity) {
_playbackSlider->setFadeOpacity(opacity);
_volumeController->setFadeOpacity(opacity);
_speedController->setFadeOpacity(opacity);
}
void PlaybackControls::updatePlayback(const Player::TrackState &state) {
@ -306,8 +317,12 @@ void PlaybackControls::resizeEvent(QResizeEvent *e) {
_pictureInPicture->moveToLeft(left, playTop);
const auto volumeTop = playTop + (_fullScreenToggle->height() - _volumeController->height()) / 2;
_volumeController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height());
_volumeController->moveToRight(skip, playTop + (_fullScreenToggle->height() - _volumeController->height()) / 2);
_volumeController->moveToRight(skip, volumeTop);
_speedController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height());
_speedController->moveToRight(skip + _volumeController->width() + skip, volumeTop);
}
void PlaybackControls::paintEvent(QPaintEvent *e) {
@ -320,6 +335,7 @@ void PlaybackControls::paintEvent(QPaintEvent *e) {
showChildren();
_playbackSlider->setFadeOpacity(1.);
_volumeController->setFadeOpacity(1.);
_speedController->setFadeOpacity(1.);
_childrenHidden = false;
}
App::roundRect(p, rect(), st::mediaviewSaveMsgBg, MediaviewSaveCorners);

View File

@ -36,6 +36,8 @@ public:
virtual void playbackControlsSeekFinished(crl::time position) = 0;
virtual void playbackControlsVolumeChanged(float64 volume) = 0;
[[nodiscard]] virtual float64 playbackControlsCurrentVolume() = 0;
virtual void playbackControlsSpeedChanged(float64 speed) = 0;
[[nodiscard]] virtual float64 playbackControlsCurrentSpeed() = 0;
virtual void playbackControlsToFullScreen() = 0;
virtual void playbackControlsFromFullScreen() = 0;
virtual void playbackControlsToPictureInPicture() = 0;
@ -90,6 +92,7 @@ private:
std::unique_ptr<PlaybackProgress> _playbackProgress;
std::unique_ptr<PlaybackProgress> _receivedTillProgress;
object_ptr<Ui::MediaSlider> _volumeController;
object_ptr<Ui::MediaSlider> _speedController;
object_ptr<Ui::IconButton> _fullScreenToggle;
object_ptr<Ui::IconButton> _pictureInPicture;
object_ptr<Ui::LabelSimple> _playedAlready;