input/icy: support "charset" parameter in URI fragment

Closes https://github.com/MusicPlayerDaemon/MPD/issues/616
This commit is contained in:
Max Kellermann 2019-08-09 15:44:09 +02:00
parent 4a47bbd816
commit cf9ee33928
4 changed files with 38 additions and 2 deletions

1
NEWS
View File

@ -5,6 +5,7 @@ ver 0.22 (not yet released)
* tags * tags
- new tags "Grouping" (for ID3 "TIT1") and "Work" - new tags "Grouping" (for ID3 "TIT1") and "Work"
* input * input
- curl: support "charset" parameter in URI fragment
- ffmpeg: allow partial reads - ffmpeg: allow partial reads
* archive * archive
- iso9660: support seeking - iso9660: support seeking

View File

@ -985,6 +985,22 @@ is no way for :program:`MPD` to find out whether the DAC supports
it. DSD to PCM conversion is the fallback if DSD cannot be used it. DSD to PCM conversion is the fallback if DSD cannot be used
directly. directly.
ICY-MetaData
------------
Some MP3 streams send information about the current song with a
protocol named `"ICY-MetaData"
<http://www.smackfu.com/stuff/programming/shoutcast.html>`_.
:program:`MPD` makes its ``StreamTitle`` value available as ``Title``
tag.
By default, :program:`MPD` assumes this tag is UTF-8-encoded. To tell
:program:`MPD` to assume a different character set, specify it in the
``charset`` URL fragment parameter, e.g.::
mpc add 'http://radio.example.com/stream#charset=cp1251'
Client Hacks Client Hacks
************ ************

View File

@ -20,11 +20,27 @@
#include "IcyInputStream.hxx" #include "IcyInputStream.hxx"
#include "IcyMetaDataParser.hxx" #include "IcyMetaDataParser.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "util/UriExtract.hxx"
#include "util/UriQueryParser.hxx"
#include "util/StringView.hxx"
#include <string>
IcyInputStream::IcyInputStream(InputStreamPtr _input, IcyInputStream::IcyInputStream(InputStreamPtr _input,
std::shared_ptr<IcyMetaDataParser> _parser) noexcept std::shared_ptr<IcyMetaDataParser> _parser)
:ProxyInputStream(std::move(_input)), parser(std::move(_parser)) :ProxyInputStream(std::move(_input)), parser(std::move(_parser))
{ {
#ifdef HAVE_ICU_CONVERTER
const char *fragment = uri_get_fragment(GetURI());
if (fragment != nullptr) {
const auto charset = UriFindRawQueryParameter(fragment,
"charset");
if (charset != nullptr) {
const std::string copy(charset.data, charset.size);
parser->SetCharset(copy.c_str());
}
}
#endif
} }
IcyInputStream::~IcyInputStream() noexcept = default; IcyInputStream::~IcyInputStream() noexcept = default;

View File

@ -52,9 +52,12 @@ public:
* with our input; it needs to be shared because our input * with our input; it needs to be shared because our input
* needs to feed parameters (e.g. from the "icy-metaint" * needs to feed parameters (e.g. from the "icy-metaint"
* header) into it * header) into it
*
* Throws on error (e.g. if the charset converter specified by
* the URI fragment fails to initialize).
*/ */
IcyInputStream(InputStreamPtr _input, IcyInputStream(InputStreamPtr _input,
std::shared_ptr<IcyMetaDataParser> _parser) noexcept; std::shared_ptr<IcyMetaDataParser> _parser);
virtual ~IcyInputStream() noexcept; virtual ~IcyInputStream() noexcept;
IcyInputStream(const IcyInputStream &) = delete; IcyInputStream(const IcyInputStream &) = delete;