Comment out stream_tags

This commit is contained in:
badaix 2021-06-04 10:32:33 +02:00
parent 9bbba976f9
commit 53e27e0d8b
13 changed files with 173 additions and 106 deletions

View file

@ -71,9 +71,9 @@ using namespace player;
static constexpr auto LOG_TAG = "Controller";
static constexpr auto TIME_SYNC_INTERVAL = 1s;
Controller::Controller(boost::asio::io_context& io_context, const ClientSettings& settings, std::unique_ptr<MetadataAdapter> meta)
: io_context_(io_context), timer_(io_context), settings_(settings), stream_(nullptr), decoder_(nullptr), player_(nullptr), meta_(std::move(meta)),
serverSettings_(nullptr)
Controller::Controller(boost::asio::io_context& io_context, const ClientSettings& settings) //, std::unique_ptr<MetadataAdapter> meta)
: io_context_(io_context), timer_(io_context), settings_(settings), stream_(nullptr), decoder_(nullptr), player_(nullptr),
serverSettings_(nullptr) // meta_(std::move(meta)),
{
}
@ -241,14 +241,14 @@ void Controller::getNextMessage()
player_->setVolume(serverSettings_->getVolume() / 100., serverSettings_->isMuted());
// }
}
else if (response->type == message_type::kStreamTags)
{
if (meta_)
{
auto stream_tags = msg::message_cast<msg::StreamTags>(std::move(response));
meta_->push(stream_tags->msg);
}
}
// else if (response->type == message_type::kStreamTags)
// {
// if (meta_)
// {
// auto stream_tags = msg::message_cast<msg::StreamTags>(std::move(response));
// meta_->push(stream_tags->msg);
// }
// }
else
{
LOG(WARNING, LOG_TAG) << "Unexpected message received, type: " << response->type << "\n";

View file

@ -24,8 +24,8 @@
#include "decoder/decoder.hpp"
#include "message/message.hpp"
#include "message/server_settings.hpp"
#include "message/stream_tags.hpp"
#include "metadata.hpp"
// #include "message/stream_tags.hpp"
// #include "metadata.hpp"
#include "player/player.hpp"
#include "stream.hpp"
#include <atomic>
@ -43,7 +43,7 @@ using namespace std::chrono_literals;
class Controller
{
public:
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); //, std::unique_ptr<MetadataAdapter> meta);
void start();
// void stop();
static std::vector<std::string> getSupportedPlayerNames();
@ -63,13 +63,12 @@ private:
boost::asio::io_context& io_context_;
boost::asio::steady_timer timer_;
ClientSettings settings_;
std::string meta_callback_;
SampleFormat sampleFormat_;
std::unique_ptr<ClientConnection> clientConnection_;
std::shared_ptr<Stream> stream_;
std::unique_ptr<decoder::Decoder> decoder_;
std::unique_ptr<player::Player> player_;
std::unique_ptr<MetadataAdapter> meta_;
// std::unique_ptr<MetadataAdapter> meta_;
std::unique_ptr<msg::ServerSettings> serverSettings_;
std::unique_ptr<msg::CodecHeader> headerChunk_;
};

View file

@ -45,7 +45,7 @@
#include "common/str_compat.hpp"
#include "common/utils.hpp"
#include "common/version.hpp"
#include "metadata.hpp"
// #include "metadata.hpp"
using namespace std;
@ -429,8 +429,8 @@ int main(int argc, char** argv)
LOG(INFO, LOG_TAG) << "Version " << version::code << (!version::rev().empty() ? (", revision " + version::rev(8)) : ("")) << "\n";
// Setup metadata handling
auto meta(metaStderr ? std::make_unique<MetaStderrAdapter>() : std::make_unique<MetadataAdapter>());
auto controller = make_shared<Controller>(io_context, settings, std::move(meta));
// auto meta(metaStderr ? std::make_unique<MetaStderrAdapter>() : std::make_unique<MetadataAdapter>());
auto controller = make_shared<Controller>(io_context, settings); //, std::move(meta));
controller->start();
int num_threads = 0;

View file

@ -24,7 +24,7 @@
#include "hello.hpp"
#include "pcm_chunk.hpp"
#include "server_settings.hpp"
#include "stream_tags.hpp"
// #include "stream_tags.hpp"
#include "time.hpp"
#include "common/str_compat.hpp"
@ -74,8 +74,8 @@ static std::unique_ptr<BaseMessage> createMessage(const BaseMessage& base_messag
return createMessage<Hello>(base_message, buffer);
case message_type::kServerSettings:
return createMessage<ServerSettings>(base_message, buffer);
case message_type::kStreamTags:
return createMessage<StreamTags>(base_message, buffer);
// case message_type::kStreamTags:
// return createMessage<StreamTags>(base_message, buffer);
case message_type::kTime:
return createMessage<Time>(base_message, buffer);
case message_type::kWireChunk:

View file

@ -1,6 +1,6 @@
/***
This file is part of snapcast
Copyright (C) 2014-2020 Johannes Pohl
Copyright (C) 2014-2021 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
@ -16,9 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef STREAMTAGS_H
#define STREAMTAGS_H
#ifndef STREAMTAGS_HPP
#define STREAMTAGS_HPP
// #include "common/metatags.hpp"
#include "json_message.hpp"
/*
@ -65,6 +66,12 @@ public:
{
}
// StreamTags(const Metatags& tags) : JsonMessage(message_type::kStreamTags)
// {
// if (tags.album.has_value())
// msg['album'] = *tags.album;
// }
~StreamTags() override = default;
};
} // namespace msg

28
control/test.cpp Normal file
View file

@ -0,0 +1,28 @@
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/embed.h> // everything needed for embedding
namespace py = pybind11;
void say_hello()
{
// Try to import scipy
py::object scipy = py::module::import("/home/johannes/Develop/snapcast/control/meta_mpd.py");
// Equivalent to "from decimal import Decimal"
py::object Decimal = py::module::import("decimal").attr("Decimal");
// Construct a Python object of class Decimal
py::object pi = Decimal("3.14159");
py::print(py::str(pi));
py::print(pi);
py::print("Hello, World!"); // use the Python API
}
int main(int argc, char** argv)
{
py::scoped_interpreter guard{}; // start the interpreter and keep it alive
say_hello();
}

View file

@ -21,7 +21,7 @@
#include "config.hpp"
#include "message/client_info.hpp"
#include "message/hello.hpp"
#include "message/stream_tags.hpp"
// #include "message/stream_tags.hpp"
#include "message/time.hpp"
#include "stream_session_tcp.hpp"
#include <iostream>
@ -56,13 +56,12 @@ void Server::onMetaChanged(const PcmStream* pcmStream)
// clang-format on
const auto meta = pcmStream->getMeta();
LOG(DEBUG, LOG_TAG) << "metadata = " << meta->msg.dump(3) << "\n";
LOG(DEBUG, LOG_TAG) << "onMetaChanged (" << pcmStream->getName() << ")\n";
LOG(DEBUG, LOG_TAG) << "Metadata changed, stream: " << pcmStream->getName() << ", meta: " << meta->toJson().dump(3) << "\n";
streamServer_->onMetaChanged(pcmStream, meta);
// streamServer_->onMetaChanged(pcmStream, meta);
// Send meta to all connected clients
json notification = jsonrpcpp::Notification("Stream.OnMetadata", jsonrpcpp::Parameter("id", pcmStream->getId(), "meta", meta->msg)).to_json();
json notification = jsonrpcpp::Notification("Stream.OnMetadata", jsonrpcpp::Parameter("id", pcmStream->getId(), "meta", meta->toJson())).to_json();
controlServer_->send(notification.dump(), nullptr);
// cout << "Notification: " << notification.dump() << "\n";
}
@ -70,8 +69,8 @@ void Server::onMetaChanged(const PcmStream* pcmStream)
void Server::onPropertiesChanged(const PcmStream* pcmStream)
{
LOG(DEBUG, LOG_TAG) << "onPropertiesChanged (" << pcmStream->getName() << ")\n";
const auto props = pcmStream->getProperties();
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();
@ -299,7 +298,7 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, jsonrpcpp::ent
session_ptr session = streamServer_->getStreamSession(client->id);
if (session && (session->pcmStream() != stream))
{
session->send(stream->getMeta());
// session->send(stream->getMeta());
session->send(stream->getHeader());
session->setPcmStream(stream);
}
@ -354,7 +353,7 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, jsonrpcpp::ent
session_ptr session = streamServer_->getStreamSession(client->id);
if (session && stream && (session->pcmStream() != stream))
{
session->send(stream->getMeta());
// session->send(stream->getMeta());
session->send(stream->getHeader());
session->setPcmStream(stream);
}
@ -417,28 +416,29 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, jsonrpcpp::ent
}
else if (request->method().find("Stream.") == 0)
{
if (request->method().find("Stream.SetMeta") == 0)
{
// clang-format off
// 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"...}}}
// Response: {"id":4,"jsonrpc":"2.0","result":{"id":"Spotify"}}
// clang-format on
// clang-format on
LOG(INFO, LOG_TAG) << "Stream.SetMeta id: " << request->params().get<std::string>("id") << ", meta: " << request->params().get("meta") << "\n";
// LOG(INFO, LOG_TAG) << "Stream.SetMeta id: " << request->params().get<std::string>("id") << ", meta: " << request->params().get("meta") <<
// "\n";
// Find stream
string streamId = request->params().get<std::string>("id");
PcmStreamPtr stream = streamManager_->getStream(streamId);
if (stream == nullptr)
throw jsonrpcpp::InternalErrorException("Stream not found", request->id());
// // Find stream
// string streamId = request->params().get<std::string>("id");
// PcmStreamPtr stream = streamManager_->getStream(streamId);
// if (stream == nullptr)
// throw jsonrpcpp::InternalErrorException("Stream not found", request->id());
// Set metadata from request
stream->setMeta(request->params().get("meta"));
// // Set metadata from request
// stream->setMeta(request->params().get("meta"));
// Setup response
result["id"] = streamId;
}
else if (request->method().find("Stream.Control") == 0)
// // Setup response
// result["id"] = streamId;
// }
if (request->method().find("Stream.Control") == 0)
{
// clang-format off
// Request: {"id":4,"jsonrpc":"2.0","method":"Stream.Control","params":{"id":"Spotify", "command": "next", params: {}}}
@ -700,8 +700,8 @@ void Server::onMessageReceived(StreamSession* streamSession, const msg::BaseMess
saveConfig();
LOG(DEBUG, LOG_TAG) << "Sending meta data to " << streamSession->clientId << "\n";
streamSession->send(stream->getMeta());
// LOG(DEBUG, LOG_TAG) << "Sending meta data to " << streamSession->clientId << "\n";
// streamSession->send(stream->getMeta());
streamSession->setPcmStream(stream);
auto headerChunk = stream->getHeader();
LOG(DEBUG, LOG_TAG) << "Sending codec header to " << streamSession->clientId << "\n";

View file

@ -21,7 +21,7 @@
#include "config.hpp"
#include "message/client_info.hpp"
#include "message/hello.hpp"
#include "message/stream_tags.hpp"
// #include "message/stream_tags.hpp"
#include "message/time.hpp"
#include "stream_session_tcp.hpp"
#include <iostream>
@ -66,20 +66,20 @@ void StreamServer::addSession(const std::shared_ptr<StreamSession>& session)
}
void StreamServer::onMetaChanged(const PcmStream* pcmStream, std::shared_ptr<msg::StreamTags> meta)
{
// Send meta to all connected clients
// void StreamServer::onMetaChanged(const PcmStream* pcmStream, std::shared_ptr<msg::StreamTags> meta)
// {
// // Send meta to all connected clients
std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_);
for (const auto& s : sessions_)
{
if (auto session = s.lock())
{
if (session->pcmStream().get() == pcmStream)
session->send(meta);
}
}
}
// std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_);
// for (const auto& s : sessions_)
// {
// if (auto session = s.lock())
// {
// if (session->pcmStream().get() == pcmStream)
// session->send(meta);
// }
// }
// }
void StreamServer::onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, std::shared_ptr<msg::PcmChunk> chunk, double /*duration*/)

View file

@ -64,7 +64,7 @@ public:
// void send(const msg::BaseMessage* message);
void addSession(const std::shared_ptr<StreamSession>& session);
void onMetaChanged(const PcmStream* pcmStream, std::shared_ptr<msg::StreamTags> meta);
// void onMetaChanged(const PcmStream* pcmStream, std::shared_ptr<msg::StreamTags> meta);
void onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, std::shared_ptr<msg::PcmChunk> chunk, double duration);
session_ptr getStreamSession(const std::string& clientId) const;

View file

@ -107,7 +107,6 @@ void LibrespotStream::initExeAndPath(const std::string& filename)
void LibrespotStream::onStderrMsg(const std::string& line)
{
static bool libreelec_patched = false;
// Watch stderr for 'Loading track' messages and set the stream metadata
// For more than track name check: https://github.com/plietar/librespot/issues/154
@ -153,31 +152,34 @@ void LibrespotStream::onStderrMsg(const std::string& line)
// Librespot patch:
// info!("metadata:{{\"ARTIST\":\"{}\",\"TITLE\":\"{}\"}}", artist.name, track.name);
// non patched:
// [2021-06-04T07:20:47Z INFO librespot_playback::player] <Tunnel> (310573 ms) loaded
// info!("Track \"{}\" loaded", track.name);
// If we detect a patched libreelec we don't want to bother with this anymoer
// to avoid duplicate metadata pushes
// std::cerr << line << "\n";
smatch m;
if (!libreelec_patched)
{
static regex re_nonpatched("Track \"(.*)\" loaded");
if (regex_search(line, m, re_nonpatched))
{
LOG(INFO, LOG_TAG) << "metadata: <" << m[1] << ">\n";
json jtag = {{"TITLE", string(m[1])}};
setMeta(jtag);
}
}
// Parse the patched version
static regex re_patched("metadata:(.*)");
static regex re_track_loaded(R"( <(.*)> \((.*) ms\) loaded)");
// Parse the patched version
if (regex_search(line, m, re_patched))
{
// Patched version
LOG(INFO, LOG_TAG) << "metadata: <" << m[1] << ">\n";
setMeta(json::parse(m[1].str()));
libreelec_patched = true;
json j = json::parse(m[1].str());
Metatags meta;
meta.artist = std::vector<std::string>{j["ARTIST"].get<std::string>()};
meta.title = j["TITLE"].get<std::string>();
setMeta(meta);
}
else if (regex_search(line, m, re_track_loaded))
{
LOG(INFO, LOG_TAG) << "metadata: <" << m[1] << ">\n";
Metatags meta;
meta.title = string(m[1]);
meta.duration = cpt::stod(m[2]) / 1000.;
setMeta(meta);
// Properties props;
// props.can_seek = true;
// props.can_control = true;
// setProperties(props);
}
}

View file

@ -177,7 +177,7 @@ 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());
// setMeta(json());
}
@ -379,7 +379,7 @@ json PcmStream::toJson() const
};
if (meta_)
j["meta"] = meta_->msg;
j["meta"] = meta_->toJson();
if (properties_)
j["properties"] = properties_->toJson();
@ -393,7 +393,7 @@ void PcmStream::addListener(PcmListener* pcmListener)
}
std::shared_ptr<msg::StreamTags> PcmStream::getMeta() const
std::shared_ptr<Metatags> PcmStream::getMeta() const
{
return meta_;
}
@ -414,6 +414,16 @@ void PcmStream::setProperties(const Properties& props)
jsonrpcpp::Request request(++req_id_, "Player.SetProperties", props.toJson());
ctrl_script_->send(request.to_json().dump() + "\n"); //, params);
}
else // TODO: Will the ctr_script always loop back the new properties?
{
properties_ = std::make_shared<Properties>(props);
// Trigger a stream update
for (auto* listener : pcmListeners_)
{
if (listener != nullptr)
listener->onPropertiesChanged(this);
}
}
}
@ -433,11 +443,10 @@ void PcmStream::control(const std::string& command, const json& params)
}
void PcmStream::setMeta(const json& jtag)
void PcmStream::setMeta(const Metatags& meta)
{
meta_.reset(new msg::StreamTags(jtag));
meta_->msg["STREAM"] = name_;
LOG(INFO, LOG_TAG) << "Stream: " << name_ << ", metadata=" << meta_->msg.dump(4) << "\n";
meta_ = std::make_shared<Metatags>(meta);
LOG(INFO, LOG_TAG) << "Stream: " << name_ << ", metadata=" << meta_->toJson().dump(4) << "\n";
// Trigger a stream update
for (auto* listener : pcmListeners_)

View file

@ -36,11 +36,12 @@
#include <boost/optional.hpp>
#include "common/json.hpp"
#include "common/metatags.hpp"
#include "common/properties.hpp"
#include "common/sample_format.hpp"
#include "encoder/encoder.hpp"
#include "message/codec_header.hpp"
#include "message/stream_tags.hpp"
// #include "message/stream_tags.hpp"
#include "server_settings.hpp"
#include "stream_uri.hpp"
@ -168,8 +169,7 @@ public:
virtual const SampleFormat& getSampleFormat() const;
virtual std::string getCodec() const;
std::shared_ptr<msg::StreamTags> getMeta() const;
void setMeta(const json& j);
std::shared_ptr<Metatags> getMeta() const;
std::shared_ptr<Properties> getProperties() const;
void setProperties(const Properties& props);
@ -190,6 +190,8 @@ protected:
void resync(const std::chrono::nanoseconds& duration);
void chunkEncoded(const encoder::Encoder& encoder, std::shared_ptr<msg::PcmChunk> chunk, double duration);
void setMeta(const Metatags& meta);
std::chrono::time_point<std::chrono::steady_clock> tvEncodedChunk_;
std::vector<PcmListener*> pcmListeners_;
StreamUri uri_;
@ -198,7 +200,7 @@ protected:
std::unique_ptr<encoder::Encoder> encoder_;
std::string name_;
ReaderState state_;
std::shared_ptr<msg::StreamTags> meta_;
std::shared_ptr<Metatags> meta_;
std::shared_ptr<Properties> properties_;
boost::asio::io_context& ioc_;
ServerSettings server_settings_;

View file

@ -18,6 +18,9 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include <regex>
#include "common/aixlog.hpp"
#include "common/metatags.hpp"
#include "common/properties.hpp"
@ -141,7 +144,7 @@ TEST_CASE("Metatags")
"trackNumber": 5
}
)");
std::cout << in_json.dump(4) << "\n";
// std::cout << in_json.dump(4) << "\n";
Metatags meta(in_json);
REQUIRE(meta.album.has_value());
@ -151,7 +154,7 @@ TEST_CASE("Metatags")
REQUIRE(meta.genre.value().front() == "Dance/Electronic");
auto out_json = meta.toJson();
std::cout << out_json.dump(4) << "\n";
// std::cout << out_json.dump(4) << "\n";
REQUIRE(in_json == out_json);
}
@ -165,18 +168,18 @@ TEST_CASE("Properties")
"loopStatus": "track",
"shuffle": false,
"volume": 42,
"elapsed": 23.0
"position": 23.0
}
)");
std::cout << in_json.dump(4) << "\n";
// std::cout << in_json.dump(4) << "\n";
Properties props(in_json);
std::cout << props.toJson().dump(4) << "\n";
// std::cout << props.toJson().dump(4) << "\n";
REQUIRE(props.playback_status.has_value());
auto out_json = props.toJson();
std::cout << out_json.dump(4) << "\n";
// std::cout << out_json.dump(4) << "\n";
REQUIRE(in_json == out_json);
in_json = json::parse(R"(
@ -184,14 +187,31 @@ TEST_CASE("Properties")
"volume": 42
}
)");
std::cout << in_json.dump(4) << "\n";
// std::cout << in_json.dump(4) << "\n";
props.fromJson(in_json);
std::cout << props.toJson().dump(4) << "\n";
// std::cout << props.toJson().dump(4) << "\n";
REQUIRE(!props.playback_status.has_value());
out_json = props.toJson();
std::cout << out_json.dump(4) << "\n";
// std::cout << out_json.dump(4) << "\n";
REQUIRE(in_json == out_json);
}
TEST_CASE("Librespot")
{
std::string line = "[2021-06-04T07:20:47Z INFO librespot_playback::player] <Tunnel> (310573 ms) loaded";
smatch m;
static regex re_track_loaded(R"( <(.*)> \((.*) ms\) loaded)");
// Parse the patched version
if (std::regex_search(line, m, re_track_loaded))
{
REQUIRE(m.size() == 3);
REQUIRE(m[1] == "Tunnel");
REQUIRE(m[2] == "310573");
}
REQUIRE(m.size() == 3);
}