mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-01 11:17:36 +02:00
Dynamic stream creation and deletion via JSON-RPC API
This commit is contained in:
parent
ad19c32b4f
commit
506de22ff1
4 changed files with 77 additions and 0 deletions
|
@ -72,6 +72,9 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds
|
||||||
* [Server.GetRPCVersion](#servergetrpcversion)
|
* [Server.GetRPCVersion](#servergetrpcversion)
|
||||||
* [Server.GetStatus](#servergetstatus)
|
* [Server.GetStatus](#servergetstatus)
|
||||||
* [Server.DeleteClient](#serverdeleteclient)
|
* [Server.DeleteClient](#serverdeleteclient)
|
||||||
|
* Stream
|
||||||
|
* [Stream.AddStream](#streamaddstream)
|
||||||
|
* [Stream.RemoveStream](#streamremovestream)
|
||||||
|
|
||||||
### Notifications
|
### Notifications
|
||||||
* Client
|
* 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"}}]}}}
|
{"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
|
## Notifications
|
||||||
### Client.OnConnect
|
### Client.OnConnect
|
||||||
```json
|
```json
|
||||||
|
|
|
@ -424,6 +424,39 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp
|
||||||
// Setup response
|
// Setup response
|
||||||
result["id"] = streamId;
|
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
|
else
|
||||||
throw jsonrpcpp::MethodNotFoundException(request->id());
|
throw jsonrpcpp::MethodNotFoundException(request->id());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<PcmStreamPtr>::iterator iter = streams_.begin(); iter != streams_.end(); ++iter )
|
||||||
|
{
|
||||||
|
auto s = *iter;
|
||||||
|
if( s->getName() == name )
|
||||||
|
{
|
||||||
|
s->stop();
|
||||||
|
streams_.erase( iter );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<PcmStreamPtr>& StreamManager::getStreams()
|
const std::vector<PcmStreamPtr>& StreamManager::getStreams()
|
||||||
{
|
{
|
||||||
return streams_;
|
return streams_;
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
const std::vector<PcmStreamPtr>& getStreams();
|
const std::vector<PcmStreamPtr>& getStreams();
|
||||||
const PcmStreamPtr getDefaultStream();
|
const PcmStreamPtr getDefaultStream();
|
||||||
const PcmStreamPtr getStream(const std::string& id);
|
const PcmStreamPtr getStream(const std::string& id);
|
||||||
|
void removeStream(const std::string& name);
|
||||||
json toJson() const;
|
json toJson() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -26,6 +27,7 @@ private:
|
||||||
PcmListener* pcmListener_;
|
PcmListener* pcmListener_;
|
||||||
std::string sampleFormat_;
|
std::string sampleFormat_;
|
||||||
std::string codec_;
|
std::string codec_;
|
||||||
|
std::string streamUri_;
|
||||||
size_t readBufferMs_;
|
size_t readBufferMs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue