Ticket #1503: 0001-Mediaplayer-remember-position-and-volume.patch

File 0001-Mediaplayer-remember-position-and-volume.patch, 17.9 KB (added by frizer23, 5 years ago)
  • src/apps/mediaplayer/Controller.cpp

    From 0d1d77c1ea3c2042ffebc70674761ace8ddc6f54 Mon Sep 17 00:00:00 2001
    From: Julien Lepiller <julien@lepiller.eu>
    Date: Sat, 27 Sep 2014 00:29:09 +0200
    Subject: [PATCH] Mediaplayer: remember position and volume
    
    ---
     src/apps/mediaplayer/Controller.cpp                | 59 +++++++++++++++++++
     src/apps/mediaplayer/Controller.h                  |  4 ++
     src/apps/mediaplayer/MainWin.cpp                   | 11 +++-
     src/apps/mediaplayer/playlist/FilePlaylistItem.cpp | 66 +++++++++++++++++-----
     src/apps/mediaplayer/playlist/FilePlaylistItem.h   |  7 ++-
     src/apps/mediaplayer/playlist/PlaylistItem.cpp     | 38 ++++++++++++-
     src/apps/mediaplayer/playlist/PlaylistItem.h       | 16 +++++-
     src/apps/mediaplayer/settings/Settings.cpp         |  5 ++
     src/apps/mediaplayer/settings/Settings.h           |  6 ++
     src/apps/mediaplayer/settings/SettingsWindow.cpp   | 12 ++++
     src/apps/mediaplayer/settings/SettingsWindow.h     |  1 +
     11 files changed, 206 insertions(+), 19 deletions(-)
    
    diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp
    index 5176a3d..516380f 100644
    a b  
    2929
    3030#include <Autolock.h>
    3131#include <Bitmap.h>
     32#include <Catalog.h>
    3233#include <Debug.h>
    3334#include <Path.h>
    3435#include <Window.h> // for debugging only
     
    5051#include "TrackSupplier.h"
    5152#include "VideoTrackSupplier.h"
    5253
     54#undef B_TRANSLATION_CONTEXT
     55#define B_TRANSLATION_CONTEXT "MediaPlayer-Controller"
     56#define MIN_WIDTH 250
     57
    5358using std::nothrow;
    5459
    5560
    Controller::TimePosition() 
    680685}
    681686
    682687
     688status_t
     689Controller::SaveState(bool reset)
     690{
     691    if (fItem.Get() == NULL)
     692        return B_OK;
     693    if (reset)
     694        fCurrentFrame = 0;
     695    status_t status = fItem.Get()->SetLastVolume(fVolume);
     696    if (status == B_OK)
     697        status = fItem.Get()->SetLastFrame(fCurrentFrame);
     698    else
     699        fItem.Get()->SetLastFrame(fCurrentFrame);
     700    return status;
     701}
     702
     703
     704void
     705Controller::RestoreState()
     706{
     707    PlaylistItem *item =fItem.Get();
     708    if (item == NULL)
     709        return;
     710
     711    Pause();
     712
     713    if (item->LastFrame() > 0) {
     714        bool resume = fResume == mpSettings::RESUME_ALWAYS;
     715        if (fResume == mpSettings::RESUME_ASK) {
     716            BString label;
     717            int32 time = (int32)((float)item->LastFrame() * TimeDuration()
     718                / (1000000 * _FrameDuration()));
     719            label.SetToFormat(B_TRANSLATE("Do you want to resume %s at %dm%ds?"),
     720                item->Name().String(), time / 60, time % 60);
     721            BAlert *alert = new BAlert(B_TRANSLATE("Resume?"), label,
     722                B_TRANSLATE("Resume"), B_TRANSLATE("Reset"));
     723            resume = alert->Go() == 0;
     724        }
     725
     726        if (resume)
     727            SetFramePosition(item->LastFrame());
     728    }
     729
     730    float lastVolume = item->LastVolume();
     731    if (lastVolume >= 0)
     732        SetVolume(lastVolume);
     733
     734    Play();
     735}
     736
     737
    683738void
    684739Controller::SetVolume(float value)
    685740{
    Controller::SetVolume(float value) 
    699754    }
    700755}
    701756
     757
    702758void
    703759Controller::VolumeUp()
    704760{
    Controller::VolumeUp() 
    706762    SetVolume(Volume() + 0.05);
    707763}
    708764
     765
    709766void
    710767Controller::VolumeDown()
    711768{
    Controller::VolumeDown() 
    713770    SetVolume(Volume() - 0.05);
    714771}
    715772
     773
    716774void
    717775Controller::ToggleMute()
    718776{
    Controller::_AdoptGlobalSettings() 
    9741032    fLoopMovies = settings.loopMovie;
    9751033    fLoopSounds = settings.loopSound;
    9761034    fBackgroundMovieVolumeMode = settings.backgroundMovieVolumeMode;
     1035    fResume = settings.resume;
    9771036}
    9781037
    9791038
  • src/apps/mediaplayer/Controller.h

    diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h
    index 1eeda17..451d55a 100644
    a b  
    2222#define __CONTROLLER_H
    2323
    2424
     25#include <Alert.h>
    2526#include <Entry.h>
    2627#include <MediaDefs.h>
    2728#include <MediaFormats.h>
    public: 
    115116
    116117            bigtime_t           TimeDuration();
    117118            bigtime_t           TimePosition();
     119            status_t            SaveState(bool reset = false);
     120            void                RestoreState();
    118121
    119122    virtual void                SetVolume(float factor);
    120123            float               Volume();
    private: 
    224227            bool                fLoopMovies;
    225228            bool                fLoopSounds;
    226229            uint32              fBackgroundMovieVolumeMode;
     230            uint32              fResume;
    227231
    228232            BList               fListeners;
    229233};
  • src/apps/mediaplayer/MainWin.cpp

    diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp
    index 3229867..f5eb7e7 100644
    a b MainWin::MessageReceived(BMessage* msg) 
    697697        {
    698698            BAutolock _(fPlaylist);
    699699
     700            //The file is finished. Open at start next time.
     701            fController->SaveState(true);
     702
    700703            bool hadNext = fPlaylist->SetCurrentItemIndex(
    701704                fPlaylist->CurrentItemIndex() + 1);
    702705            if (!hadNext) {
    MainWin::MessageReceived(BMessage* msg) 
    799802            float volume;
    800803            if (msg->FindFloat("volume", &volume) == B_OK)
    801804                fControls->SetVolume(volume);
     805            fController->SaveState();
    802806            break;
    803807        }
    804808        case MSG_CONTROLLER_MUTED_CHANGED:
    MainWin::WindowActivated(bool active) 
    10671071bool
    10681072MainWin::QuitRequested()
    10691073{
     1074    fController->SaveState();
    10701075    BMessage message(M_PLAYER_QUIT);
    10711076    GetQuitMessage(&message);
    10721077    be_app->PostMessage(&message);
    MainWin::_PlaylistItemOpened(const PlaylistItemRef& item, status_t result) 
    14011406        }
    14021407        fController->SetTimePosition(fInitialSeekPosition);
    14031408        fInitialSeekPosition = 0;
     1409
     1410        if (fPlaylist->CountItems() == 1)
     1411            fController->RestoreState();
    14041412    }
    14051413    _SetupWindow();
    14061414
    MainWin::_Wind(bigtime_t howMuch, int64 frames) 
    24522460        } else if (seekTime > fController->TimeDuration()) {
    24532461            fInitialSeekPosition = 0;
    24542462            PostMessage(M_SKIP_NEXT);
    2455         } else
     2463        } else {
    24562464            fController->SetTimePosition(seekTime);
     2465        }
    24572466    }
    24582467
    24592468    fController->Unlock();
  • src/apps/mediaplayer/playlist/FilePlaylistItem.cpp

    diff --git a/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp b/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp
    index 4b1cafd..5b5e430 100644
    a b FilePlaylistItem::SetAttribute(const Attribute& attribute, 
    114114            BEntry entry(&fRefs[0], false);
    115115            return entry.Rename(string.String(), false);
    116116        }
    117    
     117
    118118        case ATTR_STRING_KEYWORDS:
    119119            return _SetAttribute("Meta:Keywords", B_STRING_TYPE,
    120120                string.String(), string.Length());
    status_t 
    190190FilePlaylistItem::SetAttribute(const Attribute& attribute,
    191191    const int64& value)
    192192{
     193    if (attribute == ATTR_INT64_FRAME) {
     194        return _SetAttribute("Media:Frame", B_INT64_TYPE, &value,
     195            sizeof(int64));
     196    }
     197
    193198    return B_NOT_SUPPORTED;
    194199}
    195200
    status_t 
    198203FilePlaylistItem::GetAttribute(const Attribute& attribute,
    199204    int64& value) const
    200205{
     206    if (attribute == ATTR_INT64_FRAME) {
     207        return _GetAttribute("Media:Frame", B_INT64_TYPE, &value,
     208            sizeof(int64));
     209    }
     210
     211    return B_NOT_SUPPORTED;
     212}
     213
     214
     215status_t
     216FilePlaylistItem::SetAttribute(const Attribute& attribute,
     217    const float& value)
     218{
     219        if (attribute == ATTR_FLOAT_VOLUME) {
     220            return _SetAttribute("Media:Volume", B_FLOAT_TYPE, &value,
     221                sizeof(float));
     222        }
     223
     224        return B_NOT_SUPPORTED;
     225}
     226
     227
     228status_t
     229FilePlaylistItem::GetAttribute(const Attribute& attribute,
     230    float& value) const
     231{
     232    if (attribute == ATTR_FLOAT_VOLUME) {
     233        return _GetAttribute("Media:Volume", B_FLOAT_TYPE, &value,
     234            sizeof(float));
     235    }
     236
    201237    return B_NOT_SUPPORTED;
    202238}
    203239
    FilePlaylistItem::MoveIntoTrash() 
    236272    err = _MoveIntoTrash(&fRefs, &fNamesInTrash);
    237273    if (err != B_OK)
    238274        return err;
    239    
     275
    240276    if (fImageRefs.empty())
    241277        return B_OK;
    242278
    FilePlaylistItem::RestoreFromTrash() 
    260296    err = _RestoreFromTrash(&fRefs, &fNamesInTrash);
    261297    if (err != B_OK)
    262298        return err;
    263    
     299
    264300    if (fImageRefs.empty())
    265301        return B_OK;
    266302
    FilePlaylistItem::ImageRef() const 
    381417
    382418    if (fImageRefs.empty())
    383419        return ref;
    384    
     420
    385421    return fImageRefs[0];
    386422}
    387423
    FilePlaylistItem::_SetAttribute(const char* attrName, type_code type, 
    407443
    408444status_t
    409445FilePlaylistItem::_GetAttribute(const char* attrName, type_code type,
    410     void* data, size_t size)
     446    void* data, size_t size) const
    411447{
    412448    BEntry entry(&fRefs[0], true);
    413449    BNode node(&entry);
    FilePlaylistItem::_MoveIntoTrash(vector<entry_ref>* refs, 
    452488                (*refs)[i].name, strerror(err));
    453489            return err;
    454490        }
    455    
     491
    456492        // Find a unique name for the entry in the trash
    457493        (*namesInTrash)[i] = (*refs)[i].name;
    458494        int32 uniqueNameIndex = 1;
    FilePlaylistItem::_MoveIntoTrash(vector<entry_ref>* refs, 
    464500            (*namesInTrash)[i] << ' ' << uniqueNameIndex;
    465501            uniqueNameIndex++;
    466502        }
    467    
     503
    468504        // Remember the original path
    469505        BPath originalPath;
    470506        entry.GetPath(&originalPath);
    471    
     507
    472508        // Finally, move the entry into the trash
    473509        err = entry.MoveTo(&trashDir, (*namesInTrash)[i].String());
    474510        if (err != B_OK) {
    FilePlaylistItem::_MoveIntoTrash(vector<entry_ref>* refs, 
    476512                trashPath, strerror(err));
    477513            return err;
    478514        }
    479    
     515
    480516        // Allow Tracker to restore this entry
    481517        BNode node(&entry);
    482518        BString originalPathString(originalPath.Path());
    FilePlaylistItem::_RestoreFromTrash(vector<entry_ref>* refs, 
    498534        fprintf(stderr, "failed to find Trash: %s\n", strerror(err));
    499535        return err;
    500536    }
    501    
     537
    502538    for (vector<entry_ref>::size_type i = 0; i < refs->size(); i++) {
    503539        // construct the entry to the file in the trash
    504540        // TODO: BEntry(const BDirectory* directory, const char* path) is broken!
    FilePlaylistItem::_RestoreFromTrash(vector<entry_ref>* refs, 
    513549        }
    514550        //entry.GetPath(&path);
    515551        //printf("moving '%s'\n", path.Path());
    516    
     552
    517553        // construct the folder of the original entry_ref
    518554        node_ref nodeRef;
    519555        nodeRef.device = (*refs)[i].device;
    FilePlaylistItem::_RestoreFromTrash(vector<entry_ref>* refs, 
    525561                "%s: %s\n", (*refs)[i].name, strerror(err));
    526562            return err;
    527563        }
    528    
     564
    529565        //path.SetTo(&originalDir, fItems[i].name);
    530566        //printf("as '%s'\n", path.Path());
    531    
     567
    532568        // Reset the name here, the user may have already moved the entry
    533569        // out of the trash via Tracker for example.
    534570        (*namesInTrash)[i] = "";
    535    
     571
    536572        // Finally, move the entry back into the original folder
    537573        err = entry.MoveTo(&originalDir, (*refs)[i].name);
    538574        if (err != B_OK) {
    FilePlaylistItem::_RestoreFromTrash(vector<entry_ref>* refs, 
    540576                "%s: %s\n", (*refs)[i].name, strerror(err));
    541577            return err;
    542578        }
    543    
     579
    544580        // Remove the attribute that helps Tracker restore the entry.
    545581        BNode node(&entry);
    546582        node.RemoveAttr("_trk/original_path");
  • src/apps/mediaplayer/playlist/FilePlaylistItem.h

    diff --git a/src/apps/mediaplayer/playlist/FilePlaylistItem.h b/src/apps/mediaplayer/playlist/FilePlaylistItem.h
    index a0c4da4..126cf78 100644
    a b public: 
    4343                                    const int64& value);
    4444    virtual status_t            GetAttribute(const Attribute& attribute,
    4545                                    int64& value) const;
     46   
     47    virtual status_t            SetAttribute(const Attribute& attribute,
     48                                    const float& value);
     49    virtual status_t            GetAttribute(const Attribute& attribute,
     50                                    float& value) const;
    4651
    4752    // methods
    4853    virtual BString             LocationURI() const;
    private: 
    6772                                    size_t size);
    6873            status_t            _GetAttribute(const char* attrName,
    6974                                    type_code type, void* data,
    70                                     size_t size);
     75                                    size_t size) const;
    7176            status_t            _MoveIntoTrash(vector<entry_ref>* refs,
    7277                                    vector<BString>* namesInTrash);
    7378            status_t            _RestoreFromTrash(vector<entry_ref>* refs,
  • src/apps/mediaplayer/playlist/PlaylistItem.cpp

    diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.cpp b/src/apps/mediaplayer/playlist/PlaylistItem.cpp
    index fde90a8..6bbe0e3 100644
    a b PlaylistItem::Listener::Listener() 
    1919{
    2020}
    2121
     22
    2223PlaylistItem::Listener::~Listener()
    2324{
    2425}
    2526
     27
    2628void PlaylistItem::Listener::ItemChanged(const PlaylistItem* item)
    2729{
    2830}
    void PlaylistItem::Listener::ItemChanged(const PlaylistItem* item) 
    3133// #pragma mark -
    3234
    3335
    34 //#define DEBUG_INSTANCE_COUNT
     36// #define DEBUG_INSTANCE_COUNT
    3537#ifdef DEBUG_INSTANCE_COUNT
    3638static vint32 sInstanceCount = 0;
    3739#endif
    PlaylistItem::TrackNumber() const 
    107109}
    108110
    109111
     112int64
     113PlaylistItem::LastFrame() const
     114{
     115    int64 lastFrame;
     116    if (GetAttribute(ATTR_INT64_FRAME, lastFrame) != B_OK)
     117        lastFrame = 0;
     118    return lastFrame;
     119}
     120
     121
     122float
     123PlaylistItem::LastVolume() const
     124{
     125    float lastVolume;
     126    if (GetAttribute(ATTR_FLOAT_VOLUME, lastVolume) != B_OK)
     127        lastVolume = -1;
     128    return lastVolume;
     129}
     130
     131
     132status_t
     133PlaylistItem::SetLastFrame(int64 value)
     134{
     135    return SetAttribute(ATTR_INT64_FRAME, value);
     136}
     137
     138
     139status_t
     140PlaylistItem::SetLastVolume(float value)
     141{
     142    return SetAttribute(ATTR_FLOAT_VOLUME, value);
     143}
     144
     145
    110146void
    111147PlaylistItem::SetPlaybackFailed()
    112148{
  • src/apps/mediaplayer/playlist/PlaylistItem.h

    diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.h b/src/apps/mediaplayer/playlist/PlaylistItem.h
    index b896df5..a34f9a7 100644
    a b public: 
    5353
    5454        ATTR_INT32_TRACK            = 'trck',
    5555        ATTR_INT32_YEAR             = 'year',
    56         ATTR_INT32_RATING           = 'rtng'
     56        ATTR_INT32_RATING           = 'rtng',
     57
     58        ATTR_INT64_FRAME            = 'fram',
     59
     60        ATTR_FLOAT_VOLUME           = 'volu'
    5761    } Attribute;
    5862
    5963    virtual status_t            SetAttribute(const Attribute& attribute,
    public: 
    7074                                    const int64& value) = 0;
    7175    virtual status_t            GetAttribute(const Attribute& attribute,
    7276                                    int64& value) const = 0;
     77   
     78    virtual status_t            SetAttribute(const Attribute& attribute,
     79                                    const float& value) = 0;
     80    virtual status_t            GetAttribute(const Attribute& attribute,
     81                                    float& value) const = 0;
    7382
    7483    // convenience access to attributes
    7584            BString             Name() const;
    public: 
    7887            BString             Title() const;
    7988
    8089            int32               TrackNumber() const;
     90            int64               LastFrame() const;
     91            float               LastVolume() const;
     92
     93            status_t            SetLastFrame(int64 value);
     94            status_t            SetLastVolume(float value);
    8195
    8296    // methods
    8397    virtual BString             LocationURI() const = 0;
  • src/apps/mediaplayer/settings/Settings.cpp

    diff --git a/src/apps/mediaplayer/settings/Settings.cpp b/src/apps/mediaplayer/settings/Settings.cpp
    index 7f1d00d..a4b22f9 100644
    a b mpSettings::operator!=(const mpSettings& other) const 
    2626        || useOverlays != other.useOverlays
    2727        || scaleBilinear != other.scaleBilinear
    2828        || scaleFullscreenControls != other.scaleFullscreenControls
     29        || resume != other.resume
    2930        || subtitleSize != other.subtitleSize
    3031        || subtitlePlacement != other.subtitlePlacement
    3132        || backgroundMovieVolumeMode != other.backgroundMovieVolumeMode
    Settings::Get(mpSettings& settings) const 
    6162    settings.scaleFullscreenControls
    6263        = fSettingsMessage.GetValue("scaleFullscreenControls", true);
    6364
     65    settings.resume
     66        = fSettingsMessage.GetValue("resume",
     67            (uint32)mpSettings::RESUME_ASK);
    6468    settings.subtitleSize
    6569        = fSettingsMessage.GetValue("subtitleSize",
    6670            (uint32)mpSettings::SUBTITLE_SIZE_MEDIUM);
    Settings::Update(const mpSettings& settings) 
    9599    fSettingsMessage.SetValue("scaleFullscreenControls",
    96100        settings.scaleFullscreenControls);
    97101
     102    fSettingsMessage.SetValue("resume", settings.resume);
    98103    fSettingsMessage.SetValue("subtitleSize", settings.subtitleSize);
    99104    fSettingsMessage.SetValue("subtitlePlacement", settings.subtitlePlacement);
    100105
  • src/apps/mediaplayer/settings/Settings.h

    diff --git a/src/apps/mediaplayer/settings/Settings.h b/src/apps/mediaplayer/settings/Settings.h
    index f8b3590..5dbc499 100644
    a b struct mpSettings { 
    3434                BG_MOVIES_HALF_VLUME = 1,
    3535                BG_MOVIES_MUTED = 2
    3636            };
     37            enum {
     38                RESUME_NEVER = 0,
     39                RESUME_ASK = 1,
     40                RESUME_ALWAYS = 2
     41            };
    3742
    3843            bool                autostart;
    3944            bool                closeWhenDonePlayingMovie;
    struct mpSettings { 
    4348            bool                useOverlays;
    4449            bool                scaleBilinear;
    4550            bool                scaleFullscreenControls;
     51            uint32              resume;
    4652            uint32              subtitleSize;
    4753            uint32              subtitlePlacement;
    4854            uint32              backgroundMovieVolumeMode;
  • src/apps/mediaplayer/settings/SettingsWindow.cpp

    diff --git a/src/apps/mediaplayer/settings/SettingsWindow.cpp b/src/apps/mediaplayer/settings/SettingsWindow.cpp
    index ea1cc17..d3eaa62 100644
    a b SettingsWindow::SettingsWindow(BRect frame) 
    9999        B_TRANSLATE("Scale controls in full screen mode"),
    100100        new BMessage(M_SETTINGS_CHANGED));
    101101
     102    fResumeOP = new BOptionPopUp("resume",
     103        B_TRANSLATE("Resume:"), new BMessage(M_SETTINGS_CHANGED));
     104    fResumeOP->AddOption(
     105        B_TRANSLATE("never"), mpSettings::RESUME_NEVER);
     106    fResumeOP->AddOption(
     107        B_TRANSLATE("ask every time"), mpSettings::RESUME_ASK);
     108    fResumeOP->AddOption(
     109        B_TRANSLATE("always"), mpSettings::RESUME_ALWAYS);
     110
    102111    fSubtitleSizeOP = new BOptionPopUp("subtitleSize",
    103112        B_TRANSLATE("Subtitle size:"), new BMessage(M_SETTINGS_CHANGED));
    104113    fSubtitleSizeOP->AddOption(
    SettingsWindow::SettingsWindow(BRect frame) 
    156165                    .End()
    157166                    .Add(fLoopMoviesCB)
    158167                    .Add(fLoopSoundsCB)
     168                    .Add(fResumeOP)
    159169                .End()
    160170            .End()
    161171            .AddStrut(kSpacing)
    SettingsWindow::AdoptSettings() 
    270280    fScaleBilinearCB->SetValue(fSettings.scaleBilinear);
    271281    fScaleFullscreenControlsCB->SetValue(fSettings.scaleFullscreenControls);
    272282
     283    fResumeOP->SetValue(fSettings.resume);
    273284    fSubtitleSizeOP->SetValue(fSettings.subtitleSize);
    274285    fSubtitlePlacementOP->SetValue(fSettings.subtitlePlacement);
    275286
    SettingsWindow::ApplySettings() 
    300311    fSettings.scaleFullscreenControls
    301312        = fScaleFullscreenControlsCB->Value() == B_CONTROL_ON;
    302313
     314    fSettings.resume = fResumeOP->Value();
    303315    fSettings.subtitleSize = fSubtitleSizeOP->Value();
    304316    fSettings.subtitlePlacement = fSubtitlePlacementOP->Value();
    305317
  • src/apps/mediaplayer/settings/SettingsWindow.h

    diff --git a/src/apps/mediaplayer/settings/SettingsWindow.h b/src/apps/mediaplayer/settings/SettingsWindow.h
    index 6285620..312927a 100644
    a b private: 
    4747        BCheckBox*              fScaleBilinearCB;
    4848        BCheckBox*              fScaleFullscreenControlsCB;
    4949
     50        BOptionPopUp*           fResumeOP;
    5051        BOptionPopUp*           fSubtitleSizeOP;
    5152        BOptionPopUp*           fSubtitlePlacementOP;
    5253