Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support playback restore after player power loss #249

Merged
merged 4 commits into from Apr 29, 2019

Conversation

maniac103
Copy link
Contributor

The commits in this PR are meant to support correctly restoring playback (especially radio station playback) after the player disappeared after losing power. Previously radio station playback didn't resume after restoring power.
My use case is a SB receiver I've mounted in some cabinet in my bathroom whose power supply is switched by a wall (light) switch. I usually use this one with radio stations, so want to turn it off via wall switch and want it to continue playback when I turn it on via wall switch again.

For rationale on each part of the change, please see the commit messages.

Copy link
Contributor

@mherger mherger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this is not about powering off a unit, but about it going away because the plug is being pulled? Does this integrate with the existing prefs to control behaviour in case of power off etc.? Eg. would this not kick in if I had selected to "... Remain stopped at power on"?

Overall looking simple and good - assuming above questions are ok. Could the check for playlist be improved?

Slim/Networking/Slimproto.pm Outdated Show resolved Hide resolved
# Treat radio stream as playlist, because that's what they are.
# If we don't do this, we'll end up attempting to play the served m3u.

if ($entry =~ m{^http://opml\.(?:radiotime|tunein)\.com}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would only help with stations played from the Radio menu, but no other stations. Is this change even required?

And then the regex should at least match https, too ;-)

Copy link
Contributor Author

@maniac103 maniac103 Apr 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would only help with stations played from the Radio menu, but no other stations.

That's correct, but I'm not sure what other information one could use to restore the 'playlist' flag. Any other ideas?

Is this change even required?

IIRC (it's been a few years since I initially wrote this) the issue is that when restoring the playlist after power-off, the radio station M3U was restored as normal track, not as playlist, thus the M3U was attempted to be played instead of the MP3 stream it points to. So yes, I'm pretty sure it's required. I can try to gather the sequence of events without this piece again, though.
Edit: Reading through the code again I think the reason was that initial radio station playlist loading happens via

  • Player::Protocols::HTTP::scanUrl
  • -> Utils::Scanner::Remote::scanURL
  • -> Utils::Scanner::Remote::readRemoteHeaders
  • -> Utils::Scanner::Remote::parsePlaylist

where the latter unconditionally sets the playlist flag. This playlist (M3U) becomes part of the player playlist, and when restoring that playlist via

  • Player::Client::startup
  • -> Player::Playlist::loadClientPlaylist
  • -> Formats::Playlists::M3U::read
  • -> Formats::Playlists::M3U::_item
  • -> Formats::Playlists::Base::_updateMetaData

the playlist flag of said M3U item isn't set. Unfortunately the radio M3U doesn't have the m3u file extension which would make it distinguishable. As I said, other ideas are totally welcome ;-)

For reference, this is the client playlist of the player in question:

#CURTRACK 0
#EXTM3U
#EXTURL:http://opml.radiotime.com/Tune.ashx?id=s6649&formats=aac,ogg,mp3,wma,wmvoice&partnerId=16&serial=0180a109688f558ab300362ce9ee52ca
#EXTINF:-1,Radio PSR
http://opml.radiotime.com/Tune.ashx?id=s6649&formats=aac,ogg,mp3,wma,wmvoice&partnerId=16&serial=0180a109688f558ab300362ce9ee52ca

And then the regex should at least match https, too ;-)

Good point, will update accordingly :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https is now covered in the regex. Please let me know if you got any better idea for the playlist flag thing.

@mherger
Copy link
Contributor

mherger commented Apr 17, 2019

Hmm... why would this only work with online radio, but eg. not with local music or a Spotify track?

@maniac103
Copy link
Contributor Author

Hmm... why would this only work with online radio, but eg. not with local music or a Spotify track?

It should work with those as well. I just used radio in my description as that's my main use case, and radio is the only case needing the playlist patch. The other parts apply to other sources as well, even though I only ever tried local playback and radio stations.

I understand this is not about powering off a unit, but about it going away because the plug is being pulled?

Correct. The mentioned wall switch 'pulls the plug' by turning off a wall outlet the player is connected to.

Does this integrate with the existing prefs to control behaviour in case of power off etc.? Eg. would this not kick in if I had selected to "... Remain stopped at power on"?

Yes. These patches just make sure the relevant parts in Player::power that check the preference are actually reached. The preference value is still checked there.

When not doing so, on startup the radio stream M3U will be attempted to
be played, which (obviously) fails.
Store 'playing at power off' pref if a playing client vanishes (e.g.
because it's powered down) so we can restore playing state when it
reappears.
Doing so is important for restoring the client playlist before powering
up, which will use the playlist.
Previously the power() call was mostly a no-op, as $currOn always equals
$on when called from Power::init, as both values are loaded from the
same preference.
@@ -55,6 +63,7 @@ sub _updateMetaData {
'url' => $entry,
'attributes' => $attributes,
'readTags' => 1,
'playlist' => $playlist,
} );
}
Copy link
Contributor

@mherger mherger Apr 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to just the following one line change:

		$track = Slim::Schema->updateOrCreate( {
			'url'        => $entry,
			'attributes' => $attributes,
			'readTags'   => 1,
			'playlist'   => Slim::Music::Info::isPlaylist($entry),
		} );

Then I think we're good to merge this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I knew there had to be a better solution :-) Thanks!

@mherger mherger merged commit 6d1694c into LMS-Community:public/7.9 Apr 29, 2019
@mherger
Copy link
Contributor

mherger commented Apr 29, 2019

Never mind my previous comment. I'm going to change this right after the merge.

Thanks a lot!

@IDC-Dragon
Copy link

IDC-Dragon commented Sep 18, 2020

@maniac103, you'd be my hero, I was missing this feature since years. SB not continuing where left off is the only reason I still use an old Archos Jukebox in the kitchen, which is now sadly falling apart. My use case is local FLAC files from LMS, not radio. Possibly Spotify using "Spotty" plugin.

Just updated LMS to v7.9.3, I wasn't up to date since a while. However, I'm getting the following behaviour:

  • Squeezebox Touch resumes, actually skips back about 15 seconds from last position. It shows the home screen, not the while playing screen where left off.
  • Squeezebox Duet Receiver doesn't resume playback. The LMS web interface shows it in playing state, looping 5 secs over and over, probably because the progress is drawn locally. Toggling pause/play does not change anything, however clicking the seek bar does.
  • Squeezebox 2 doesn't resume playback. It shows the correct screen, title and position, but just doesn't play. When I hit play at the remote, the title starts from the beginning, not the position it was showing. Unfortunately the Squeezebox 2 is my kitchen device, where I'd love this to work...

Am I doing something wrong, is there some player configuration missing? All are set to "Pause at power off / Resume at power on".

Kudos, many thanks!
Jörg

@maniac103
Copy link
Contributor Author

Am I doing something wrong, is there some player configuration missing? Both are set to "Pause at power off / Resume at power on".

That should be the only required configuration here. I only tested this on a SB Receiver device (which should be close enough to your SB2), so I'm not sure how the Touch will react to this.
I'll update to 7.9.3 and give this a try with local music files when I find some time.

@IDC-Dragon
Copy link

IDC-Dragon commented Sep 19, 2020

I've just re-tested with "your" use case, internet radio.
The behaviour is about the same:

  • SB2 and SB Duet Receiver don't resume, need to be "kicked" into playback by hand.
  • The SB Touch resumes, but shows the home screen.
    I was a bit too impatient with the Touch, same with file playback: after a minute it shows the playback screen, because this is the "screensaver" when playing. But not from the start, which would be nice.

Something seems to be missing... :-(

@IDC-Dragon
Copy link

@maniac103 , by no means being pushy, how is your "finding some time" coming along?

@maniac103
Copy link
Contributor Author

Sorry, I completely forgot about it :-/ I just tried with a local playlist and can confirm it doesn't resume correctly: the playlist is kept, but it stays in paused state and playlist position isn't correct either (I left it off at 2/27 and it resumed at 27/27).
I'll see what I can do there. Debugging will be a bit time consuming because it takes about 5 minutes for the server to notice the vanishing client.

@IDC-Dragon
Copy link

@maniac103, sorry to bother again. My Archos now did fall apart, and I'd like to establish/revive the Squeezebox as our kitchen stereo. However, without functional resume the WAF is zero, I'm getting into domestic trouble. She piled up a stack of CDs instead...
After power resume, the SB2 is completely idle. It takes 10(!) button presses to get back into the desired shuffle across music library and activate title display.
Should there be some info in the log about lost or resumed player? I didn't see anything. What does it take to debug/implement the feature? If no avail, can this be externally automated, by some API of LMS?

@maniac103
Copy link
Contributor Author

maniac103 commented May 15, 2021

What does it take to debug/implement the feature?

Do the power in/off and monitor Server Loge (and maybe add debug messages) at the same time. This is a cumbersome process, which is why I keep forgetting about it :-/
The expected sequence of events is:

  • player is powered on and playing
  • cut power
  • server should not notice at first
  • after a timeout (1 minute or something) the server should notice, and my new code should apply the 'pause on power off' setting in that case (commit daeefab)
  • when restoring power, server notices the player due to it connecting to the server
  • at that point, the 'resume at power on' setting should come into play, just as if it were soft powered off before (-> commit 34613ca)

If no avail, can this be externally automated, by some API of LMS?

I am not aware of anything like that.

@maniac103
Copy link
Contributor Author

Finally got around to look into this (at last!) -> #698

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants