Skip to content

Commit

Permalink
Merge pull request #617 from philippe44/PR611&612-follow-up
Browse files Browse the repository at this point in the history
making sure core url does not include startime
  • Loading branch information
mherger committed Jun 17, 2021
2 parents 4225bda + d453f8b commit b9b784c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 25 deletions.
8 changes: 5 additions & 3 deletions DEVELOPERS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ When it returns, scanUrl provides a new $track that replaces the current one in
When playing again that track from the playlist, LMS would normally scan again that redirected
$track->url which might be gone (see below).

Not that scanURL also replaces the $song->streamUrl by the $newTrack->url if this url is different
from the $url passed as an argument. See "thin protocol handler" for more explanations.
Not that scanURL also replaces the $song->streamUrl by the $newTrack->url if streamUrl still equals
to the $url parameter when song is being opened/created. This allows protocol handler to change it
as they want, but still update it when built-in scan has control.See "thin protocol handler" for
more explanations.

-------------------------- Issue of "volatile" redirection -------------------------------

Expand Down Expand Up @@ -87,7 +89,7 @@ parsed track, shall be interecepted to recover the redirected url and replace it
url (at least add-again your <myph:://> to was is returned) to make sure that the track, once
replaced in the playlist, will still use your protocol handler. This is also where it's recommended
to set $song->streamUrl to the streamable url, often simply the $newtrack->url. Note that because
$track->url is reset to the original value, the $song->streamUrl will not be overwritten by scanURL
$song->streamUrl is updated by the protocol handler, it will not be overwritten by scanURL

Best is to look at Slim::Plugin::Podcast as an example of such thin protocol handler

Expand Down
4 changes: 2 additions & 2 deletions Slim/Player/Song.pm
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ sub getNextSong {
}

$track = $newTrack;
# need to replace streamUrl if we have been redirected/updated
$self->streamUrl($track->url) if $track->url ne $url;
# need to replace streamUrl unless scanner has changed it
$self->streamUrl($track->url) if $self->streamUrl eq $url;
}

# maybe we just found or scanned a playlist
Expand Down
19 changes: 16 additions & 3 deletions Slim/Plugin/Podcast/Plugin.pm
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ sub initPlugin {
func => \&trackInfoMenu,
) );

# create wrapped pseudo-tracks for recently played to have title during scanUrl
foreach my $item (@{$prefs->get('recent')}) {
my $track = Slim::Schema->updateOrCreate( {
url => wrapUrl($item->{url}),
attributes => {
TITLE => $item->{title},
ARTWORK => $item->{cover},
},
} );
}

%recentlyPlayed = map { $_->{url} => $_ } reverse @{$prefs->get('recent')};

$class->SUPER::initPlugin(
Expand All @@ -92,12 +103,14 @@ sub shutdownPlugin {

sub updateRecentlyPlayed {
my ($class, $client, $song) = @_;
my ($url) = unwrapUrl($song->currentTrack->url);
my $track = $song->currentTrack;
my ($url) = unwrapUrl($track->url);

$recentlyPlayed{$url} = {
url => $url,
title => $song->currentTrack->title,
cover => Slim::Player::ProtocolHandlers->iconForURL($song->currentTrack->url, $client),
title => Slim::Music::Info::getCurrentTitle($client, $track->url),
# this is not great as we should not know that...
cover => $cache->get('remote_image_' . $track->url) || Slim::Player::ProtocolHandlers->iconForURL($track->url, $client),
duration => $song->duration,
};
}
Expand Down
48 changes: 31 additions & 17 deletions Slim/Plugin/Podcast/ProtocolHandler.pm
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,38 @@ Slim::Player::ProtocolHandlers->registerHandler('podcast', __PACKAGE__);
# remove podcast:// protocol to scan real url
sub scanUrl {
my ( $class, $url, $args ) = @_;
my $song = $args->{song};
my ($scanUrl, $startTime) = Slim::Plugin::Podcast::Plugin::unwrapUrl($url);

my $song = $args->{song};
my ($httpUrl, $startTime) = Slim::Plugin::Podcast::Plugin::unwrapUrl($url);
my $cb = $args->{cb};

if ($startTime) {
# make a unique & clean url with no trailing start time
$url = Slim::Plugin::Podcast::Plugin::wrapUrl($httpUrl);

# set seekdata for getNextTrack (once $song->track is updated)
$song->seekdata({ startTime => $startTime});
}

$args->{cb} = sub {
my $track = shift;

main::INFOLOG && $log->info("Scanned podcast $url from ($startTime) for title: ", $song->track->title);
main::INFOLOG && $log->info("Scanned podcast $url => ", $track->url, " from ($startTime) for title: ", $song->track->title);

# use the scanned track to get streamable url, ignore scanned title and coverart
$song->streamUrl($track->url);
$track->title(Slim::Music::Info::getCurrentTitle($args->{client}, $url));
$track->cover(0);

# reset track's url first otherwise url-based methods will fail
# reset track's url - from now on all $url-based requests will refer to that track
$track->url($url);

# set seekdata so they can be used in proxied and direct
if ($startTime) {
my $seekdata = $song->getSeekData($startTime);
$song->seekdata($seekdata);
}

# must update playlist time for webUI to refresh - not sure why
$song->master->currentPlaylistUpdateTime( Time::HiRes::time() );
$cb->($track, @_);
};

$class->SUPER::scanUrl($scanUrl, $args);
$class->SUPER::scanUrl($httpUrl, $args);
}

sub shouldCacheImage { 1 }
Expand All @@ -66,7 +72,6 @@ sub onStop {
my $elapsed = $song->master->controller->playingSongElapsed;
my ($url) = Slim::Plugin::Podcast::Plugin::unwrapUrl($song->currentTrack->url);


if ($elapsed > 15 && (!$song->duration || $elapsed < $song->duration - 15)) {
$cache->set("podcast-$url", int ($elapsed), '30days');
main::INFOLOG && $log->info("Last position for $url is $elapsed");
Expand All @@ -78,13 +83,22 @@ sub onStop {
sub onStream {
my ($self, $client, $song) = @_;

# ignore updated title that comes from parsing stream
my $title = Slim::Music::Info::getCurrentTitle($client, $song->currentTrack->redir);
Slim::Music::Info::setCurrentTitle($song->currentTrack->url, $title, $client);
$song->currentTrack->title($title);

Slim::Plugin::Podcast::Plugin->updateRecentlyPlayed($client, $song);
}

sub getNextTrack {
my ( $class, $song, $successCb, $errorCb ) = @_;
my $seekdata = $song->seekdata;

# set seekdata *after* $song->track has been updated by scanUrl
# so that Slim::Music::Info::getBitrate works from unwrapped url
if (my $startTime = $seekdata->{startTime}) {
$song->seekdata($song->getSeekData($startTime));
main::INFOLOG && $log->info("starting from $startTime");
}

$successCb->();
}


1;

0 comments on commit b9b784c

Please sign in to comment.