From 72d8cd7ef0edbd8449998f6f68bad3983fb2de98 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 31 Dec 2019 10:30:06 +0300 Subject: [PATCH] Save playback position in long audio files. --- .../media/player/media_player_instance.cpp | 45 ++++++++++++++----- .../media/player/media_player_instance.h | 11 +++-- .../media/view/media_view_overlay_widget.cpp | 20 ++------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/Telegram/SourceFiles/media/player/media_player_instance.cpp b/Telegram/SourceFiles/media/player/media_player_instance.cpp index 217d631b0..e150eb08b 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.cpp +++ b/Telegram/SourceFiles/media/player/media_player_instance.cpp @@ -42,8 +42,22 @@ constexpr auto kIdsLimit = 32; // Preload next messages if we went further from current than that. constexpr auto kIdsPreloadAfter = 28; +constexpr auto kMinLengthForSavePosition = 20 * TimeId(60); // 20 minutes. + } // namespace +struct Instance::Streamed { + Streamed( + AudioMsgId id, + std::shared_ptr document); + + AudioMsgId id; + Streaming::Instance instance; + View::PlaybackProgress progress; + bool clearing = false; + rpl::lifetime lifetime; +}; + void start(not_null instance) { Audio::Start(instance); Capture::Start(); @@ -58,17 +72,23 @@ void finish(not_null instance) { Audio::Finish(instance); } -struct Instance::Streamed { - Streamed( - AudioMsgId id, - std::shared_ptr document); - - AudioMsgId id; - Streaming::Instance instance; - View::PlaybackProgress progress; - bool clearing = false; - rpl::lifetime lifetime; -}; +void SaveLastPlaybackPosition( + not_null document, + const TrackState &state) { + const auto time = (state.position == kTimeUnknown + || state.length == kTimeUnknown + || state.state == State::PausedAtEnd + || IsStopped(state.state)) + ? TimeId(0) + : (state.length >= kMinLengthForSavePosition * state.frequency) + ? (state.position / state.frequency) * crl::time(1000) + : TimeId(0); + auto &session = document->session(); + if (session.settings().mediaLastPlaybackPosition(document->id) != time) { + session.settings().setMediaLastPlaybackPosition(document->id, time); + session.saveSettingsDelayed(); + } +} Instance::Streamed::Streamed( AudioMsgId id, @@ -174,6 +194,9 @@ void Instance::clearStreamed(not_null data) { return; } data->streamed->clearing = true; + SaveLastPlaybackPosition( + data->current.audio(), + data->streamed->instance.player().prepareLegacyState()); data->streamed->instance.stop(); data->isPlaying = false; requestRoundVideoResize(); diff --git a/Telegram/SourceFiles/media/player/media_player_instance.h b/Telegram/SourceFiles/media/player/media_player_instance.h index 1a06a816e..d5472e40f 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.h +++ b/Telegram/SourceFiles/media/player/media_player_instance.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_shared_media.h" class AudioMsgId; +class DocumentData; namespace Media { namespace Audio { @@ -36,13 +37,17 @@ enum class Error; namespace Media { namespace Player { +class Instance; +struct TrackState; + void start(not_null instance); void finish(not_null instance); -class Instance; -Instance *instance(); +void SaveLastPlaybackPosition( + not_null document, + const TrackState &state); -struct TrackState; +Instance *instance(); class Instance : private base::Subscriber { public: diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index d9cf894d1..38ae3ccd3 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -81,8 +81,6 @@ constexpr auto kIdsLimit = 48; // Preload next messages if we went further from current than that. constexpr auto kIdsPreloadAfter = 28; -constexpr auto kMinLengthForSavePosition = 20 * TimeId(60); // 20 minutes. - Images::Options VideoThumbOptions(not_null document) { const auto result = Images::Option::Smooth | Images::Option::Blurred; return (document && document->isVideoMessage()) @@ -439,21 +437,9 @@ bool OverlayWidget::documentBubbleShown() const { void OverlayWidget::clearStreaming(bool savePosition) { if (_streamed && _doc && savePosition) { - using State = Media::Player::State; - const auto state = _streamed->instance.player().prepareLegacyState(); - const auto time = (state.position == kTimeUnknown - || state.length == kTimeUnknown - || state.state == State::PausedAtEnd - || Media::Player::IsStopped(state.state)) - ? TimeId(0) - : (state.length >= kMinLengthForSavePosition * state.frequency) - ? (state.position / state.frequency) * crl::time(1000) - : TimeId(0); - auto &session = _doc->session(); - if (session.settings().mediaLastPlaybackPosition(_doc->id) != time) { - session.settings().setMediaLastPlaybackPosition(_doc->id, time); - session.saveSettingsDelayed(); - } + Media::Player::SaveLastPlaybackPosition( + _doc, + _streamed->instance.player().prepareLegacyState()); } _fullScreenVideo = false; _streamed = nullptr;