diff --git a/doc/json_rpc_api/v2_0_0.md b/doc/json_rpc_api/v2_0_0.md index a4f8dfbc..d42e1e34 100644 --- a/doc/json_rpc_api/v2_0_0.md +++ b/doc/json_rpc_api/v2_0_0.md @@ -72,6 +72,9 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds * [Server.GetRPCVersion](#servergetrpcversion) * [Server.GetStatus](#servergetstatus) * [Server.DeleteClient](#serverdeleteclient) +* Stream + * [Stream.AddStream](#streamaddstream) + * [Stream.RemoveStream](#streamremovestream) ### Notifications * Client @@ -268,6 +271,30 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds {"jsonrpc":"2.0","method":"Server.OnUpdate","params":{"server":{"groups":[{"clients":[{"config":{"instance":2,"latency":6,"name":"123 456","volume":{"muted":false,"percent":48}},"connected":true,"host":{"arch":"x86_64","ip":"127.0.0.1","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc#2","lastSeen":{"sec":1488025751,"usec":654777},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}}],"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","muted":false,"name":"","stream_id":"stream 2"}],"server":{"host":{"arch":"x86_64","ip":"","mac":"","name":"T400","os":"Linux Mint 17.3 Rosa"},"snapserver":{"controlProtocolVersion":1,"name":"Snapserver","protocolVersion":1,"version":"0.10.0"}},"streams":[{"id":"stream 1","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"buffer_ms":"20","codec":"flac","name":"stream 1","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 1","scheme":"pipe"}},{"id":"stream 2","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"buffer_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}} ``` + +### Stream.AddStream +#### Request +```json +{"id":8,"jsonrpc":"2.0","method":"Stream.AddStream","params":{"streamUri":"pipe:///tmp/snapfifo?name=stream 2"}} +``` + +#### Response +```json +{"id":8,"jsonrpc":"2.0","result":{"stream_id":"stream 2"}} +``` + + +### Stream.RemoveStream +#### Request +```json +{"id":8,"jsonrpc":"2.0","method":"Stream.RemoveStream","params":{"id":"stream 2"}} +``` + +#### Response +```json +{"id":8,"jsonrpc":"2.0","result":{"stream_id":"stream 2"}} +``` + ## Notifications ### Client.OnConnect ```json diff --git a/server/streamServer.cpp b/server/streamServer.cpp index f61e9801..c8f5b7c4 100644 --- a/server/streamServer.cpp +++ b/server/streamServer.cpp @@ -424,6 +424,39 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp // Setup response result["id"] = streamId; } + else if (request->method() == "Stream.AddStream") + { + /// Request: {"id":4,"jsonrpc":"2.0","method":"Stream.AddStream","params":{"streamUri":"uri"}} + /// + /// Response: {"id":4,"jsonrpc":"2.0","result":{"stream_id":"Spotify"}} + /// Call onMetaChanged(const PcmStream* pcmStream) for updates and notifications + + LOG(INFO) << "Stream.AddStream(" << request->params().get("streamUri") << ")" << "\n"; + + // Find stream + string streamUri_ = request->params().get("streamUri"); + PcmStreamPtr stream = streamManager_->addStream(streamUri_); + if (stream == nullptr) + throw jsonrpcpp::InternalErrorException("Stream not created", request->id()); + stream->start(); // We start the stream, otherwise it would be silent + // Setup response + result["id"] = stream->getId(); + } + else if (request->method() == "Stream.RemoveStream") + { + /// Request: {"id":4,"jsonrpc":"2.0","method":"Stream.RemoveStream","params":{"id":"Spotify"}} + /// + /// Response: {"id":4,"jsonrpc":"2.0","result":{"stream_id":"Spotify"}} + /// Call onMetaChanged(const PcmStream* pcmStream) for updates and notifications + + LOG(INFO) << "Stream.RemoveStream(" << request->params().get("id") << ")" << "\n"; + + // Find stream + string streamId = request->params().get("id"); + streamManager_->removeStream(streamId); + // Setup response + result["id"] = streamId; + } else throw jsonrpcpp::MethodNotFoundException(request->id()); } diff --git a/server/streamreader/streamManager.cpp b/server/streamreader/streamManager.cpp index cf904b16..f457a775 100644 --- a/server/streamreader/streamManager.cpp +++ b/server/streamreader/streamManager.cpp @@ -95,6 +95,21 @@ PcmStreamPtr StreamManager::addStream(const std::string& uri) } +void StreamManager::removeStream(const std::string& name) +{ + if (streams_.empty()) return; + for( std::vector::iterator iter = streams_.begin(); iter != streams_.end(); ++iter ) + { + auto s = *iter; + if( s->getName() == name ) + { + s->stop(); + streams_.erase( iter ); + break; + } + } +} + const std::vector& StreamManager::getStreams() { return streams_; diff --git a/server/streamreader/streamManager.h b/server/streamreader/streamManager.h index b3755323..2f9c9687 100644 --- a/server/streamreader/streamManager.h +++ b/server/streamreader/streamManager.h @@ -19,6 +19,7 @@ public: const std::vector& getStreams(); const PcmStreamPtr getDefaultStream(); const PcmStreamPtr getStream(const std::string& id); + void removeStream(const std::string& name); json toJson() const; private: @@ -26,6 +27,7 @@ private: PcmListener* pcmListener_; std::string sampleFormat_; std::string codec_; + std::string streamUri_; size_t readBufferMs_; };