diff --git a/control/snapcast_mpris.py b/control/snapcast_mpris.py index da96b883..22a80cf0 100755 --- a/control/snapcast_mpris.py +++ b/control/snapcast_mpris.py @@ -387,8 +387,8 @@ class SnapcastWrapper(object): logger.info(f'Stream id: {self._stream_id}') for stream in jmsg['result']['server']['streams']: if stream['id'] == self._stream_id: - if 'meta' in stream: - self.__update_metadata(stream['meta']) + if 'metadata' in stream: + self.__update_metadata(stream['metadata']) if 'properties' in stream: self.__update_properties(stream['properties']) break @@ -403,7 +403,7 @@ class SnapcastWrapper(object): logger.info(f'Stream meta changed for "{stream_id}"') if self._stream_id != stream_id: return - meta = jmsg["params"]["meta"] + meta = jmsg["params"]["metadata"] self.__update_metadata(meta) elif jmsg["method"] == "Stream.OnProperties": diff --git a/doc/json_rpc_api/stream_plugin.md b/doc/json_rpc_api/stream_plugin.md index 085ef9e2..4c48ad93 100644 --- a/doc/json_rpc_api/stream_plugin.md +++ b/doc/json_rpc_api/stream_plugin.md @@ -134,7 +134,7 @@ To control the stream state, the following commands can be sent to the Snapcast ## Notifications: ```json -{"jsonrpc": "2.0", "method": "Stream.OnMetadata", "params": {"id": "Pipe", "meta": {}}} +{"jsonrpc": "2.0", "method": "Stream.OnMetadata", "params": {"id": "Pipe", "metadata": {}}} ``` ```json diff --git a/doc/json_rpc_api/v2_0_0.md b/doc/json_rpc_api/v2_0_0.md index 8eedc1ae..46304b7c 100644 --- a/doc/json_rpc_api/v2_0_0.md +++ b/doc/json_rpc_api/v2_0_0.md @@ -383,12 +383,12 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds ### Stream.SetMeta #### Request ```json -{"id":4,"jsonrpc":"2.0","method":"Stream.SetMeta","params":{"id":"Spotify", "meta": {"album": "some album", "artist": "some artist", "track": "some track"...}}} +{"id":4,"jsonrpc":"2.0","method":"Stream.SetMeta","params":{"id":"Spotify", "metadata": {"album": "some album", "artist": "some artist", "track": "some track"...}}} ``` #### Response ```json -{"id":4,"jsonrpc":"2.0","result":{"stream_id":"Spotify"}} +{"id":4,"jsonrpc":"2.0","result":{"id":"Spotify"}} ``` ## Notifications @@ -439,7 +439,7 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds ### Stream.OnMetadata ```json -{"jsonrpc":"2.0","method":"Stream.OnMetadata","params":{"id":"stream 1", "meta": {"album": "some album", "artist": "some artist", "track": "some track"...}}} +{"jsonrpc":"2.0","method":"Stream.OnMetadata","params":{"id":"stream 1", "metadata": {"album": "some album", "artist": "some artist", "track": "some track"...}}} ``` ### Server.OnUpdate diff --git a/server/server.cpp b/server/server.cpp index 1be53ba6..08bc1925 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -49,19 +49,19 @@ void Server::onNewSession(std::shared_ptr session) } -void Server::onMetaChanged(const PcmStream* pcmStream) +void Server::onMetadataChanged(const PcmStream* pcmStream) { // clang-format off - // Notification: {"jsonrpc":"2.0","method":"Stream.OnMetadata","params":{"id":"stream 1", "meta": {"album": "some album", "artist": "some artist", "track": "some track"...}}} + // Notification: {"jsonrpc":"2.0","method":"Stream.OnMetadata","params":{"id":"stream 1", "metadata": {"album": "some album", "artist": "some artist", "track": "some track"...}}} // clang-format on - const auto meta = pcmStream->getMeta(); - LOG(DEBUG, LOG_TAG) << "Metadata changed, stream: " << pcmStream->getName() << ", meta: " << meta->toJson().dump(3) << "\n"; + const auto metadata = pcmStream->getMetadata(); + LOG(DEBUG, LOG_TAG) << "Metadata changed, stream: " << pcmStream->getName() << ", meta: " << metadata.toJson().dump(3) << "\n"; - // streamServer_->onMetaChanged(pcmStream, meta); + // streamServer_->onMetadataChanged(pcmStream, meta); // Send meta to all connected clients - json notification = jsonrpcpp::Notification("Stream.OnMetadata", jsonrpcpp::Parameter("id", pcmStream->getId(), "meta", meta->toJson())).to_json(); + json notification = jsonrpcpp::Notification("Stream.OnMetadata", jsonrpcpp::Parameter("id", pcmStream->getId(), "metadata", metadata.toJson())).to_json(); controlServer_->send(notification.dump(), nullptr); // cout << "Notification: " << notification.dump() << "\n"; } @@ -70,10 +70,10 @@ void Server::onMetaChanged(const PcmStream* pcmStream) void Server::onPropertiesChanged(const PcmStream* pcmStream) { const auto props = pcmStream->getProperties(); - LOG(DEBUG, LOG_TAG) << "Properties changed, stream: " << pcmStream->getName() << ", properties: " << props->toJson().dump(3) << "\n"; + LOG(DEBUG, LOG_TAG) << "Properties changed, stream: " << pcmStream->getName() << ", properties: " << props.toJson().dump(3) << "\n"; // Send propeties to all connected control clients - json notification = jsonrpcpp::Notification("Stream.OnProperties", jsonrpcpp::Parameter("id", pcmStream->getId(), "properties", props->toJson())).to_json(); + json notification = jsonrpcpp::Notification("Stream.OnProperties", jsonrpcpp::Parameter("id", pcmStream->getId(), "properties", props.toJson())).to_json(); controlServer_->send(notification.dump(), nullptr); } @@ -422,11 +422,11 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, const OnRespon // if (request->method().find("Stream.SetMeta") == 0) // { // clang-format off - // Request: {"id":4,"jsonrpc":"2.0","method":"Stream.SetMeta","params":{"id":"Spotify", "meta": {"album": "some album", "artist": "some artist", "track": "some track"...}}} + // Request: {"id":4,"jsonrpc":"2.0","method":"Stream.SetMeta","params":{"id":"Spotify", "metadata": {"album": "some album", "artist": "some artist", "track": "some track"...}}} // Response: {"id":4,"jsonrpc":"2.0","result":{"id":"Spotify"}} // clang-format on - // LOG(INFO, LOG_TAG) << "Stream.SetMeta id: " << request->params().get("id") << ", meta: " << request->params().get("meta") << + // LOG(INFO, LOG_TAG) << "Stream.SetMeta id: " << request->params().get("id") << ", meta: " << request->params().get("metadata") << // "\n"; // // Find stream @@ -436,7 +436,7 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, const OnRespon // throw jsonrpcpp::InternalErrorException("Stream not found", request->id()); // // Set metadata from request - // stream->setMeta(request->params().get("meta")); + // stream->setMetadata(request->params().get("metadata")); // // Setup response // result["id"] = streamId; diff --git a/server/server.hpp b/server/server.hpp index d8fcba60..0db35625 100644 --- a/server/server.hpp +++ b/server/server.hpp @@ -78,7 +78,7 @@ private: void onNewSession(std::shared_ptr session) override; /// Implementation of PcmListener - void onMetaChanged(const PcmStream* pcmStream) override; + void onMetadataChanged(const PcmStream* pcmStream) override; void onPropertiesChanged(const PcmStream* pcmStream) override; void onStateChanged(const PcmStream* pcmStream, ReaderState state) override; void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override; diff --git a/server/stream_server.cpp b/server/stream_server.cpp index 61567552..bc7e61ce 100644 --- a/server/stream_server.cpp +++ b/server/stream_server.cpp @@ -66,7 +66,7 @@ void StreamServer::addSession(std::shared_ptr session) } -// void StreamServer::onMetaChanged(const PcmStream* pcmStream, std::shared_ptr meta) +// void StreamServer::onMetadataChanged(const PcmStream* pcmStream, std::shared_ptr meta) // { // // Send meta to all connected clients diff --git a/server/stream_server.hpp b/server/stream_server.hpp index 7cb719dc..88e58de4 100644 --- a/server/stream_server.hpp +++ b/server/stream_server.hpp @@ -64,7 +64,7 @@ public: // void send(const msg::BaseMessage* message); void addSession(std::shared_ptr session); - // void onMetaChanged(const PcmStream* pcmStream, std::shared_ptr meta); + // void onMetadataChanged(const PcmStream* pcmStream, std::shared_ptr meta); void onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, std::shared_ptr chunk, double duration); session_ptr getStreamSession(const std::string& clientId) const; diff --git a/server/streamreader/airplay_stream.cpp b/server/streamreader/airplay_stream.cpp index 100faddb..9797d12b 100644 --- a/server/streamreader/airplay_stream.cpp +++ b/server/streamreader/airplay_stream.cpp @@ -155,7 +155,7 @@ void AirplayStream::push() // - cover art message (2) // // As can be seen, the order of metadata (1) and cover (2) messages is non-deterministic. - // That is why we call setMeta() on both end of message (1) and (2). + // That is why we call setMetadata() on both end of message (1) and (2). string data = entry_->data; // Do not base64 decode cover art @@ -183,7 +183,7 @@ void AirplayStream::push() // mden = metadata end, pcen == picture end if (metadata_dirty_ && entry_->type == "ssnc" && (entry_->code == "mden" || entry_->code == "pcen")) { - setMeta(metadata_); + setMetadata(metadata_); metadata_dirty_ = false; } } diff --git a/server/streamreader/librespot_stream.cpp b/server/streamreader/librespot_stream.cpp index d7d33a9a..a88f4b5e 100644 --- a/server/streamreader/librespot_stream.cpp +++ b/server/streamreader/librespot_stream.cpp @@ -161,7 +161,7 @@ void LibrespotStream::onStderrMsg(const std::string& line) Metatags meta; meta.artist = std::vector{j["ARTIST"].get()}; meta.title = j["TITLE"].get(); - setMeta(meta); + setMetadata(meta); } else if (regex_search(line, m, re_track_loaded)) { @@ -169,7 +169,7 @@ void LibrespotStream::onStderrMsg(const std::string& line) Metatags meta; meta.title = string(m[1]); meta.duration = cpt::stod(m[2]) / 1000.; - setMeta(meta); + setMetadata(meta); Properties props; // props.can_seek = true; // props.can_control = true; diff --git a/server/streamreader/meta_stream.cpp b/server/streamreader/meta_stream.cpp index d4ff7adf..a8e3bb92 100644 --- a/server/streamreader/meta_stream.cpp +++ b/server/streamreader/meta_stream.cpp @@ -84,9 +84,9 @@ void MetaStream::stop() } -void MetaStream::onMetaChanged(const PcmStream* pcmStream) +void MetaStream::onMetadataChanged(const PcmStream* pcmStream) { - LOG(DEBUG, LOG_TAG) << "onMetaChanged: " << pcmStream->getName() << "\n"; + LOG(DEBUG, LOG_TAG) << "onMetadataChanged: " << pcmStream->getName() << "\n"; std::lock_guard lock(mutex_); if (pcmStream != active_stream_.get()) return; diff --git a/server/streamreader/meta_stream.hpp b/server/streamreader/meta_stream.hpp index 869231ac..422ff604 100644 --- a/server/streamreader/meta_stream.hpp +++ b/server/streamreader/meta_stream.hpp @@ -46,7 +46,7 @@ public: protected: /// Implementation of PcmListener - void onMetaChanged(const PcmStream* pcmStream) override; + void onMetadataChanged(const PcmStream* pcmStream) override; void onPropertiesChanged(const PcmStream* pcmStream) override; void onStateChanged(const PcmStream* pcmStream, ReaderState state) override; void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override; diff --git a/server/streamreader/pcm_stream.cpp b/server/streamreader/pcm_stream.cpp index b60e5b1c..ad030f74 100644 --- a/server/streamreader/pcm_stream.cpp +++ b/server/streamreader/pcm_stream.cpp @@ -208,8 +208,6 @@ PcmStream::PcmStream(PcmListener* pcmListener, boost::asio::io_context& ioc, con if (uri_.query.find(kUriChunkMs) != uri_.query.end()) chunk_ms_ = cpt::stoul(uri_.query[kUriChunkMs]); - - // setMeta(json()); } @@ -263,39 +261,46 @@ void PcmStream::onControlRequest(const jsonrpcpp::Request& request) void PcmStream::onControlNotification(const jsonrpcpp::Notification& notification) { - LOG(INFO, LOG_TAG) << "Notification method: " << notification.method() << ", params: " << notification.params().to_json() << "\n"; - if (notification.method() == "Plugin.Stream.Player.Metadata") + try { - LOG(DEBUG, LOG_TAG) << "Received metadata notification\n"; - setMeta(notification.params().to_json()); + LOG(INFO, LOG_TAG) << "Notification method: " << notification.method() << ", params: " << notification.params().to_json() << "\n"; + if (notification.method() == "Plugin.Stream.Player.Metadata") + { + LOG(DEBUG, LOG_TAG) << "Received metadata notification\n"; + setMetadata(notification.params().to_json()); + } + else if (notification.method() == "Plugin.Stream.Player.Properties") + { + LOG(DEBUG, LOG_TAG) << "Received properties notification\n"; + setProperties(notification.params().to_json()); + } + else if (notification.method() == "Plugin.Stream.Ready") + { + LOG(DEBUG, LOG_TAG) << "Plugin is ready\n"; + ctrl_script_->send({++req_id_, "Plugin.Stream.Player.GetProperties"}, [this](const jsonrpcpp::Response& response) { + LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetProperties: " << response.to_json() << "\n"; + if (response.error().code() == 0) + setProperties(response.result()); + }); + ctrl_script_->send({++req_id_, "Plugin.Stream.Player.GetMetadata"}, [this](const jsonrpcpp::Response& response) { + LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetMetadata: " << response.to_json() << "\n"; + if (response.error().code() == 0) + setMetadata(response.result()); + }); + } + else if (notification.method() == "Plugin.Stream.Log") + { + std::string severity = notification.params().get("severity"); + std::string message = notification.params().get("message"); + LOG(INFO, LOG_TAG) << "Plugin log - severity: " << severity << ", message: " << message << "\n"; + } + else + LOG(WARNING, LOG_TAG) << "Received unknown notification method: '" << notification.method() << "'\n"; } - else if (notification.method() == "Plugin.Stream.Player.Properties") + catch (const std::exception& e) { - LOG(DEBUG, LOG_TAG) << "Received properties notification\n"; - setProperties(notification.params().to_json()); + LOG(ERROR, LOG_TAG) << "Error while receiving notification: " << e.what() << '\n'; } - else if (notification.method() == "Plugin.Stream.Ready") - { - LOG(DEBUG, LOG_TAG) << "Plugin is ready\n"; - ctrl_script_->send({++req_id_, "Plugin.Stream.Player.GetProperties"}, [this](const jsonrpcpp::Response& response) { - LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetProperties: " << response.to_json() << "\n"; - if (response.error().code() == 0) - setProperties(response.result()); - }); - ctrl_script_->send({++req_id_, "Plugin.Stream.Player.GetMetadata"}, [this](const jsonrpcpp::Response& response) { - LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetMetadata: " << response.to_json() << "\n"; - if (response.error().code() == 0) - setMeta(response.result()); - }); - } - else if (notification.method() == "Plugin.Stream.Log") - { - std::string severity = notification.params().get("severity"); - std::string message = notification.params().get("message"); - LOG(INFO, LOG_TAG) << "Plugin log - severity: " << severity << ", message: " << message << "\n"; - } - else - LOG(WARNING, LOG_TAG) << "Received unknown notification method: '" << notification.method() << "'\n"; } @@ -419,10 +424,8 @@ json PcmStream::toJson() const {"status", to_string(state_)}, }; - if (meta_) - j["meta"] = meta_->toJson(); - if (properties_) - j["properties"] = properties_->toJson(); + j["metadata"] = metadata_.toJson(); + j["properties"] = properties_.toJson(); return j; } @@ -434,13 +437,13 @@ void PcmStream::addListener(PcmListener* pcmListener) } -std::shared_ptr PcmStream::getMeta() const +const Metatags& PcmStream::getMetadata() const { - return meta_; + return metadata_; } -std::shared_ptr PcmStream::getProperties() const +const Properties& PcmStream::getProperties() const { return properties_; } @@ -448,104 +451,128 @@ std::shared_ptr PcmStream::getProperties() const void PcmStream::setProperty(const jsonrpcpp::Request& request, const CtrlScript::OnResponse& response_handler) { - auto name = request.params().get("property"); - auto value = request.params().get("value"); - LOG(INFO, LOG_TAG) << "Stream '" << getId() << "' set property: " << name << " = " << value << "\n"; - // TODO: check validity - bool valid = true; - if (name == "loopStatus") + try { - auto val = value.get(); - valid = ((val == "none") || (val == "track") || (val == "playlist")); - } - else if (name == "shuffle") - { - valid = value.is_boolean(); - } - else if (name == "volume") - { - valid = value.is_number_integer(); - } - else if (name == "rate") - { - valid = value.is_number_float(); - } - else - { - valid = false; - } + if (!request.params().has("property")) + throw SnapException("Parameter 'property' is missing"); - if (!valid) + if (!request.params().has("value")) + throw SnapException("Parameter 'value' is missing"); + + auto name = request.params().get("property"); + auto value = request.params().get("value"); + LOG(INFO, LOG_TAG) << "Stream '" << getId() << "' set property: " << name << " = " << value << "\n"; + + if (name == "loopStatus") + { + auto val = value.get(); + if ((val != "none") || (val != "track") || (val != "playlist")) + throw SnapException("Value for loopStatus must be one of 'none', 'track', 'playlist'"); + } + else if (name == "shuffle") + { + if (!value.is_boolean()) + throw SnapException("Value for shuffle must be bool"); + } + else if (name == "volume") + { + if (!value.is_number_integer()) + throw SnapException("Value for volume must be an int"); + } + else if (name == "rate") + { + if (!value.is_number_float()) + throw SnapException("Value for rate must be float"); + } + + if (!properties_.can_control) + throw SnapException("CanControl is false"); + + if (ctrl_script_) + { + jsonrpcpp::Request req(++req_id_, "Plugin.Stream.Player.SetProperty", {name, value}); + ctrl_script_->send(req, response_handler); + } + } + catch (const std::exception& e) { - auto error = jsonrpcpp::InvalidParamsException(request); + LOG(WARNING, LOG_TAG) << "Error in setProperty: " << e.what() << '\n'; + auto error = jsonrpcpp::InvalidParamsException(e.what(), request.id()); response_handler(error.to_json()); - return; - } - - if (ctrl_script_) - { - jsonrpcpp::Request req(++req_id_, "Plugin.Stream.Player.SetProperty", {name, value}); - ctrl_script_->send(req, response_handler); } } void PcmStream::control(const jsonrpcpp::Request& request, const CtrlScript::OnResponse& response_handler) { - std::string command = request.params().get("command"); - static std::set supported_commands{"Next", "Previous", "Pause", "PlayPause", "Stop", "Play", "Seek", "SetPosition"}; - if ((supported_commands.find(command) == supported_commands.end()) || - ((command == "SetPosition") && - (!request.params().has("params") || !request.params().get("params").contains("Position") || !request.params().get("params").contains("TrackId"))) || - ((command == "Seek") && (!request.params().has("params") || !request.params().get("params").contains("Offset")))) + try { - auto error = jsonrpcpp::InvalidParamsException(request); - response_handler(error.to_json()); - return; - } + if (!request.params().has("command")) + throw SnapException("Parameter 'command' is missing"); - LOG(INFO, LOG_TAG) << "Stream '" << getId() << "' received command: '" << command << "', params: '" << request.params().to_json() << "'\n"; - if (ctrl_script_) + std::string command = request.params().get("command"); + static std::set supported_commands{"Next", "Previous", "Pause", "PlayPause", "Stop", "Play", "Seek", "SetPosition"}; + if (supported_commands.find(command) == supported_commands.end()) + throw SnapException("Command not supported"); + + if (((command == "SetPosition") || (command == "Seek")) && !request.params().has("params")) + throw SnapException("Parameter 'params' is missing"); + + if ((command == "SetPosition") && (!request.params().get("params").contains("Position") || !request.params().get("params").contains("TrackId"))) + throw SnapException("SetPosition requires parameters 'Position' and 'TrackId'"); + + if ((command == "Seek") && !request.params().get("params").contains("Offset")) + throw SnapException("Seek requires parameter 'Offset'"); + + LOG(INFO, LOG_TAG) << "Stream '" << getId() << "' received command: '" << command << "', params: '" << request.params().to_json() << "'\n"; + if (ctrl_script_) + { + jsonrpcpp::Parameter params{"command", command}; + if (request.params().has("params")) + params.add("params", request.params().get("params")); + jsonrpcpp::Request req(++req_id_, "Plugin.Stream.Player.Control", params); + ctrl_script_->send(req, response_handler); + } + } + catch (const std::exception& e) { - jsonrpcpp::Parameter params{"command", command}; - if (request.params().has("params")) - params.add("params", request.params().get("params")); - jsonrpcpp::Request req(++req_id_, "Plugin.Stream.Player.Control", params); - ctrl_script_->send(req, response_handler); + LOG(WARNING, LOG_TAG) << "Error in control: " << e.what() << '\n'; + auto error = jsonrpcpp::InvalidParamsException(e.what(), request.id()); + response_handler(error.to_json()); } } -void PcmStream::setMeta(const Metatags& meta) +void PcmStream::setMetadata(const Metatags& metadata) { - if ((meta_ != nullptr) && (meta == *meta_)) + if (metadata == metadata_) { - LOG(DEBUG, LOG_TAG) << "setMeta: Meta data did not change\n"; + LOG(DEBUG, LOG_TAG) << "setMetadata: Metadata did not change\n"; return; } - meta_ = std::make_shared(meta); - LOG(INFO, LOG_TAG) << "setMeta, stream: " << getId() << ", metadata: " << meta_->toJson() << "\n"; + metadata_ = metadata; + LOG(INFO, LOG_TAG) << "setMetadata, stream: " << getId() << ", metadata: " << metadata_.toJson() << "\n"; // Trigger a stream update for (auto* listener : pcmListeners_) { if (listener != nullptr) - listener->onMetaChanged(this); + listener->onMetadataChanged(this); } } void PcmStream::setProperties(const Properties& props) { - if ((properties_ != nullptr) && (props == *properties_)) + if (props == properties_) { LOG(DEBUG, LOG_TAG) << "setProperties: Properties did not change\n"; return; } - properties_ = std::make_shared(props); - LOG(INFO, LOG_TAG) << "setProperties, stream: " << getId() << ", properties: " << props.toJson() << "\n"; + properties_ = props; + LOG(INFO, LOG_TAG) << "setProperties, stream: " << getId() << ", properties: " << properties_.toJson() << "\n"; // Trigger a stream update for (auto* listener : pcmListeners_) diff --git a/server/streamreader/pcm_stream.hpp b/server/streamreader/pcm_stream.hpp index 2b388c08..d23e1da5 100644 --- a/server/streamreader/pcm_stream.hpp +++ b/server/streamreader/pcm_stream.hpp @@ -104,7 +104,7 @@ static constexpr auto kControlScript = "controlscript"; class PcmListener { public: - virtual void onMetaChanged(const PcmStream* pcmStream) = 0; + virtual void onMetadataChanged(const PcmStream* pcmStream) = 0; virtual void onPropertiesChanged(const PcmStream* pcmStream) = 0; virtual void onStateChanged(const PcmStream* pcmStream, ReaderState state) = 0; virtual void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) = 0; @@ -177,8 +177,8 @@ public: virtual const SampleFormat& getSampleFormat() const; virtual std::string getCodec() const; - std::shared_ptr getMeta() const; - std::shared_ptr getProperties() const; + const Metatags& getMetadata() const; + const Properties& getProperties() const; virtual void setProperty(const jsonrpcpp::Request& request, const CtrlScript::OnResponse& response_handler); virtual void control(const jsonrpcpp::Request& request, const CtrlScript::OnResponse& response_handler); @@ -200,7 +200,7 @@ protected: void resync(const std::chrono::nanoseconds& duration); void chunkEncoded(const encoder::Encoder& encoder, std::shared_ptr chunk, double duration); - void setMeta(const Metatags& meta); + void setMetadata(const Metatags& metadata); void setProperties(const Properties& props); std::chrono::time_point tvEncodedChunk_; @@ -211,8 +211,8 @@ protected: std::unique_ptr encoder_; std::string name_; ReaderState state_; - std::shared_ptr meta_; - std::shared_ptr properties_; + Metatags metadata_; + Properties properties_; boost::asio::io_context& ioc_; ServerSettings server_settings_; std::unique_ptr ctrl_script_;