mirror of
https://github.com/badaix/snapcast.git
synced 2025-06-02 10:51:45 +02:00
Comment out stream_tags
This commit is contained in:
parent
9bbba976f9
commit
53e27e0d8b
13 changed files with 173 additions and 106 deletions
|
@ -71,9 +71,9 @@ using namespace player;
|
||||||
static constexpr auto LOG_TAG = "Controller";
|
static constexpr auto LOG_TAG = "Controller";
|
||||||
static constexpr auto TIME_SYNC_INTERVAL = 1s;
|
static constexpr auto TIME_SYNC_INTERVAL = 1s;
|
||||||
|
|
||||||
Controller::Controller(boost::asio::io_context& io_context, const ClientSettings& settings, std::unique_ptr<MetadataAdapter> meta)
|
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)),
|
: io_context_(io_context), timer_(io_context), settings_(settings), stream_(nullptr), decoder_(nullptr), player_(nullptr),
|
||||||
serverSettings_(nullptr)
|
serverSettings_(nullptr) // meta_(std::move(meta)),
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,14 +241,14 @@ void Controller::getNextMessage()
|
||||||
player_->setVolume(serverSettings_->getVolume() / 100., serverSettings_->isMuted());
|
player_->setVolume(serverSettings_->getVolume() / 100., serverSettings_->isMuted());
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
else if (response->type == message_type::kStreamTags)
|
// else if (response->type == message_type::kStreamTags)
|
||||||
{
|
// {
|
||||||
if (meta_)
|
// if (meta_)
|
||||||
{
|
// {
|
||||||
auto stream_tags = msg::message_cast<msg::StreamTags>(std::move(response));
|
// auto stream_tags = msg::message_cast<msg::StreamTags>(std::move(response));
|
||||||
meta_->push(stream_tags->msg);
|
// meta_->push(stream_tags->msg);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(WARNING, LOG_TAG) << "Unexpected message received, type: " << response->type << "\n";
|
LOG(WARNING, LOG_TAG) << "Unexpected message received, type: " << response->type << "\n";
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#include "decoder/decoder.hpp"
|
#include "decoder/decoder.hpp"
|
||||||
#include "message/message.hpp"
|
#include "message/message.hpp"
|
||||||
#include "message/server_settings.hpp"
|
#include "message/server_settings.hpp"
|
||||||
#include "message/stream_tags.hpp"
|
// #include "message/stream_tags.hpp"
|
||||||
#include "metadata.hpp"
|
// #include "metadata.hpp"
|
||||||
#include "player/player.hpp"
|
#include "player/player.hpp"
|
||||||
#include "stream.hpp"
|
#include "stream.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
@ -43,7 +43,7 @@ using namespace std::chrono_literals;
|
||||||
class Controller
|
class Controller
|
||||||
{
|
{
|
||||||
public:
|
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 start();
|
||||||
// void stop();
|
// void stop();
|
||||||
static std::vector<std::string> getSupportedPlayerNames();
|
static std::vector<std::string> getSupportedPlayerNames();
|
||||||
|
@ -63,13 +63,12 @@ private:
|
||||||
boost::asio::io_context& io_context_;
|
boost::asio::io_context& io_context_;
|
||||||
boost::asio::steady_timer timer_;
|
boost::asio::steady_timer timer_;
|
||||||
ClientSettings settings_;
|
ClientSettings settings_;
|
||||||
std::string meta_callback_;
|
|
||||||
SampleFormat sampleFormat_;
|
SampleFormat sampleFormat_;
|
||||||
std::unique_ptr<ClientConnection> clientConnection_;
|
std::unique_ptr<ClientConnection> clientConnection_;
|
||||||
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<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_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include "common/str_compat.hpp"
|
#include "common/str_compat.hpp"
|
||||||
#include "common/utils.hpp"
|
#include "common/utils.hpp"
|
||||||
#include "common/version.hpp"
|
#include "common/version.hpp"
|
||||||
#include "metadata.hpp"
|
// #include "metadata.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
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";
|
LOG(INFO, LOG_TAG) << "Version " << version::code << (!version::rev().empty() ? (", revision " + version::rev(8)) : ("")) << "\n";
|
||||||
|
|
||||||
// Setup metadata handling
|
// Setup metadata handling
|
||||||
auto meta(metaStderr ? std::make_unique<MetaStderrAdapter>() : std::make_unique<MetadataAdapter>());
|
// auto meta(metaStderr ? std::make_unique<MetaStderrAdapter>() : std::make_unique<MetadataAdapter>());
|
||||||
auto controller = make_shared<Controller>(io_context, settings, std::move(meta));
|
auto controller = make_shared<Controller>(io_context, settings); //, std::move(meta));
|
||||||
controller->start();
|
controller->start();
|
||||||
|
|
||||||
int num_threads = 0;
|
int num_threads = 0;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "hello.hpp"
|
#include "hello.hpp"
|
||||||
#include "pcm_chunk.hpp"
|
#include "pcm_chunk.hpp"
|
||||||
#include "server_settings.hpp"
|
#include "server_settings.hpp"
|
||||||
#include "stream_tags.hpp"
|
// #include "stream_tags.hpp"
|
||||||
#include "time.hpp"
|
#include "time.hpp"
|
||||||
|
|
||||||
#include "common/str_compat.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);
|
return createMessage<Hello>(base_message, buffer);
|
||||||
case message_type::kServerSettings:
|
case message_type::kServerSettings:
|
||||||
return createMessage<ServerSettings>(base_message, buffer);
|
return createMessage<ServerSettings>(base_message, buffer);
|
||||||
case message_type::kStreamTags:
|
// case message_type::kStreamTags:
|
||||||
return createMessage<StreamTags>(base_message, buffer);
|
// return createMessage<StreamTags>(base_message, buffer);
|
||||||
case message_type::kTime:
|
case message_type::kTime:
|
||||||
return createMessage<Time>(base_message, buffer);
|
return createMessage<Time>(base_message, buffer);
|
||||||
case message_type::kWireChunk:
|
case message_type::kWireChunk:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/***
|
/***
|
||||||
This file is part of snapcast
|
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
|
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
|
||||||
|
@ -16,9 +16,10 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef STREAMTAGS_H
|
#ifndef STREAMTAGS_HPP
|
||||||
#define STREAMTAGS_H
|
#define STREAMTAGS_HPP
|
||||||
|
|
||||||
|
// #include "common/metatags.hpp"
|
||||||
#include "json_message.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;
|
~StreamTags() override = default;
|
||||||
};
|
};
|
||||||
} // namespace msg
|
} // namespace msg
|
||||||
|
|
28
control/test.cpp
Normal file
28
control/test.cpp
Normal 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();
|
||||||
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "message/client_info.hpp"
|
#include "message/client_info.hpp"
|
||||||
#include "message/hello.hpp"
|
#include "message/hello.hpp"
|
||||||
#include "message/stream_tags.hpp"
|
// #include "message/stream_tags.hpp"
|
||||||
#include "message/time.hpp"
|
#include "message/time.hpp"
|
||||||
#include "stream_session_tcp.hpp"
|
#include "stream_session_tcp.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -56,13 +56,12 @@ void Server::onMetaChanged(const PcmStream* pcmStream)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
const auto meta = pcmStream->getMeta();
|
const auto meta = pcmStream->getMeta();
|
||||||
LOG(DEBUG, LOG_TAG) << "metadata = " << meta->msg.dump(3) << "\n";
|
LOG(DEBUG, LOG_TAG) << "Metadata changed, stream: " << pcmStream->getName() << ", meta: " << meta->toJson().dump(3) << "\n";
|
||||||
LOG(DEBUG, LOG_TAG) << "onMetaChanged (" << pcmStream->getName() << ")\n";
|
|
||||||
|
|
||||||
streamServer_->onMetaChanged(pcmStream, meta);
|
// streamServer_->onMetaChanged(pcmStream, meta);
|
||||||
|
|
||||||
// Send meta to all connected clients
|
// 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);
|
controlServer_->send(notification.dump(), nullptr);
|
||||||
// cout << "Notification: " << notification.dump() << "\n";
|
// cout << "Notification: " << notification.dump() << "\n";
|
||||||
}
|
}
|
||||||
|
@ -70,8 +69,8 @@ void Server::onMetaChanged(const PcmStream* pcmStream)
|
||||||
|
|
||||||
void Server::onPropertiesChanged(const PcmStream* pcmStream)
|
void Server::onPropertiesChanged(const PcmStream* pcmStream)
|
||||||
{
|
{
|
||||||
LOG(DEBUG, LOG_TAG) << "onPropertiesChanged (" << pcmStream->getName() << ")\n";
|
|
||||||
const auto props = pcmStream->getProperties();
|
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
|
// 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();
|
||||||
|
@ -299,7 +298,7 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, jsonrpcpp::ent
|
||||||
session_ptr session = streamServer_->getStreamSession(client->id);
|
session_ptr session = streamServer_->getStreamSession(client->id);
|
||||||
if (session && (session->pcmStream() != stream))
|
if (session && (session->pcmStream() != stream))
|
||||||
{
|
{
|
||||||
session->send(stream->getMeta());
|
// session->send(stream->getMeta());
|
||||||
session->send(stream->getHeader());
|
session->send(stream->getHeader());
|
||||||
session->setPcmStream(stream);
|
session->setPcmStream(stream);
|
||||||
}
|
}
|
||||||
|
@ -354,7 +353,7 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, jsonrpcpp::ent
|
||||||
session_ptr session = streamServer_->getStreamSession(client->id);
|
session_ptr session = streamServer_->getStreamSession(client->id);
|
||||||
if (session && stream && (session->pcmStream() != stream))
|
if (session && stream && (session->pcmStream() != stream))
|
||||||
{
|
{
|
||||||
session->send(stream->getMeta());
|
// session->send(stream->getMeta());
|
||||||
session->send(stream->getHeader());
|
session->send(stream->getHeader());
|
||||||
session->setPcmStream(stream);
|
session->setPcmStream(stream);
|
||||||
}
|
}
|
||||||
|
@ -417,28 +416,29 @@ void Server::processRequest(const jsonrpcpp::request_ptr request, jsonrpcpp::ent
|
||||||
}
|
}
|
||||||
else if (request->method().find("Stream.") == 0)
|
else if (request->method().find("Stream.") == 0)
|
||||||
{
|
{
|
||||||
if (request->method().find("Stream.SetMeta") == 0)
|
// if (request->method().find("Stream.SetMeta") == 0)
|
||||||
{
|
// {
|
||||||
// clang-format off
|
// 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", "meta": {"album": "some album", "artist": "some artist", "track": "some track"...}}}
|
||||||
// Response: {"id":4,"jsonrpc":"2.0","result":{"id":"Spotify"}}
|
// 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
|
// // Find stream
|
||||||
string streamId = request->params().get<std::string>("id");
|
// string streamId = request->params().get<std::string>("id");
|
||||||
PcmStreamPtr stream = streamManager_->getStream(streamId);
|
// PcmStreamPtr stream = streamManager_->getStream(streamId);
|
||||||
if (stream == nullptr)
|
// if (stream == nullptr)
|
||||||
throw jsonrpcpp::InternalErrorException("Stream not found", request->id());
|
// throw jsonrpcpp::InternalErrorException("Stream not found", request->id());
|
||||||
|
|
||||||
// Set metadata from request
|
// // Set metadata from request
|
||||||
stream->setMeta(request->params().get("meta"));
|
// stream->setMeta(request->params().get("meta"));
|
||||||
|
|
||||||
// Setup response
|
// // Setup response
|
||||||
result["id"] = streamId;
|
// result["id"] = streamId;
|
||||||
}
|
// }
|
||||||
else if (request->method().find("Stream.Control") == 0)
|
if (request->method().find("Stream.Control") == 0)
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Request: {"id":4,"jsonrpc":"2.0","method":"Stream.Control","params":{"id":"Spotify", "command": "next", params: {}}}
|
// 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();
|
saveConfig();
|
||||||
|
|
||||||
LOG(DEBUG, LOG_TAG) << "Sending meta data to " << streamSession->clientId << "\n";
|
// LOG(DEBUG, LOG_TAG) << "Sending meta data to " << streamSession->clientId << "\n";
|
||||||
streamSession->send(stream->getMeta());
|
// streamSession->send(stream->getMeta());
|
||||||
streamSession->setPcmStream(stream);
|
streamSession->setPcmStream(stream);
|
||||||
auto headerChunk = stream->getHeader();
|
auto headerChunk = stream->getHeader();
|
||||||
LOG(DEBUG, LOG_TAG) << "Sending codec header to " << streamSession->clientId << "\n";
|
LOG(DEBUG, LOG_TAG) << "Sending codec header to " << streamSession->clientId << "\n";
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "message/client_info.hpp"
|
#include "message/client_info.hpp"
|
||||||
#include "message/hello.hpp"
|
#include "message/hello.hpp"
|
||||||
#include "message/stream_tags.hpp"
|
// #include "message/stream_tags.hpp"
|
||||||
#include "message/time.hpp"
|
#include "message/time.hpp"
|
||||||
#include "stream_session_tcp.hpp"
|
#include "stream_session_tcp.hpp"
|
||||||
#include <iostream>
|
#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)
|
// void StreamServer::onMetaChanged(const PcmStream* pcmStream, std::shared_ptr<msg::StreamTags> meta)
|
||||||
{
|
// {
|
||||||
// Send meta to all connected clients
|
// // Send meta to all connected clients
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_);
|
// std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_);
|
||||||
for (const auto& s : sessions_)
|
// for (const auto& s : sessions_)
|
||||||
{
|
// {
|
||||||
if (auto session = s.lock())
|
// if (auto session = s.lock())
|
||||||
{
|
// {
|
||||||
if (session->pcmStream().get() == pcmStream)
|
// if (session->pcmStream().get() == pcmStream)
|
||||||
session->send(meta);
|
// session->send(meta);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
void StreamServer::onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, std::shared_ptr<msg::PcmChunk> chunk, double /*duration*/)
|
void StreamServer::onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, std::shared_ptr<msg::PcmChunk> chunk, double /*duration*/)
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
// void send(const msg::BaseMessage* message);
|
// void send(const msg::BaseMessage* message);
|
||||||
|
|
||||||
void addSession(const std::shared_ptr<StreamSession>& session);
|
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);
|
void onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, std::shared_ptr<msg::PcmChunk> chunk, double duration);
|
||||||
|
|
||||||
session_ptr getStreamSession(const std::string& clientId) const;
|
session_ptr getStreamSession(const std::string& clientId) const;
|
||||||
|
|
|
@ -107,7 +107,6 @@ void LibrespotStream::initExeAndPath(const std::string& filename)
|
||||||
|
|
||||||
void LibrespotStream::onStderrMsg(const std::string& line)
|
void LibrespotStream::onStderrMsg(const std::string& line)
|
||||||
{
|
{
|
||||||
static bool libreelec_patched = false;
|
|
||||||
// Watch stderr for 'Loading track' messages and set the stream metadata
|
// Watch stderr for 'Loading track' messages and set the stream metadata
|
||||||
// For more than track name check: https://github.com/plietar/librespot/issues/154
|
// 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:
|
// Librespot patch:
|
||||||
// info!("metadata:{{\"ARTIST\":\"{}\",\"TITLE\":\"{}\"}}", artist.name, track.name);
|
// info!("metadata:{{\"ARTIST\":\"{}\",\"TITLE\":\"{}\"}}", artist.name, track.name);
|
||||||
// non patched:
|
// non patched:
|
||||||
|
// [2021-06-04T07:20:47Z INFO librespot_playback::player] <Tunnel> (310573 ms) loaded
|
||||||
// info!("Track \"{}\" loaded", track.name);
|
// info!("Track \"{}\" loaded", track.name);
|
||||||
|
// std::cerr << line << "\n";
|
||||||
// If we detect a patched libreelec we don't want to bother with this anymoer
|
|
||||||
// to avoid duplicate metadata pushes
|
|
||||||
smatch m;
|
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_patched("metadata:(.*)");
|
||||||
|
static regex re_track_loaded(R"( <(.*)> \((.*) ms\) loaded)");
|
||||||
|
// Parse the patched version
|
||||||
if (regex_search(line, m, re_patched))
|
if (regex_search(line, m, re_patched))
|
||||||
{
|
{
|
||||||
|
// Patched version
|
||||||
LOG(INFO, LOG_TAG) << "metadata: <" << m[1] << ">\n";
|
LOG(INFO, LOG_TAG) << "metadata: <" << m[1] << ">\n";
|
||||||
|
json j = json::parse(m[1].str());
|
||||||
setMeta(json::parse(m[1].str()));
|
Metatags meta;
|
||||||
libreelec_patched = true;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,7 @@ PcmStream::PcmStream(PcmListener* pcmListener, boost::asio::io_context& ioc, con
|
||||||
if (uri_.query.find(kUriChunkMs) != uri_.query.end())
|
if (uri_.query.find(kUriChunkMs) != uri_.query.end())
|
||||||
chunk_ms_ = cpt::stoul(uri_.query[kUriChunkMs]);
|
chunk_ms_ = cpt::stoul(uri_.query[kUriChunkMs]);
|
||||||
|
|
||||||
setMeta(json());
|
// setMeta(json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ json PcmStream::toJson() const
|
||||||
};
|
};
|
||||||
|
|
||||||
if (meta_)
|
if (meta_)
|
||||||
j["meta"] = meta_->msg;
|
j["meta"] = meta_->toJson();
|
||||||
if (properties_)
|
if (properties_)
|
||||||
j["properties"] = properties_->toJson();
|
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_;
|
return meta_;
|
||||||
}
|
}
|
||||||
|
@ -414,6 +414,16 @@ void PcmStream::setProperties(const Properties& props)
|
||||||
jsonrpcpp::Request request(++req_id_, "Player.SetProperties", props.toJson());
|
jsonrpcpp::Request request(++req_id_, "Player.SetProperties", props.toJson());
|
||||||
ctrl_script_->send(request.to_json().dump() + "\n"); //, params);
|
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_ = std::make_shared<Metatags>(meta);
|
||||||
meta_->msg["STREAM"] = name_;
|
LOG(INFO, LOG_TAG) << "Stream: " << name_ << ", metadata=" << meta_->toJson().dump(4) << "\n";
|
||||||
LOG(INFO, LOG_TAG) << "Stream: " << name_ << ", metadata=" << meta_->msg.dump(4) << "\n";
|
|
||||||
|
|
||||||
// Trigger a stream update
|
// Trigger a stream update
|
||||||
for (auto* listener : pcmListeners_)
|
for (auto* listener : pcmListeners_)
|
||||||
|
|
|
@ -36,11 +36,12 @@
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
#include "common/json.hpp"
|
#include "common/json.hpp"
|
||||||
|
#include "common/metatags.hpp"
|
||||||
#include "common/properties.hpp"
|
#include "common/properties.hpp"
|
||||||
#include "common/sample_format.hpp"
|
#include "common/sample_format.hpp"
|
||||||
#include "encoder/encoder.hpp"
|
#include "encoder/encoder.hpp"
|
||||||
#include "message/codec_header.hpp"
|
#include "message/codec_header.hpp"
|
||||||
#include "message/stream_tags.hpp"
|
// #include "message/stream_tags.hpp"
|
||||||
#include "server_settings.hpp"
|
#include "server_settings.hpp"
|
||||||
#include "stream_uri.hpp"
|
#include "stream_uri.hpp"
|
||||||
|
|
||||||
|
@ -168,8 +169,7 @@ public:
|
||||||
virtual const SampleFormat& getSampleFormat() const;
|
virtual const SampleFormat& getSampleFormat() const;
|
||||||
virtual std::string getCodec() const;
|
virtual std::string getCodec() const;
|
||||||
|
|
||||||
std::shared_ptr<msg::StreamTags> getMeta() const;
|
std::shared_ptr<Metatags> getMeta() const;
|
||||||
void setMeta(const json& j);
|
|
||||||
|
|
||||||
std::shared_ptr<Properties> getProperties() const;
|
std::shared_ptr<Properties> getProperties() const;
|
||||||
void setProperties(const Properties& props);
|
void setProperties(const Properties& props);
|
||||||
|
@ -190,6 +190,8 @@ protected:
|
||||||
void resync(const std::chrono::nanoseconds& duration);
|
void resync(const std::chrono::nanoseconds& duration);
|
||||||
void chunkEncoded(const encoder::Encoder& encoder, std::shared_ptr<msg::PcmChunk> chunk, double 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::chrono::time_point<std::chrono::steady_clock> tvEncodedChunk_;
|
||||||
std::vector<PcmListener*> pcmListeners_;
|
std::vector<PcmListener*> pcmListeners_;
|
||||||
StreamUri uri_;
|
StreamUri uri_;
|
||||||
|
@ -198,7 +200,7 @@ protected:
|
||||||
std::unique_ptr<encoder::Encoder> encoder_;
|
std::unique_ptr<encoder::Encoder> encoder_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
ReaderState state_;
|
ReaderState state_;
|
||||||
std::shared_ptr<msg::StreamTags> meta_;
|
std::shared_ptr<Metatags> meta_;
|
||||||
std::shared_ptr<Properties> properties_;
|
std::shared_ptr<Properties> properties_;
|
||||||
boost::asio::io_context& ioc_;
|
boost::asio::io_context& ioc_;
|
||||||
ServerSettings server_settings_;
|
ServerSettings server_settings_;
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
|
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
#include "common/aixlog.hpp"
|
#include "common/aixlog.hpp"
|
||||||
#include "common/metatags.hpp"
|
#include "common/metatags.hpp"
|
||||||
#include "common/properties.hpp"
|
#include "common/properties.hpp"
|
||||||
|
@ -141,7 +144,7 @@ TEST_CASE("Metatags")
|
||||||
"trackNumber": 5
|
"trackNumber": 5
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
std::cout << in_json.dump(4) << "\n";
|
// std::cout << in_json.dump(4) << "\n";
|
||||||
|
|
||||||
Metatags meta(in_json);
|
Metatags meta(in_json);
|
||||||
REQUIRE(meta.album.has_value());
|
REQUIRE(meta.album.has_value());
|
||||||
|
@ -151,7 +154,7 @@ TEST_CASE("Metatags")
|
||||||
REQUIRE(meta.genre.value().front() == "Dance/Electronic");
|
REQUIRE(meta.genre.value().front() == "Dance/Electronic");
|
||||||
|
|
||||||
auto out_json = meta.toJson();
|
auto out_json = meta.toJson();
|
||||||
std::cout << out_json.dump(4) << "\n";
|
// std::cout << out_json.dump(4) << "\n";
|
||||||
REQUIRE(in_json == out_json);
|
REQUIRE(in_json == out_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,18 +168,18 @@ TEST_CASE("Properties")
|
||||||
"loopStatus": "track",
|
"loopStatus": "track",
|
||||||
"shuffle": false,
|
"shuffle": false,
|
||||||
"volume": 42,
|
"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);
|
Properties props(in_json);
|
||||||
std::cout << props.toJson().dump(4) << "\n";
|
// std::cout << props.toJson().dump(4) << "\n";
|
||||||
|
|
||||||
REQUIRE(props.playback_status.has_value());
|
REQUIRE(props.playback_status.has_value());
|
||||||
|
|
||||||
auto out_json = props.toJson();
|
auto out_json = props.toJson();
|
||||||
std::cout << out_json.dump(4) << "\n";
|
// std::cout << out_json.dump(4) << "\n";
|
||||||
REQUIRE(in_json == out_json);
|
REQUIRE(in_json == out_json);
|
||||||
|
|
||||||
in_json = json::parse(R"(
|
in_json = json::parse(R"(
|
||||||
|
@ -184,14 +187,31 @@ TEST_CASE("Properties")
|
||||||
"volume": 42
|
"volume": 42
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
std::cout << in_json.dump(4) << "\n";
|
// std::cout << in_json.dump(4) << "\n";
|
||||||
|
|
||||||
props.fromJson(in_json);
|
props.fromJson(in_json);
|
||||||
std::cout << props.toJson().dump(4) << "\n";
|
// std::cout << props.toJson().dump(4) << "\n";
|
||||||
|
|
||||||
REQUIRE(!props.playback_status.has_value());
|
REQUIRE(!props.playback_status.has_value());
|
||||||
|
|
||||||
out_json = props.toJson();
|
out_json = props.toJson();
|
||||||
std::cout << out_json.dump(4) << "\n";
|
// std::cout << out_json.dump(4) << "\n";
|
||||||
REQUIRE(in_json == out_json);
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue