mirror of
https://github.com/badaix/snapcast.git
synced 2025-06-17 10:11:42 +02:00
Remove MetadataAdapter
This commit is contained in:
parent
afa8c118f6
commit
f8e4e60f2f
7 changed files with 38 additions and 123 deletions
|
@ -44,7 +44,7 @@ class Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// c'tor
|
/// c'tor
|
||||||
Controller(boost::asio::io_context& io_context, const ClientSettings& settings); //, std::unique_ptr<MetadataAdapter> meta);
|
Controller(boost::asio::io_context& io_context, const ClientSettings& settings);
|
||||||
/// Start thw work
|
/// Start thw work
|
||||||
void start();
|
void start();
|
||||||
// void stop();
|
// void stop();
|
||||||
|
@ -74,7 +74,6 @@ private:
|
||||||
std::shared_ptr<Stream> stream_;
|
std::shared_ptr<Stream> stream_;
|
||||||
std::unique_ptr<decoder::Decoder> decoder_;
|
std::unique_ptr<decoder::Decoder> decoder_;
|
||||||
std::unique_ptr<player::Player> player_;
|
std::unique_ptr<player::Player> player_;
|
||||||
// std::unique_ptr<MetadataAdapter> meta_;
|
|
||||||
std::unique_ptr<msg::ServerSettings> serverSettings_;
|
std::unique_ptr<msg::ServerSettings> serverSettings_;
|
||||||
std::unique_ptr<msg::CodecHeader> headerChunk_;
|
std::unique_ptr<msg::CodecHeader> headerChunk_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
/***
|
|
||||||
This file is part of snapcast
|
|
||||||
Copyright (C) 2014-2024 Johannes Pohl
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// local headers
|
|
||||||
#include "common/json.hpp"
|
|
||||||
|
|
||||||
// standard headers
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
// Prefix used in output
|
|
||||||
#define METADATA std::string("metadata")
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implement a generic metadata output handler
|
|
||||||
*/
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Base class, prints to stdout
|
|
||||||
*/
|
|
||||||
class MetadataAdapter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MetadataAdapter()
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MetadataAdapter() = default;
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
msg_ = json{};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string serialize()
|
|
||||||
{
|
|
||||||
return METADATA + ":" + msg_.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
void tag(const std::string& name, const std::string& value)
|
|
||||||
{
|
|
||||||
msg_[name] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string operator[](const std::string& key)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return msg_[key];
|
|
||||||
}
|
|
||||||
catch (std::domain_error&)
|
|
||||||
{
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int push()
|
|
||||||
{
|
|
||||||
std::cout << serialize() << "\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int push(const json& jtag)
|
|
||||||
{
|
|
||||||
msg_ = jtag;
|
|
||||||
return push();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
json msg_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Send metadata to stderr as json
|
|
||||||
*/
|
|
||||||
class MetaStderrAdapter : public MetadataAdapter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using MetadataAdapter::push;
|
|
||||||
|
|
||||||
int push() override
|
|
||||||
{
|
|
||||||
std::cerr << serialize() << "\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,6 +1,6 @@
|
||||||
/***
|
/***
|
||||||
This file is part of snapcast
|
This file is part of snapcast
|
||||||
Copyright (C) 2014-2024 Johannes Pohl
|
Copyright (C) 2014-2025 Johannes Pohl
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
|
/// Queue with "wait for new element" functionality
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Queue
|
class Queue
|
||||||
{
|
{
|
||||||
|
@ -32,8 +33,7 @@ public:
|
||||||
T pop()
|
T pop()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> mlock(mutex_);
|
std::unique_lock<std::mutex> mlock(mutex_);
|
||||||
while (queue_.empty())
|
cond_.wait(mlock, [this]() { return queue_.empty(); });
|
||||||
cond_.wait(mlock);
|
|
||||||
|
|
||||||
// std::lock_guard<std::mutex> lock(mutex_);
|
// std::lock_guard<std::mutex> lock(mutex_);
|
||||||
auto val = queue_.front();
|
auto val = queue_.front();
|
||||||
|
@ -54,7 +54,7 @@ public:
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> mlock(mutex_);
|
std::unique_lock<std::mutex> mlock(mutex_);
|
||||||
abort_ = false;
|
abort_ = false;
|
||||||
if (!cond_.wait_for(mlock, timeout, [this] { return (!queue_.empty() || abort_); }))
|
if (!cond_.wait_for(mlock, timeout, [this]() { return (!queue_.empty() || abort_); }))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !queue_.empty() && !abort_;
|
return !queue_.empty() && !abort_;
|
||||||
|
@ -66,7 +66,7 @@ public:
|
||||||
abort_ = false;
|
abort_ = false;
|
||||||
if (timeout.count() > 0)
|
if (timeout.count() > 0)
|
||||||
{
|
{
|
||||||
if (!cond_.wait_for(mlock, timeout, [this] { return (!queue_.empty() || abort_); }))
|
if (!cond_.wait_for(mlock, timeout, [this]() { return (!queue_.empty() || abort_); }))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/***
|
/***
|
||||||
This file is part of snapcast
|
This file is part of snapcast
|
||||||
Copyright (C) 2014-2024 Johannes Pohl
|
Copyright (C) 2014-2025 Johannes Pohl
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -32,20 +32,24 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
/// Resampler
|
||||||
class Resampler
|
class Resampler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// c'tor to resample from @p in_format to @p out_format
|
||||||
Resampler(const SampleFormat& in_format, const SampleFormat& out_format);
|
Resampler(const SampleFormat& in_format, const SampleFormat& out_format);
|
||||||
|
/// d'tor
|
||||||
virtual ~Resampler();
|
virtual ~Resampler();
|
||||||
|
|
||||||
// std::shared_ptr<msg::PcmChunk> resample(std::shared_ptr<msg::PcmChunk> chunk, chronos::usec duration);
|
/// @return resampled @p chunk
|
||||||
std::shared_ptr<msg::PcmChunk> resample(std::shared_ptr<msg::PcmChunk> chunk);
|
std::shared_ptr<msg::PcmChunk> resample(std::shared_ptr<msg::PcmChunk> chunk);
|
||||||
|
/// @return resampled @p chunk
|
||||||
std::shared_ptr<msg::PcmChunk> resample(const msg::PcmChunk& chunk);
|
std::shared_ptr<msg::PcmChunk> resample(const msg::PcmChunk& chunk);
|
||||||
|
/// @return if resampling is needed (in_format != out_format)
|
||||||
bool resamplingNeeded() const;
|
bool resamplingNeeded() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<char> resample_buffer_;
|
std::vector<char> resample_buffer_;
|
||||||
// std::unique_ptr<msg::PcmChunk> resampled_chunk_;
|
|
||||||
SampleFormat in_format_;
|
SampleFormat in_format_;
|
||||||
SampleFormat out_format_;
|
SampleFormat out_format_;
|
||||||
#ifdef HAS_SOXR
|
#ifdef HAS_SOXR
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/***
|
/***
|
||||||
This file is part of snapcast
|
This file is part of snapcast
|
||||||
Copyright (C) 2014-2024 Johannes Pohl
|
Copyright (C) 2014-2025 Johannes Pohl
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,27 +29,35 @@
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
/// Meta data of a single track
|
||||||
class Metadata
|
class Metadata
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// Cover art
|
||||||
struct ArtData
|
struct ArtData
|
||||||
{
|
{
|
||||||
|
/// base64 encoded art data
|
||||||
std::string data;
|
std::string data;
|
||||||
|
/// type of the data (e.g. jpg)
|
||||||
std::string extension;
|
std::string extension;
|
||||||
|
|
||||||
|
/// compare for equality
|
||||||
bool operator==(const ArtData& other) const
|
bool operator==(const ArtData& other) const
|
||||||
{
|
{
|
||||||
return ((other.data == data) && (other.extension == extension));
|
return ((other.data == data) && (other.extension == extension));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// compare for un-equality
|
||||||
bool operator!=(const ArtData& other) const
|
bool operator!=(const ArtData& other) const
|
||||||
{
|
{
|
||||||
return !(other == *this);
|
return !(other == *this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// c'tor
|
||||||
Metadata() = default;
|
Metadata() = default;
|
||||||
Metadata(const json& j);
|
/// c'tor taking json serialized meta data
|
||||||
|
explicit Metadata(const json& j);
|
||||||
|
|
||||||
/// https://www.musicpd.org/doc/html/protocol.html#tags
|
/// https://www.musicpd.org/doc/html/protocol.html#tags
|
||||||
/// the duration of the song
|
/// the duration of the song
|
||||||
|
@ -142,7 +150,10 @@ public:
|
||||||
/// Spotify track id
|
/// Spotify track id
|
||||||
std::optional<std::string> spotify_track_id;
|
std::optional<std::string> spotify_track_id;
|
||||||
|
|
||||||
|
/// serialize to json
|
||||||
json toJson() const;
|
json toJson() const;
|
||||||
|
/// deserialize from json
|
||||||
void fromJson(const json& j);
|
void fromJson(const json& j);
|
||||||
|
/// compare for equality
|
||||||
bool operator==(const Metadata& other) const;
|
bool operator==(const Metadata& other) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "control_error.hpp"
|
#include "control_error.hpp"
|
||||||
#include "encoder/encoder_factory.hpp"
|
#include "encoder/encoder_factory.hpp"
|
||||||
#include "image_cache.hpp"
|
#include "image_cache.hpp"
|
||||||
|
#include "streamreader/properties.hpp"
|
||||||
|
|
||||||
// 3rd party headers
|
// 3rd party headers
|
||||||
#include <boost/asio/ip/host_name.hpp>
|
#include <boost/asio/ip/host_name.hpp>
|
||||||
|
@ -152,7 +153,7 @@ void PcmStream::pollProperties()
|
||||||
{
|
{
|
||||||
LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetProperties: " << response.to_json() << "\n";
|
LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetProperties: " << response.to_json() << "\n";
|
||||||
if (response.error().code() == 0)
|
if (response.error().code() == 0)
|
||||||
setProperties(response.result());
|
setProperties(Properties(response.result()));
|
||||||
});
|
});
|
||||||
pollProperties();
|
pollProperties();
|
||||||
}
|
}
|
||||||
|
@ -168,7 +169,7 @@ void PcmStream::onControlNotification(const jsonrpcpp::Notification& notificatio
|
||||||
if (notification.method() == "Plugin.Stream.Player.Properties")
|
if (notification.method() == "Plugin.Stream.Player.Properties")
|
||||||
{
|
{
|
||||||
LOG(DEBUG, LOG_TAG) << "Received properties notification\n";
|
LOG(DEBUG, LOG_TAG) << "Received properties notification\n";
|
||||||
setProperties(notification.params().to_json());
|
setProperties(Properties(notification.params().to_json()));
|
||||||
}
|
}
|
||||||
else if (notification.method() == "Plugin.Stream.Ready")
|
else if (notification.method() == "Plugin.Stream.Ready")
|
||||||
{
|
{
|
||||||
|
@ -177,7 +178,7 @@ void PcmStream::onControlNotification(const jsonrpcpp::Notification& notificatio
|
||||||
{
|
{
|
||||||
LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetProperties: " << response.to_json() << "\n";
|
LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetProperties: " << response.to_json() << "\n";
|
||||||
if (response.error().code() == 0)
|
if (response.error().code() == 0)
|
||||||
setProperties(response.result());
|
setProperties(Properties(response.result()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Add capabilities or settings?
|
// TODO: Add capabilities or settings?
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/***
|
/***
|
||||||
This file is part of snapcast
|
This file is part of snapcast
|
||||||
Copyright (C) 2014-2024 Johannes Pohl
|
Copyright (C) 2014-2025 Johannes Pohl
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -143,12 +143,14 @@ static std::istream& operator>>(std::istream& is, LoopStatus& loop_status)
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Properties of the stream (volume, shuffle, mute, position, can_play, can_pause, ...)
|
||||||
class Properties
|
class Properties
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// c'tor
|
||||||
Properties() = default;
|
Properties() = default;
|
||||||
Properties(const json& j);
|
/// c'tor taking json serialized properties
|
||||||
|
explicit Properties(const json& j);
|
||||||
|
|
||||||
/// Meta data
|
/// Meta data
|
||||||
std::optional<Metadata> metadata;
|
std::optional<Metadata> metadata;
|
||||||
|
@ -185,7 +187,10 @@ public:
|
||||||
/// Whether the media player may be controlled over this interface
|
/// Whether the media player may be controlled over this interface
|
||||||
bool can_control = false;
|
bool can_control = false;
|
||||||
|
|
||||||
|
/// serialize to json
|
||||||
json toJson() const;
|
json toJson() const;
|
||||||
|
/// deserialize from json
|
||||||
void fromJson(const json& j);
|
void fromJson(const json& j);
|
||||||
|
/// compare for equality
|
||||||
bool operator==(const Properties& other) const;
|
bool operator==(const Properties& other) const;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue