From 3d9652ae356f23d645200ca83cdce25ff4fb9690 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 26 Feb 2016 13:23:42 +0100 Subject: [PATCH] TagStream: add TagBuilder overload with ScanGenericTags() fallback This commit adds support for APE/ID3 tags from NFS/SMB files. See http://bugs.musicpd.org/view.php?id=4270 --- NEWS | 1 + src/SongUpdate.cxx | 6 ++---- src/TagStream.cxx | 28 ++++++++++++++++++++++++++++ src/TagStream.hxx | 15 +++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 571b2cbb6..f201928f2 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ ver 0.20 (not yet released) - id3: remove the "id3v1_encoding" setting; by definition, all ID3v1 tags are ISO-Latin-1 - ape: support APE replay gain on remote files + - read ID3 tags from NFS/SMB * decoder - improved error logging - report I/O errors to clients diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx index 46582bf4b..412630d97 100644 --- a/src/SongUpdate.cxx +++ b/src/SongUpdate.cxx @@ -92,8 +92,7 @@ Song::UpdateFile(Storage &storage) if (path_fs.IsNull()) { const auto absolute_uri = storage.MapUTF8(relative_uri.c_str()); - if (!tag_stream_scan(absolute_uri.c_str(), - full_tag_handler, &tag_builder)) + if (!tag_stream_scan(absolute_uri.c_str(), tag_builder)) return false; } else { if (!tag_file_scan(path_fs, tag_builder)) @@ -165,8 +164,7 @@ DetachedSong::Update() return LoadFile(path_fs); } else if (IsRemote()) { TagBuilder tag_builder; - if (!tag_stream_scan(uri.c_str(), full_tag_handler, - &tag_builder)) + if (!tag_stream_scan(uri.c_str(), tag_builder)) return false; mtime = 0; diff --git a/src/TagStream.cxx b/src/TagStream.cxx index 7c91ff1ca..dbc67ecb2 100644 --- a/src/TagStream.cxx +++ b/src/TagStream.cxx @@ -19,6 +19,9 @@ #include "config.h" #include "TagStream.hxx" +#include "tag/Generic.hxx" +#include "tag/TagHandler.hxx" +#include "tag/TagBuilder.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" #include "decoder/DecoderList.hxx" @@ -72,3 +75,28 @@ tag_stream_scan(const char *uri, const TagHandler &handler, void *ctx) IgnoreError()); return is && tag_stream_scan(*is, handler, ctx); } + +bool +tag_stream_scan(InputStream &is, TagBuilder &builder) +{ + assert(is.IsReady()); + + if (!tag_stream_scan(is, full_tag_handler, &builder)) + return false; + + if (builder.IsEmpty()) + ScanGenericTags(is, full_tag_handler, &builder); + + return true; +} + +bool +tag_stream_scan(const char *uri, TagBuilder &builder) +{ + Mutex mutex; + Cond cond; + + auto is = InputStream::OpenReady(uri, mutex, cond, + IgnoreError()); + return is && tag_stream_scan(*is, builder); +} diff --git a/src/TagStream.hxx b/src/TagStream.hxx index a8690d62b..5d766bd8a 100644 --- a/src/TagStream.hxx +++ b/src/TagStream.hxx @@ -24,6 +24,7 @@ class InputStream; struct TagHandler; +class TagBuilder; /** * Scan the tags of an #InputStream. Invokes matching decoder @@ -38,4 +39,18 @@ tag_stream_scan(InputStream &is, const TagHandler &handler, void *ctx); bool tag_stream_scan(const char *uri, const TagHandler &handler, void *ctx); +/** + * Scan the tags of an #InputStream. Invokes matching decoder + * plugins, and falls back to generic scanners (APE and ID3) if no + * tags were found (but the file was recognized). + * + * @return true if the file was recognized (even if no metadata was + * found) + */ +bool +tag_stream_scan(InputStream &is, TagBuilder &builder); + +bool +tag_stream_scan(const char *uri, TagBuilder &builder); + #endif