From 3248de3de47011137e0c667a7247dd424c827bd7 Mon Sep 17 00:00:00 2001 From: Julien Lepiller Date: Wed, 11 Jul 2018 12:35:40 +0200 Subject: [PATCH] Mediaplayer: remember position and volume Change-Id: I43fa7cbcedd39c39e4b136e9e1f9bb34bf3eb570 --- src/apps/mediaplayer/Controller.cpp | 60 +++++++++++++++++++ src/apps/mediaplayer/Controller.h | 4 ++ src/apps/mediaplayer/MainWin.cpp | 8 +++ .../mediaplayer/playlist/FilePlaylistItem.cpp | 32 ++++++++++ .../mediaplayer/playlist/FilePlaylistItem.h | 5 ++ .../mediaplayer/playlist/PlaylistItem.cpp | 38 +++++++++++- src/apps/mediaplayer/playlist/PlaylistItem.h | 14 ++++- .../mediaplayer/playlist/UrlPlaylistItem.cpp | 14 +++++ .../mediaplayer/playlist/UrlPlaylistItem.h | 5 ++ src/apps/mediaplayer/settings/Settings.cpp | 5 ++ src/apps/mediaplayer/settings/Settings.h | 6 ++ .../mediaplayer/settings/SettingsWindow.cpp | 12 ++++ .../mediaplayer/settings/SettingsWindow.h | 7 ++- 13 files changed, 205 insertions(+), 5 deletions(-) diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index 2efda09162..bdfee11465 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include // for debugging only @@ -38,6 +39,11 @@ #include "TrackSupplier.h" #include "VideoTrackSupplier.h" + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "MediaPlayer-Controller" +#define MIN_WIDTH 250 + using std::nothrow; @@ -694,6 +700,56 @@ Controller::TimePosition() } +status_t +Controller::SaveState(bool reset) +{ + if (fItem.Get() == NULL) + return B_OK; + if (reset) + fCurrentFrame = 0; + status_t status = fItem.Get()->SetLastVolume(fVolume); + if (status == B_OK) + status = fItem.Get()->SetLastFrame(fCurrentFrame); + else + fItem.Get()->SetLastFrame(fCurrentFrame); + return status; +} + + +void +Controller::RestoreState() +{ + PlaylistItem *item =fItem.Get(); + if (item == NULL) + return; + + Pause(); + + if (item->LastFrame() > 0) { + bool resume = fResume == mpSettings::RESUME_ALWAYS; + if (fResume == mpSettings::RESUME_ASK) { + BString label; + int32 time = (int32)((float)item->LastFrame() * TimeDuration() + / (1000000 * _FrameDuration())); + label.SetToFormat(B_TRANSLATE("Do you want to resume %s at %dm%ds?"), + item->Name().String(), time / 60, time % 60); + BAlert *alert = new BAlert(B_TRANSLATE("Resume?"), label, + B_TRANSLATE("Resume"), B_TRANSLATE("Reset")); + resume = alert->Go() == 0; + } + + if (resume) + SetFramePosition(item->LastFrame()); + } + + float lastVolume = item->LastVolume(); + if (lastVolume >= 0) + SetVolume(lastVolume); + + Play(); +} + + void Controller::SetVolume(float value) { @@ -713,6 +769,7 @@ Controller::SetVolume(float value) } } + void Controller::VolumeUp() { @@ -720,6 +777,7 @@ Controller::VolumeUp() SetVolume(Volume() + 0.05); } + void Controller::VolumeDown() { @@ -727,6 +785,7 @@ Controller::VolumeDown() SetVolume(Volume() - 0.05); } + void Controller::ToggleMute() { @@ -988,6 +1047,7 @@ Controller::_AdoptGlobalSettings() fLoopMovies = settings.loopMovie; fLoopSounds = settings.loopSound; fBackgroundMovieVolumeMode = settings.backgroundMovieVolumeMode; + fResume = settings.resume; } diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h index 45ec5a2232..a4eb64abb5 100644 --- a/src/apps/mediaplayer/Controller.h +++ b/src/apps/mediaplayer/Controller.h @@ -10,6 +10,7 @@ #define __CONTROLLER_H +#include #include #include #include @@ -103,6 +104,8 @@ public: bigtime_t TimeDuration(); bigtime_t TimePosition(); + status_t SaveState(bool reset = false); + void RestoreState(); virtual void SetVolume(float factor); float Volume(); @@ -211,6 +214,7 @@ private: bool fLoopMovies; bool fLoopSounds; uint32 fBackgroundMovieVolumeMode; + uint32 fResume; BList fListeners; }; diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp index ac9270bd0b..ad1c8811c0 100644 --- a/src/apps/mediaplayer/MainWin.cpp +++ b/src/apps/mediaplayer/MainWin.cpp @@ -729,6 +729,9 @@ MainWin::MessageReceived(BMessage* msg) { BAutolock _(fPlaylist); + //The file is finished. Open at start next time. + fController->SaveState(true); + bool hadNext = fPlaylist->SetCurrentItemIndex( fPlaylist->CurrentItemIndex() + 1); if (!hadNext) { @@ -831,6 +834,7 @@ MainWin::MessageReceived(BMessage* msg) float volume; if (msg->FindFloat("volume", &volume) == B_OK) fControls->SetVolume(volume); + fController->SaveState(); break; } case MSG_CONTROLLER_MUTED_CHANGED: @@ -1108,6 +1112,7 @@ MainWin::WindowActivated(bool active) bool MainWin::QuitRequested() { + fController->SaveState(); BMessage message(M_PLAYER_QUIT); GetQuitMessage(&message); be_app->PostMessage(&message); @@ -1429,6 +1434,9 @@ MainWin::_PlaylistItemOpened(const PlaylistItemRef& item, status_t result) } fController->SetTimePosition(fInitialSeekPosition); fInitialSeekPosition = 0; + + if (fPlaylist->CountItems() == 1) + fController->RestoreState(); } _SetupWindow(); diff --git a/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp b/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp index 56d3cec3a3..775aa6d0ae 100644 --- a/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp +++ b/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp @@ -192,6 +192,9 @@ FilePlaylistItem::SetAttribute(const Attribute& attribute, const int64& value) { switch (attribute) { + case ATTR_INT64_FRAME: + return _SetAttribute("Media:Frame", B_INT64_TYPE, &value, + sizeof(int64)); case ATTR_INT64_DURATION: return _SetAttribute("Media:Length", B_INT64_TYPE, &value, sizeof(int64)); @@ -206,6 +209,9 @@ FilePlaylistItem::GetAttribute(const Attribute& attribute, int64& value) const { switch (attribute) { + case ATTR_INT64_FRAME: + return _GetAttribute("Media:Frame", B_INT64_TYPE, &value, + sizeof(int64)); case ATTR_INT64_DURATION: return _GetAttribute("Media:Length", B_INT64_TYPE, &value, sizeof(int64)); @@ -215,6 +221,32 @@ FilePlaylistItem::GetAttribute(const Attribute& attribute, } +status_t +FilePlaylistItem::SetAttribute(const Attribute& attribute, + const float& value) +{ + if (attribute == ATTR_FLOAT_VOLUME) { + return _SetAttribute("Media:Volume", B_FLOAT_TYPE, &value, + sizeof(float)); + } + + return B_NOT_SUPPORTED; +} + + +status_t +FilePlaylistItem::GetAttribute(const Attribute& attribute, + float& value) const +{ + if (attribute == ATTR_FLOAT_VOLUME) { + return _GetAttribute("Media:Volume", B_FLOAT_TYPE, &value, + sizeof(float)); + } + + return B_NOT_SUPPORTED; +} + + // #pragma mark - diff --git a/src/apps/mediaplayer/playlist/FilePlaylistItem.h b/src/apps/mediaplayer/playlist/FilePlaylistItem.h index 82b6235664..ee78c29682 100644 --- a/src/apps/mediaplayer/playlist/FilePlaylistItem.h +++ b/src/apps/mediaplayer/playlist/FilePlaylistItem.h @@ -44,6 +44,11 @@ public: virtual status_t GetAttribute(const Attribute& attribute, int64& value) const; + virtual status_t SetAttribute(const Attribute& attribute, + const float& value); + virtual status_t GetAttribute(const Attribute& attribute, + float& value) const; + // methods virtual BString LocationURI() const; virtual status_t GetIcon(BBitmap* bitmap, diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.cpp b/src/apps/mediaplayer/playlist/PlaylistItem.cpp index 1ed5fdc040..bb96c22f90 100644 --- a/src/apps/mediaplayer/playlist/PlaylistItem.cpp +++ b/src/apps/mediaplayer/playlist/PlaylistItem.cpp @@ -22,10 +22,12 @@ PlaylistItem::Listener::Listener() { } + PlaylistItem::Listener::~Listener() { } + void PlaylistItem::Listener::ItemChanged(const PlaylistItem* item) { } @@ -34,7 +36,7 @@ void PlaylistItem::Listener::ItemChanged(const PlaylistItem* item) // #pragma mark - -//#define DEBUG_INSTANCE_COUNT +// #define DEBUG_INSTANCE_COUNT #ifdef DEBUG_INSTANCE_COUNT static vint32 sInstanceCount = 0; #endif @@ -149,6 +151,40 @@ PlaylistItem::Duration() } +int64 +PlaylistItem::LastFrame() const +{ + int64 lastFrame; + if (GetAttribute(ATTR_INT64_FRAME, lastFrame) != B_OK) + lastFrame = 0; + return lastFrame; +} + + +float +PlaylistItem::LastVolume() const +{ + float lastVolume; + if (GetAttribute(ATTR_FLOAT_VOLUME, lastVolume) != B_OK) + lastVolume = -1; + return lastVolume; +} + + +status_t +PlaylistItem::SetLastFrame(int64 value) +{ + return SetAttribute(ATTR_INT64_FRAME, value); +} + + +status_t +PlaylistItem::SetLastVolume(float value) +{ + return SetAttribute(ATTR_FLOAT_VOLUME, value); +} + + void PlaylistItem::SetPlaybackFailed() { diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.h b/src/apps/mediaplayer/playlist/PlaylistItem.h index 7331c21ade..3b1a4bb067 100644 --- a/src/apps/mediaplayer/playlist/PlaylistItem.h +++ b/src/apps/mediaplayer/playlist/PlaylistItem.h @@ -54,7 +54,9 @@ public: ATTR_INT32_YEAR = 'year', ATTR_INT32_RATING = 'rtng', - ATTR_INT64_DURATION = 'drtn' + ATTR_INT64_DURATION = 'drtn', + ATTR_INT64_FRAME = 'fram', + ATTR_FLOAT_VOLUME = 'volu' } Attribute; virtual status_t SetAttribute(const Attribute& attribute, @@ -72,6 +74,11 @@ public: virtual status_t GetAttribute(const Attribute& attribute, int64& value) const = 0; + virtual status_t SetAttribute(const Attribute& attribute, + const float& value) = 0; + virtual status_t GetAttribute(const Attribute& attribute, + float& value) const = 0; + // convenience access to attributes BString Name() const; BString Author() const; @@ -81,6 +88,11 @@ public: int32 TrackNumber() const; bigtime_t Duration(); + int64 LastFrame() const; + float LastVolume() const; + + status_t SetLastFrame(int64 value); + status_t SetLastVolume(float value); // methods virtual BString LocationURI() const = 0; diff --git a/src/apps/mediaplayer/playlist/UrlPlaylistItem.cpp b/src/apps/mediaplayer/playlist/UrlPlaylistItem.cpp index 5f2fbc2b65..ec778e8e4c 100644 --- a/src/apps/mediaplayer/playlist/UrlPlaylistItem.cpp +++ b/src/apps/mediaplayer/playlist/UrlPlaylistItem.cpp @@ -114,6 +114,20 @@ UrlPlaylistItem::GetAttribute(const Attribute& attribute, int64& value) const } +status_t +UrlPlaylistItem::SetAttribute(const Attribute& attribute, const float& value) +{ + return B_NOT_SUPPORTED; +} + + +status_t +UrlPlaylistItem::GetAttribute(const Attribute& attribute, float& value) const +{ + return B_NOT_SUPPORTED; +} + + BString UrlPlaylistItem::LocationURI() const { diff --git a/src/apps/mediaplayer/playlist/UrlPlaylistItem.h b/src/apps/mediaplayer/playlist/UrlPlaylistItem.h index 11481b7a99..6f4a86b86c 100644 --- a/src/apps/mediaplayer/playlist/UrlPlaylistItem.h +++ b/src/apps/mediaplayer/playlist/UrlPlaylistItem.h @@ -38,6 +38,11 @@ public: virtual status_t GetAttribute(const Attribute& attribute, int64& value) const; + virtual status_t SetAttribute(const Attribute& attribute, + const float& value); + virtual status_t GetAttribute(const Attribute& attribute, + float& value) const; + virtual BString LocationURI() const; virtual status_t GetIcon(BBitmap* bitmap, icon_size iconSize) const; diff --git a/src/apps/mediaplayer/settings/Settings.cpp b/src/apps/mediaplayer/settings/Settings.cpp index 7f1d00d25b..49bd745e5e 100644 --- a/src/apps/mediaplayer/settings/Settings.cpp +++ b/src/apps/mediaplayer/settings/Settings.cpp @@ -26,6 +26,7 @@ mpSettings::operator!=(const mpSettings& other) const || useOverlays != other.useOverlays || scaleBilinear != other.scaleBilinear || scaleFullscreenControls != other.scaleFullscreenControls + || resume != other.resume || subtitleSize != other.subtitleSize || subtitlePlacement != other.subtitlePlacement || backgroundMovieVolumeMode != other.backgroundMovieVolumeMode @@ -61,6 +62,9 @@ Settings::Get(mpSettings& settings) const settings.scaleFullscreenControls = fSettingsMessage.GetValue("scaleFullscreenControls", true); + settings.resume + = fSettingsMessage.GetValue("resume", + (uint32)mpSettings::RESUME_ALWAYS); settings.subtitleSize = fSettingsMessage.GetValue("subtitleSize", (uint32)mpSettings::SUBTITLE_SIZE_MEDIUM); @@ -95,6 +99,7 @@ Settings::Update(const mpSettings& settings) fSettingsMessage.SetValue("scaleFullscreenControls", settings.scaleFullscreenControls); + fSettingsMessage.SetValue("resume", settings.resume); fSettingsMessage.SetValue("subtitleSize", settings.subtitleSize); fSettingsMessage.SetValue("subtitlePlacement", settings.subtitlePlacement); diff --git a/src/apps/mediaplayer/settings/Settings.h b/src/apps/mediaplayer/settings/Settings.h index f8b3590233..5dbc499007 100644 --- a/src/apps/mediaplayer/settings/Settings.h +++ b/src/apps/mediaplayer/settings/Settings.h @@ -34,6 +34,11 @@ struct mpSettings { BG_MOVIES_HALF_VLUME = 1, BG_MOVIES_MUTED = 2 }; + enum { + RESUME_NEVER = 0, + RESUME_ASK = 1, + RESUME_ALWAYS = 2 + }; bool autostart; bool closeWhenDonePlayingMovie; @@ -43,6 +48,7 @@ struct mpSettings { bool useOverlays; bool scaleBilinear; bool scaleFullscreenControls; + uint32 resume; uint32 subtitleSize; uint32 subtitlePlacement; uint32 backgroundMovieVolumeMode; diff --git a/src/apps/mediaplayer/settings/SettingsWindow.cpp b/src/apps/mediaplayer/settings/SettingsWindow.cpp index 42f46a2f6f..1bddedd3c5 100644 --- a/src/apps/mediaplayer/settings/SettingsWindow.cpp +++ b/src/apps/mediaplayer/settings/SettingsWindow.cpp @@ -99,6 +99,15 @@ SettingsWindow::SettingsWindow(BRect frame) B_TRANSLATE("Scale controls in full screen mode"), new BMessage(M_SETTINGS_CHANGED)); + fResumeOP = new BOptionPopUp("resume", + B_TRANSLATE("Resume:"), new BMessage(M_SETTINGS_CHANGED)); + fResumeOP->AddOption( + B_TRANSLATE("never"), mpSettings::RESUME_NEVER); + fResumeOP->AddOption( + B_TRANSLATE("ask every time"), mpSettings::RESUME_ASK); + fResumeOP->AddOption( + B_TRANSLATE("always"), mpSettings::RESUME_ALWAYS); + fSubtitleSizeOP = new BOptionPopUp("subtitleSize", B_TRANSLATE("Subtitle size:"), new BMessage(M_SETTINGS_CHANGED)); fSubtitleSizeOP->AddOption( @@ -157,6 +166,7 @@ SettingsWindow::SettingsWindow(BRect frame) .End() .Add(fLoopMoviesCB) .Add(fLoopSoundsCB) + .Add(fResumeOP) .End() .End() .AddStrut(kSpacing) @@ -272,6 +282,7 @@ SettingsWindow::AdoptSettings() fScaleBilinearCB->SetValue(fSettings.scaleBilinear); fScaleFullscreenControlsCB->SetValue(fSettings.scaleFullscreenControls); + fResumeOP->SetValue(fSettings.resume); fSubtitleSizeOP->SetValue(fSettings.subtitleSize); fSubtitlePlacementOP->SetValue(fSettings.subtitlePlacement); @@ -302,6 +313,7 @@ SettingsWindow::ApplySettings() fSettings.scaleFullscreenControls = fScaleFullscreenControlsCB->Value() == B_CONTROL_ON; + fSettings.resume = fResumeOP->Value(); fSettings.subtitleSize = fSubtitleSizeOP->Value(); fSettings.subtitlePlacement = fSubtitlePlacementOP->Value(); diff --git a/src/apps/mediaplayer/settings/SettingsWindow.h b/src/apps/mediaplayer/settings/SettingsWindow.h index 6285620e29..38e2f2cc63 100644 --- a/src/apps/mediaplayer/settings/SettingsWindow.h +++ b/src/apps/mediaplayer/settings/SettingsWindow.h @@ -37,7 +37,7 @@ private: mpSettings fSettings; mpSettings fLastSettings; - BCheckBox* fAutostartCB; + BCheckBox* fAutostartCB; BCheckBox* fCloseWindowMoviesCB; BCheckBox* fCloseWindowSoundsCB; BCheckBox* fLoopMoviesCB; @@ -47,11 +47,12 @@ private: BCheckBox* fScaleBilinearCB; BCheckBox* fScaleFullscreenControlsCB; + BOptionPopUp* fResumeOP; BOptionPopUp* fSubtitleSizeOP; BOptionPopUp* fSubtitlePlacementOP; - BRadioButton* fFullVolumeBGMoviesRB; - BRadioButton* fHalfVolumeBGMoviesRB; + BRadioButton* fFullVolumeBGMoviesRB; + BRadioButton* fHalfVolumeBGMoviesRB; BRadioButton* fMutedVolumeBGMoviesRB; BButton* fRevertB;