mopidy
mopidy copied to clipboard
Save (playlist) state on each playlist change
I use mopidy on a Raspberry Pi with a (mostly) read-only root fs as music player. I turn the power supply on and off for starting and stopping the music. With mopidy 2 I used the qsaver plugin to make sure the playback resumes my playlist. Mopidy 3 persists the state when I stop mopidy and shutdown the OS, but it does not persist any state in the background. So if I hard kill the machine mopidy always start with an empty state.
Would it be possible to trigger the state persistence on each playlist change? I wouldn't expect that the state contains the position inside a track, but it would be great if the playlist and the last played track could be recovered after a boot. I think from this feature desktop users could benefit, too. Even nowadays processes crash and stop unexpected.
I have managed to do this by making some changes in mopidy/core/actor.py
.
Firstly, move the lines try: state_file_unlink() + error handler
from near the end of _load_state()
, and put into _save_state()
after save_state
has got the filename. With this change, the state file is only ever missing for a fraction of a second.
And the second thing is to make calls to self.teardown()
in each of the functions:
volume_changed
, position_changed
, state_changed
, stream_changed
and mute_changed
. (A teardown comment specifically says do-not-use; but all it does is check that the save state option is configured, and then saves-the-state if so.)
The one thing I'm missing is a pause_changed()
function, so the state file does not get updated when the audio is paused.
I'm not a python programmer, so I may not have done things properly, but it works for me. actor.py.txt actor.py-diffs.txt
_save_state
does not look at all thread-safe to me. I would guess that is the main reason we suggest you don't call it yourself from random places.
Ahh, yeah, my programming expertise was developed long before threads unfortunately. Guess I'll have to try to understand them now. Thanks for information!!
If you have time, could you please say what sort of things in _save_state look unsafe for threads. The only thing I can see is that the state file might get deleted by a thread which clashes with writing by another.
Yes, exactly that. Do you not think that could give you some problems?
OK thanks. I think I've got around that, so I'll post again with what I've done. Probably tomorrow, cheers, Mike.
I have changed the way the saved state file is handled in as much that if the save_state option is true, then there will always be an up to date state_file on disk. And if the save_state option is false then any state_file on disk is deleted whenever Mopidy starts up. I think the code is thread safe now. As I said previously, I have no experience with Python, so my code may not be up-to-scratch. actor.py.diff.txt actor.py.txt
Thanks for providing your changes, perhaps anyone else interested can make use of them. However, this use-case is outside of what we had in mind for the state restoration functionality. It would require more work to support this properly and it's not something we are looking at doing right now.