song/DetachedSong: copy the AudioFormat from LightSong
Enables the "Format" row in "playlistinfo" responses. https://github.com/MusicPlayerDaemon/MPD/issues/1094
This commit is contained in:
parent
81d0c04ed4
commit
c729f16dcd
1
NEWS
1
NEWS
|
@ -1,6 +1,7 @@
|
|||
ver 0.23 (not yet released)
|
||||
* protocol
|
||||
- new command "getvol"
|
||||
- show the audio format in "playlistinfo"
|
||||
* output
|
||||
- snapcast: new plugin
|
||||
|
||||
|
|
|
@ -111,6 +111,9 @@ song_print_info(Response &r, const DetachedSong &song, bool base) noexcept
|
|||
if (!IsNegative(song.GetLastModified()))
|
||||
time_print(r, "Last-Modified", song.GetLastModified());
|
||||
|
||||
if (const auto &f = song.GetAudioFormat(); f.IsDefined())
|
||||
r.Format("Format: %s\n", ToString(f).c_str());
|
||||
|
||||
tag_print_values(r, song.GetTag());
|
||||
|
||||
const auto duration = song.GetDuration();
|
||||
|
|
|
@ -86,8 +86,7 @@ song_save(BufferedOutputStream &os, const DetachedSong &song)
|
|||
|
||||
DetachedSong
|
||||
song_load(TextFile &file, const char *uri,
|
||||
std::string *target_r,
|
||||
AudioFormat *audio_format_r)
|
||||
std::string *target_r)
|
||||
{
|
||||
DetachedSong song(uri);
|
||||
|
||||
|
@ -113,14 +112,12 @@ song_load(TextFile &file, const char *uri,
|
|||
if (target_r != nullptr)
|
||||
*target_r = value;
|
||||
} else if (StringIsEqual(line, "Format")) {
|
||||
if (audio_format_r != nullptr) {
|
||||
try {
|
||||
*audio_format_r =
|
||||
ParseAudioFormat(value, false);
|
||||
song.SetAudioFormat(ParseAudioFormat(value,
|
||||
false));
|
||||
} catch (...) {
|
||||
/* ignore parser errors */
|
||||
}
|
||||
}
|
||||
} else if (StringIsEqual(line, "Playlist")) {
|
||||
tag.SetHasPlaylist(StringIsEqual(value, "yes"));
|
||||
} else if (StringIsEqual(line, SONG_MTIME)) {
|
||||
|
|
|
@ -44,7 +44,6 @@ song_save(BufferedOutputStream &os, const DetachedSong &song);
|
|||
*/
|
||||
DetachedSong
|
||||
song_load(TextFile &file, const char *uri,
|
||||
std::string *target_r=nullptr,
|
||||
AudioFormat *audio_format_r=nullptr);
|
||||
std::string *target_r=nullptr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -153,9 +153,10 @@ DetachedSong::LoadFile(Path path)
|
|||
return false;
|
||||
|
||||
TagBuilder tag_builder;
|
||||
auto new_audio_format = AudioFormat::Undefined();
|
||||
|
||||
try {
|
||||
if (!ScanFileTagsWithGeneric(path, tag_builder))
|
||||
if (!ScanFileTagsWithGeneric(path, tag_builder, &new_audio_format))
|
||||
return false;
|
||||
} catch (...) {
|
||||
// TODO: log or propagate I/O errors?
|
||||
|
@ -163,6 +164,7 @@ DetachedSong::LoadFile(Path path)
|
|||
}
|
||||
|
||||
mtime = fi.GetModificationTime();
|
||||
audio_format = new_audio_format;
|
||||
tag_builder.Commit(tag);
|
||||
return true;
|
||||
}
|
||||
|
@ -177,9 +179,11 @@ DetachedSong::Update()
|
|||
return LoadFile(path_fs);
|
||||
} else if (IsRemote()) {
|
||||
TagBuilder tag_builder;
|
||||
auto new_audio_format = AudioFormat::Undefined();
|
||||
|
||||
try {
|
||||
if (!tag_stream_scan(uri.c_str(), tag_builder))
|
||||
if (!tag_stream_scan(uri.c_str(), tag_builder,
|
||||
&new_audio_format))
|
||||
return false;
|
||||
} catch (...) {
|
||||
// TODO: log or propagate I/O errors?
|
||||
|
@ -187,6 +191,7 @@ DetachedSong::Update()
|
|||
}
|
||||
|
||||
mtime = std::chrono::system_clock::time_point::min();
|
||||
audio_format = new_audio_format;
|
||||
tag_builder.Commit(tag);
|
||||
return true;
|
||||
} else
|
||||
|
|
|
@ -168,15 +168,12 @@ directory_load(TextFile &file, Directory &directory)
|
|||
throw FormatRuntimeError("Duplicate song '%s'", name);
|
||||
|
||||
std::string target;
|
||||
auto audio_format = AudioFormat::Undefined();
|
||||
auto detached_song = song_load(file, name,
|
||||
&target,
|
||||
&audio_format);
|
||||
&target);
|
||||
|
||||
auto song = std::make_unique<Song>(std::move(detached_song),
|
||||
directory);
|
||||
song->target = std::move(target);
|
||||
song->audio_format = audio_format;
|
||||
|
||||
directory.AddSong(std::move(song));
|
||||
} else if ((p = StringAfterPrefix(line, PLAYLIST_META_BEGIN))) {
|
||||
|
|
|
@ -34,6 +34,7 @@ Song::Song(DetachedSong &&other, Directory &_parent) noexcept
|
|||
mtime(other.GetLastModified()),
|
||||
start_time(other.GetStartTime()),
|
||||
end_time(other.GetEndTime()),
|
||||
audio_format(other.GetAudioFormat()),
|
||||
filename(other.GetURI())
|
||||
{
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@ merge_song_metadata(DetachedSong &add, const DetachedSong &base) noexcept
|
|||
if (add.GetEndTime().IsZero()) {
|
||||
add.SetEndTime(base.GetEndTime());
|
||||
}
|
||||
|
||||
if (!add.GetAudioFormat().IsDefined())
|
||||
add.SetAudioFormat(base.GetAudioFormat());
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -28,7 +28,8 @@ DetachedSong::DetachedSong(const LightSong &other) noexcept
|
|||
tag(other.tag),
|
||||
mtime(other.mtime),
|
||||
start_time(other.start_time),
|
||||
end_time(other.end_time) {}
|
||||
end_time(other.end_time),
|
||||
audio_format(other.audio_format) {}
|
||||
|
||||
DetachedSong::operator LightSong() const noexcept
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define MPD_DETACHED_SONG_HXX
|
||||
|
||||
#include "tag/Tag.hxx"
|
||||
#include "pcm/AudioFormat.hxx"
|
||||
#include "Chrono.hxx"
|
||||
#include "util/Compiler.h"
|
||||
|
||||
|
@ -79,6 +80,12 @@ class DetachedSong {
|
|||
*/
|
||||
SongTime end_time = SongTime::zero();
|
||||
|
||||
/**
|
||||
* The audio format of the song, if given by the decoder
|
||||
* plugin. May be undefined if unknown.
|
||||
*/
|
||||
AudioFormat audio_format = AudioFormat::Undefined();
|
||||
|
||||
public:
|
||||
explicit DetachedSong(const char *_uri) noexcept
|
||||
:uri(_uri) {}
|
||||
|
@ -231,6 +238,14 @@ public:
|
|||
gcc_pure
|
||||
SignedSongTime GetDuration() const noexcept;
|
||||
|
||||
const AudioFormat &GetAudioFormat() const noexcept {
|
||||
return audio_format;
|
||||
}
|
||||
|
||||
void SetAudioFormat(const AudioFormat &src) noexcept {
|
||||
audio_format = src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the #tag and #mtime.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue