diff --git a/src/command/PlaylistCommands.cxx b/src/command/PlaylistCommands.cxx
index 77131227d..858cd2029 100644
--- a/src/command/PlaylistCommands.cxx
+++ b/src/command/PlaylistCommands.cxx
@@ -38,6 +38,7 @@
 #include "util/UriUtil.hxx"
 #include "util/ConstBuffer.hxx"
 #include "util/ChronoUtil.hxx"
+#include "LocateUri.hxx"
 
 bool
 playlist_commands_available() noexcept
@@ -66,12 +67,17 @@ handle_save(Client &client, Request args, gcc_unused Response &r)
 CommandResult
 handle_load(Client &client, Request args, gcc_unused Response &r)
 {
+	const auto uri = LocateUri(args.front(), &client
+#ifdef ENABLE_DATABASE
+					   , nullptr
+#endif
+					   );
 	RangeArg range = args.ParseOptional(1, RangeArg::All());
 
 	const ScopeBulkEdit bulk_edit(client.GetPartition());
 
 	const SongLoader loader(client);
-	playlist_open_into_queue(args.front(),
+	playlist_open_into_queue(uri,
 				 range.start, range.end,
 				 client.GetPlaylist(),
 				 client.GetPlayerControl(), loader);
@@ -81,7 +87,11 @@ handle_load(Client &client, Request args, gcc_unused Response &r)
 CommandResult
 handle_listplaylist(Client &client, Request args, Response &r)
 {
-	const char *const name = args.front();
+	const auto name = LocateUri(args.front(), &client
+#ifdef ENABLE_DATABASE
+					   , nullptr
+#endif
+					   );
 
 	if (playlist_file_print(r, client.GetPartition(), SongLoader(client),
 				name, false))
@@ -93,7 +103,11 @@ handle_listplaylist(Client &client, Request args, Response &r)
 CommandResult
 handle_listplaylistinfo(Client &client, Request args, Response &r)
 {
-	const char *const name = args.front();
+	const auto name = LocateUri(args.front(), &client
+#ifdef ENABLE_DATABASE
+					   , nullptr
+#endif
+					   );
 
 	if (playlist_file_print(r, client.GetPartition(), SongLoader(client),
 				name, true))
diff --git a/src/playlist/PlaylistAny.cxx b/src/playlist/PlaylistAny.cxx
index 2cf5bd020..081433652 100644
--- a/src/playlist/PlaylistAny.cxx
+++ b/src/playlist/PlaylistAny.cxx
@@ -17,6 +17,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include "LocateUri.hxx"
 #include "PlaylistAny.hxx"
 #include "PlaylistStream.hxx"
 #include "PlaylistMapper.hxx"
@@ -25,17 +26,26 @@
 #include "config.h"
 
 std::unique_ptr<SongEnumerator>
-playlist_open_any(const char *uri,
+playlist_open_any(const LocatedUri &located_uri,
 #ifdef ENABLE_DATABASE
 		  const Storage *storage,
 #endif
 		  Mutex &mutex)
 {
-	return uri_has_scheme(uri)
-		? playlist_open_remote(uri, mutex)
-		: playlist_mapper_open(uri,
+	switch (located_uri.type) {
+	case LocatedUri::Type::ABSOLUTE:
+		return playlist_open_remote(located_uri.canonical_uri, mutex);
+
+	case LocatedUri::Type::PATH:
+		return playlist_open_path(located_uri.path, mutex);
+
+	case LocatedUri::Type::RELATIVE:
+		return playlist_mapper_open(located_uri.canonical_uri,
 #ifdef ENABLE_DATABASE
 				       storage,
 #endif
 				       mutex);
+	}
+
+	gcc_unreachable();
 }
diff --git a/src/playlist/PlaylistAny.hxx b/src/playlist/PlaylistAny.hxx
index 7edab66c3..318e78f4a 100644
--- a/src/playlist/PlaylistAny.hxx
+++ b/src/playlist/PlaylistAny.hxx
@@ -34,7 +34,7 @@ class Storage;
  * music or playlist directory.
  */
 std::unique_ptr<SongEnumerator>
-playlist_open_any(const char *uri,
+playlist_open_any(const LocatedUri &located_uri,
 #ifdef ENABLE_DATABASE
 		  const Storage *storage,
 #endif
diff --git a/src/playlist/PlaylistQueue.cxx b/src/playlist/PlaylistQueue.cxx
index 61469488c..712a50f8e 100644
--- a/src/playlist/PlaylistQueue.cxx
+++ b/src/playlist/PlaylistQueue.cxx
@@ -18,6 +18,7 @@
  */
 
 #include "config.h"
+#include "LocateUri.hxx"
 #include "PlaylistQueue.hxx"
 #include "PlaylistAny.hxx"
 #include "PlaylistSong.hxx"
@@ -63,7 +64,7 @@ playlist_load_into_queue(const char *uri, SongEnumerator &e,
 }
 
 void
-playlist_open_into_queue(const char *uri,
+playlist_open_into_queue(const LocatedUri &uri,
 			 unsigned start_index, unsigned end_index,
 			 playlist &dest, PlayerControl &pc,
 			 const SongLoader &loader)
@@ -78,7 +79,7 @@ playlist_open_into_queue(const char *uri,
 	if (playlist == nullptr)
 		throw PlaylistError::NoSuchList();
 
-	playlist_load_into_queue(uri, *playlist,
+	playlist_load_into_queue(uri.canonical_uri, *playlist,
 				 start_index, end_index,
 				 dest, pc, loader);
 }
diff --git a/src/playlist/PlaylistQueue.hxx b/src/playlist/PlaylistQueue.hxx
index 44ac8dc85..ccaf2ab5c 100644
--- a/src/playlist/PlaylistQueue.hxx
+++ b/src/playlist/PlaylistQueue.hxx
@@ -49,7 +49,7 @@ playlist_load_into_queue(const char *uri, SongEnumerator &e,
  * play queue.
  */
 void
-playlist_open_into_queue(const char *uri,
+playlist_open_into_queue(const LocatedUri &uri,
 			 unsigned start_index, unsigned end_index,
 			 playlist &dest, PlayerControl &pc,
 			 const SongLoader &loader);
diff --git a/src/playlist/Print.cxx b/src/playlist/Print.cxx
index be985e091..a5f6c755e 100644
--- a/src/playlist/Print.cxx
+++ b/src/playlist/Print.cxx
@@ -18,6 +18,7 @@
  */
 
 #include "config.h"
+#include "LocateUri.hxx"
 #include "Print.hxx"
 #include "PlaylistAny.hxx"
 #include "PlaylistSong.hxx"
@@ -55,7 +56,7 @@ playlist_provider_print(Response &r,
 bool
 playlist_file_print(Response &r, Partition &partition,
 		    const SongLoader &loader,
-		    const char *uri, bool detail)
+		    const LocatedUri &uri, bool detail)
 {
 	Mutex mutex;
 
@@ -71,6 +72,6 @@ playlist_file_print(Response &r, Partition &partition,
 	if (playlist == nullptr)
 		return false;
 
-	playlist_provider_print(r, loader, uri, *playlist, detail);
+	playlist_provider_print(r, loader, uri.canonical_uri, *playlist, detail);
 	return true;
 }
diff --git a/src/playlist/Print.hxx b/src/playlist/Print.hxx
index 25cd77ebc..16d779ab3 100644
--- a/src/playlist/Print.hxx
+++ b/src/playlist/Print.hxx
@@ -34,6 +34,6 @@ struct Partition;
 bool
 playlist_file_print(Response &r, Partition &partition,
 		    const SongLoader &loader,
-		    const char *uri, bool detail);
+		    const LocatedUri &uri, bool detail);
 
 #endif