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

making sure core url does not include startime #617

Merged
merged 1 commit into from
Jun 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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;