Save playback position in long audio files.

This commit is contained in:
John Preston 2019-12-31 10:30:06 +03:00
parent 2637c860e9
commit 72d8cd7ef0
3 changed files with 45 additions and 31 deletions

View File

@ -42,8 +42,22 @@ constexpr auto kIdsLimit = 32;
// Preload next messages if we went further from current than that. // Preload next messages if we went further from current than that.
constexpr auto kIdsPreloadAfter = 28; constexpr auto kIdsPreloadAfter = 28;
constexpr auto kMinLengthForSavePosition = 20 * TimeId(60); // 20 minutes.
} // namespace } // namespace
struct Instance::Streamed {
Streamed(
AudioMsgId id,
std::shared_ptr<Streaming::Document> document);
AudioMsgId id;
Streaming::Instance instance;
View::PlaybackProgress progress;
bool clearing = false;
rpl::lifetime lifetime;
};
void start(not_null<Audio::Instance*> instance) { void start(not_null<Audio::Instance*> instance) {
Audio::Start(instance); Audio::Start(instance);
Capture::Start(); Capture::Start();
@ -58,17 +72,23 @@ void finish(not_null<Audio::Instance*> instance) {
Audio::Finish(instance); Audio::Finish(instance);
} }
struct Instance::Streamed { void SaveLastPlaybackPosition(
Streamed( not_null<DocumentData*> document,
AudioMsgId id, const TrackState &state) {
std::shared_ptr<Streaming::Document> document); const auto time = (state.position == kTimeUnknown
|| state.length == kTimeUnknown
AudioMsgId id; || state.state == State::PausedAtEnd
Streaming::Instance instance; || IsStopped(state.state))
View::PlaybackProgress progress; ? TimeId(0)
bool clearing = false; : (state.length >= kMinLengthForSavePosition * state.frequency)
rpl::lifetime lifetime; ? (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( Instance::Streamed::Streamed(
AudioMsgId id, AudioMsgId id,
@ -174,6 +194,9 @@ void Instance::clearStreamed(not_null<Data*> data) {
return; return;
} }
data->streamed->clearing = true; data->streamed->clearing = true;
SaveLastPlaybackPosition(
data->current.audio(),
data->streamed->instance.player().prepareLegacyState());
data->streamed->instance.stop(); data->streamed->instance.stop();
data->isPlaying = false; data->isPlaying = false;
requestRoundVideoResize(); requestRoundVideoResize();

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_shared_media.h" #include "data/data_shared_media.h"
class AudioMsgId; class AudioMsgId;
class DocumentData;
namespace Media { namespace Media {
namespace Audio { namespace Audio {
@ -36,13 +37,17 @@ enum class Error;
namespace Media { namespace Media {
namespace Player { namespace Player {
class Instance;
struct TrackState;
void start(not_null<Audio::Instance*> instance); void start(not_null<Audio::Instance*> instance);
void finish(not_null<Audio::Instance*> instance); void finish(not_null<Audio::Instance*> instance);
class Instance; void SaveLastPlaybackPosition(
Instance *instance(); not_null<DocumentData*> document,
const TrackState &state);
struct TrackState; Instance *instance();
class Instance : private base::Subscriber { class Instance : private base::Subscriber {
public: public:

View File

@ -81,8 +81,6 @@ constexpr auto kIdsLimit = 48;
// Preload next messages if we went further from current than that. // Preload next messages if we went further from current than that.
constexpr auto kIdsPreloadAfter = 28; constexpr auto kIdsPreloadAfter = 28;
constexpr auto kMinLengthForSavePosition = 20 * TimeId(60); // 20 minutes.
Images::Options VideoThumbOptions(not_null<DocumentData*> document) { Images::Options VideoThumbOptions(not_null<DocumentData*> document) {
const auto result = Images::Option::Smooth | Images::Option::Blurred; const auto result = Images::Option::Smooth | Images::Option::Blurred;
return (document && document->isVideoMessage()) return (document && document->isVideoMessage())
@ -439,21 +437,9 @@ bool OverlayWidget::documentBubbleShown() const {
void OverlayWidget::clearStreaming(bool savePosition) { void OverlayWidget::clearStreaming(bool savePosition) {
if (_streamed && _doc && savePosition) { if (_streamed && _doc && savePosition) {
using State = Media::Player::State; Media::Player::SaveLastPlaybackPosition(
const auto state = _streamed->instance.player().prepareLegacyState(); _doc,
const auto time = (state.position == kTimeUnknown _streamed->instance.player().prepareLegacyState());
|| 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();
}
} }
_fullScreenVideo = false; _fullScreenVideo = false;
_streamed = nullptr; _streamed = nullptr;