TagAny: support CUE tracks
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1482
This commit is contained in:
parent
71cd6e6248
commit
2aed7378cc
1
NEWS
1
NEWS
|
@ -1,6 +1,7 @@
|
||||||
ver 0.23.6 (not yet released)
|
ver 0.23.6 (not yet released)
|
||||||
* protocol
|
* protocol
|
||||||
- support filename "cover.webp" for "albumart" command
|
- support filename "cover.webp" for "albumart" command
|
||||||
|
- support "readcomments" and "readpicture" on CUE tracks
|
||||||
* decoder
|
* decoder
|
||||||
- ffmpeg: fix end-of-file check (update stuck at empty files)
|
- ffmpeg: fix end-of-file check (update stuck at empty files)
|
||||||
- opus: fix "readpicture" on Opus files
|
- opus: fix "readpicture" on Opus files
|
||||||
|
|
|
@ -21,12 +21,16 @@
|
||||||
#include "TagStream.hxx"
|
#include "TagStream.hxx"
|
||||||
#include "TagFile.hxx"
|
#include "TagFile.hxx"
|
||||||
#include "tag/Generic.hxx"
|
#include "tag/Generic.hxx"
|
||||||
|
#include "song/LightSong.hxx"
|
||||||
|
#include "db/Interface.hxx"
|
||||||
#include "storage/StorageInterface.hxx"
|
#include "storage/StorageInterface.hxx"
|
||||||
#include "client/Client.hxx"
|
#include "client/Client.hxx"
|
||||||
#include "protocol/Ack.hxx"
|
#include "protocol/Ack.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
#include "util/Compiler.h"
|
#include "util/Compiler.h"
|
||||||
|
#include "util/ScopeExit.hxx"
|
||||||
|
#include "util/StringCompare.hxx"
|
||||||
#include "util/UriExtract.hxx"
|
#include "util/UriExtract.hxx"
|
||||||
#include "LocateUri.hxx"
|
#include "LocateUri.hxx"
|
||||||
|
|
||||||
|
@ -51,10 +55,67 @@ TagScanFile(const Path path_fs, TagHandler &handler)
|
||||||
ScanGenericTags(path_fs, handler);
|
ScanGenericTags(path_fs, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_DATABASE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collapse "../" prefixes in a URI relative to the specified base
|
||||||
|
* URI.
|
||||||
|
*/
|
||||||
|
static std::string
|
||||||
|
ResolveUri(std::string_view base, const char *relative)
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
const char *rest = StringAfterPrefix(relative, "../");
|
||||||
|
if (rest == nullptr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (base == ".")
|
||||||
|
throw ProtocolError(ACK_ERROR_NO_EXIST, "Bad real URI");
|
||||||
|
|
||||||
|
base = PathTraitsUTF8::GetParent(base);
|
||||||
|
relative = rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PathTraitsUTF8::Build(base, relative);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the specified song in the database and return its
|
||||||
|
* (resolved) "real" URI.
|
||||||
|
*/
|
||||||
|
static std::string
|
||||||
|
GetRealSongUri(Client &client, std::string_view uri)
|
||||||
|
{
|
||||||
|
const auto &db = client.GetDatabaseOrThrow();
|
||||||
|
|
||||||
|
const auto *song = db.GetSong(uri);
|
||||||
|
if (song == nullptr)
|
||||||
|
throw ProtocolError(ACK_ERROR_NO_EXIST, "No such song");
|
||||||
|
|
||||||
|
AtScopeExit(&db, song) { db.ReturnSong(song); };
|
||||||
|
|
||||||
|
if (song->real_uri == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return ResolveUri(PathTraitsUTF8::GetParent(uri), song->real_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
TagScanDatabase(Client &client, const char *uri, TagHandler &handler)
|
TagScanDatabase(Client &client, const char *uri, TagHandler &handler)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
|
const auto real_uri = GetRealSongUri(client, uri);
|
||||||
|
|
||||||
|
if (!real_uri.empty()) {
|
||||||
|
uri = real_uri.c_str();
|
||||||
|
|
||||||
|
// TODO: support absolute paths?
|
||||||
|
if (uri_has_scheme(uri))
|
||||||
|
return TagScanStream(uri, handler);
|
||||||
|
}
|
||||||
|
|
||||||
const Storage *storage = client.GetStorage();
|
const Storage *storage = client.GetStorage();
|
||||||
if (storage == nullptr) {
|
if (storage == nullptr) {
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue