mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-10 15:46:42 +02:00
Rename stream parameter "read_ms" to "chunk_ms"
This commit is contained in:
parent
b5551d9451
commit
aa3ce3d5ab
13 changed files with 79 additions and 63 deletions
|
@ -46,12 +46,12 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds
|
||||||
|
|
||||||
#### Stream
|
#### Stream
|
||||||
```json
|
```json
|
||||||
{"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 1","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"chunk_ms":"20","codec":"flac","name":"stream 1","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 1","scheme":"pipe"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Server
|
#### Server
|
||||||
```json
|
```json
|
||||||
{"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"}}]}
|
{"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,12 +206,12 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds
|
||||||
|
|
||||||
#### Response
|
#### Response
|
||||||
```json
|
```json
|
||||||
{"id":3,"jsonrpc":"2.0","result":{"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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"}}]}}}
|
{"id":3,"jsonrpc":"2.0","result":{"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Notification
|
#### Notification
|
||||||
```json
|
```json
|
||||||
{"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
```
|
```
|
||||||
### Group.SetName
|
### Group.SetName
|
||||||
#### Request
|
#### Request
|
||||||
|
@ -251,7 +251,7 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds
|
||||||
|
|
||||||
#### Response
|
#### Response
|
||||||
```json
|
```json
|
||||||
{"id":1,"jsonrpc":"2.0","result":{"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":1488025696,"usec":578142},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":81}},"connected":true,"host":{"arch":"x86_64","ip":"192.168.0.54","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc","lastSeen":{"sec":1488025696,"usec":611255},"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"}}]}}}
|
{"id":1,"jsonrpc":"2.0","result":{"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":1488025696,"usec":578142},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":81}},"connected":true,"host":{"arch":"x86_64","ip":"192.168.0.54","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc","lastSeen":{"sec":1488025696,"usec":611255},"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -263,12 +263,12 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds
|
||||||
|
|
||||||
#### Response
|
#### Response
|
||||||
```json
|
```json
|
||||||
{"id":2,"jsonrpc":"2.0","result":{"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"}}]}}}
|
{"id":2,"jsonrpc":"2.0","result":{"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Notification
|
#### Notification
|
||||||
```json
|
```json
|
||||||
{"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,11 +338,11 @@ The Server JSON object contains a list of Groups and Streams. Every Group holds
|
||||||
|
|
||||||
### Stream.OnUpdate
|
### Stream.OnUpdate
|
||||||
```json
|
```json
|
||||||
{"jsonrpc":"2.0","method":"Stream.OnUpdate","params":{"id":"stream 1","stream":{"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"}}}}
|
{"jsonrpc":"2.0","method":"Stream.OnUpdate","params":{"id":"stream 1","stream":{"id":"stream 1","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"chunk_ms":"20","codec":"flac","name":"stream 1","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 1","scheme":"pipe"}}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Server.OnUpdate
|
### Server.OnUpdate
|
||||||
```json
|
```json
|
||||||
{"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
#port = 1704
|
#port = 1704
|
||||||
|
|
||||||
# stream URI of the PCM input stream, can be configured multiple times
|
# stream URI of the PCM input stream, can be configured multiple times
|
||||||
# Format: TYPE://host/path?name=NAME[&codec=CODEC][&sampleformat=SAMPLEFORMAT]
|
# Format: TYPE://host/path?name=NAME[&codec=CODEC][&sampleformat=SAMPLEFORMAT][&chunk_ms=CHUNK_MS]
|
||||||
# Available types are:
|
# Available types are:
|
||||||
# pipe: pipe:///<path/to/pipe>?name=<name>
|
# pipe: pipe:///<path/to/pipe>?name=<name>
|
||||||
# tcp server: tcp://<listen IP, e.g. 127.0.0.1>:<port>?name=<name>[&mode=server]
|
# tcp server: tcp://<listen IP, e.g. 127.0.0.1>:<port>?name=<name>[&mode=server]
|
||||||
|
@ -100,8 +100,8 @@ stream = pipe:///tmp/snapfifo?name=default
|
||||||
# Type codec:? to get codec specific options
|
# Type codec:? to get codec specific options
|
||||||
#codec = flac
|
#codec = flac
|
||||||
|
|
||||||
# Default stream read buffer [ms]
|
# Default stream read chunk size [ms]
|
||||||
#stream_buffer = 20
|
#chunk_ms = 20
|
||||||
|
|
||||||
# Buffer [ms]
|
# Buffer [ms]
|
||||||
#buffer = 1000
|
#buffer = 1000
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct ServerSettings
|
||||||
std::string codec{"flac"};
|
std::string codec{"flac"};
|
||||||
int32_t bufferMs{1000};
|
int32_t bufferMs{1000};
|
||||||
std::string sampleFormat{"48000:16:2"};
|
std::string sampleFormat{"48000:16:2"};
|
||||||
size_t streamReadMs{20};
|
size_t streamChunkMs{20};
|
||||||
bool sendAudioToMutedClients{false};
|
bool sendAudioToMutedClients{false};
|
||||||
std::vector<std::string> bind_to_address{{"0.0.0.0"}};
|
std::vector<std::string> bind_to_address{{"0.0.0.0"}};
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,7 +86,10 @@ int main(int argc, char* argv[])
|
||||||
conf.add<Value<string>>("", "stream.sampleformat", "Default sample format", settings.stream.sampleFormat, &settings.stream.sampleFormat);
|
conf.add<Value<string>>("", "stream.sampleformat", "Default sample format", settings.stream.sampleFormat, &settings.stream.sampleFormat);
|
||||||
conf.add<Value<string>>("c", "stream.codec", "Default transport codec\n(flac|ogg|opus|pcm)[:options]\nType codec:? to get codec specific options",
|
conf.add<Value<string>>("c", "stream.codec", "Default transport codec\n(flac|ogg|opus|pcm)[:options]\nType codec:? to get codec specific options",
|
||||||
settings.stream.codec, &settings.stream.codec);
|
settings.stream.codec, &settings.stream.codec);
|
||||||
conf.add<Value<size_t>>("", "stream.stream_buffer", "Default stream read buffer [ms]", settings.stream.streamReadMs, &settings.stream.streamReadMs);
|
// deprecated: stream_buffer, use chunk_ms instead
|
||||||
|
conf.add<Value<size_t>>("", "stream.stream_buffer", "Default stream read chunk size [ms]", settings.stream.streamChunkMs,
|
||||||
|
&settings.stream.streamChunkMs);
|
||||||
|
conf.add<Value<size_t>>("", "stream.chunk_ms", "Default stream read chunk size [ms]", settings.stream.streamChunkMs, &settings.stream.streamChunkMs);
|
||||||
conf.add<Value<int>>("b", "stream.buffer", "Buffer [ms]", settings.stream.bufferMs, &settings.stream.bufferMs);
|
conf.add<Value<int>>("b", "stream.buffer", "Buffer [ms]", settings.stream.bufferMs, &settings.stream.bufferMs);
|
||||||
conf.add<Value<bool>>("", "stream.send_to_muted", "Send audio to muted clients", settings.stream.sendAudioToMutedClients,
|
conf.add<Value<bool>>("", "stream.send_to_muted", "Send audio to muted clients", settings.stream.sendAudioToMutedClients,
|
||||||
&settings.stream.sendAudioToMutedClients);
|
&settings.stream.sendAudioToMutedClients);
|
||||||
|
@ -252,10 +255,10 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
publishZeroConfg->publish(dns_services);
|
publishZeroConfg->publish(dns_services);
|
||||||
#endif
|
#endif
|
||||||
if (settings.stream.streamReadMs < 10)
|
if (settings.stream.streamChunkMs < 10)
|
||||||
{
|
{
|
||||||
LOG(WARNING) << "Stream read buffer is less than 10ms, changing to 10ms\n";
|
LOG(WARNING) << "Stream read chunk size is less than 10ms, changing to 10ms\n";
|
||||||
settings.stream.streamReadMs = 10;
|
settings.stream.streamChunkMs = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.stream.bufferMs < 400)
|
if (settings.stream.bufferMs < 400)
|
||||||
|
@ -271,7 +274,8 @@ int main(int argc, char* argv[])
|
||||||
num_threads = std::max(1, std::min(4, static_cast<int>(std::thread::hardware_concurrency())));
|
num_threads = std::max(1, std::min(4, static_cast<int>(std::thread::hardware_concurrency())));
|
||||||
LOG(INFO) << "number of threads: " << num_threads << ", hw threads: " << std::thread::hardware_concurrency() << "\n";
|
LOG(INFO) << "number of threads: " << num_threads << ", hw threads: " << std::thread::hardware_concurrency() << "\n";
|
||||||
|
|
||||||
auto sig = install_signal_handler({SIGHUP, SIGTERM, SIGINT}, [&io_context](int signal, const std::string& name) {
|
auto sig = install_signal_handler({SIGHUP, SIGTERM, SIGINT},
|
||||||
|
[&io_context](int signal, const std::string& name) {
|
||||||
SLOG(INFO) << "Received signal " << signal << ": " << name << "\n";
|
SLOG(INFO) << "Received signal " << signal << ": " << name << "\n";
|
||||||
io_context.stop();
|
io_context.stop();
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,7 +78,7 @@ void StreamServer::onMetaChanged(const PcmStream* pcmStream)
|
||||||
void StreamServer::onStateChanged(const PcmStream* pcmStream, const ReaderState& state)
|
void StreamServer::onStateChanged(const PcmStream* pcmStream, const ReaderState& state)
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Notification: {"jsonrpc":"2.0","method":"Stream.OnUpdate","params":{"id":"stream 1","stream":{"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"}}}}
|
// Notification: {"jsonrpc":"2.0","method":"Stream.OnUpdate","params":{"id":"stream 1","stream":{"id":"stream 1","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"chunk_ms":"20","codec":"flac","name":"stream 1","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 1","scheme":"pipe"}}}}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
LOG(INFO) << "onStateChanged (" << pcmStream->getName() << "): " << static_cast<int>(state) << "\n";
|
LOG(INFO) << "onStateChanged (" << pcmStream->getName() << "): " << static_cast<int>(state) << "\n";
|
||||||
// LOG(INFO) << pcmStream->toJson().dump(4);
|
// LOG(INFO) << pcmStream->toJson().dump(4);
|
||||||
|
@ -362,8 +362,8 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Request: {"id":3,"jsonrpc":"2.0","method":"Group.SetClients","params":{"clients":["00:21:6a:7d:74:fc#2","00:21:6a:7d:74:fc"],"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1"}}
|
// Request: {"id":3,"jsonrpc":"2.0","method":"Group.SetClients","params":{"clients":["00:21:6a:7d:74:fc#2","00:21:6a:7d:74:fc"],"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1"}}
|
||||||
// Response: {"id":3,"jsonrpc":"2.0","result":{"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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"}}]}}}
|
// Response: {"id":3,"jsonrpc":"2.0","result":{"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
// Notification: {"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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"}}]}}}
|
// Notification: {"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":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025905,"usec":45238},"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
vector<string> clients = request->params().get("clients");
|
vector<string> clients = request->params().get("clients");
|
||||||
// Remove clients from group
|
// Remove clients from group
|
||||||
|
@ -438,7 +438,7 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Request: {"id":1,"jsonrpc":"2.0","method":"Server.GetStatus"}
|
// Request: {"id":1,"jsonrpc":"2.0","method":"Server.GetStatus"}
|
||||||
// Response: {"id":1,"jsonrpc":"2.0","result":{"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":1488025696,"usec":578142},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":81}},"connected":true,"host":{"arch":"x86_64","ip":"192.168.0.54","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc","lastSeen":{"sec":1488025696,"usec":611255},"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"}}]}}}
|
// Response: {"id":1,"jsonrpc":"2.0","result":{"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":1488025696,"usec":578142},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":81}},"connected":true,"host":{"arch":"x86_64","ip":"192.168.0.54","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc","lastSeen":{"sec":1488025696,"usec":611255},"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
result["server"] = Config::instance().getServerStatus(streamManager_->toJson());
|
result["server"] = Config::instance().getServerStatus(streamManager_->toJson());
|
||||||
}
|
}
|
||||||
|
@ -446,8 +446,8 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Request: {"id":2,"jsonrpc":"2.0","method":"Server.DeleteClient","params":{"id":"00:21:6a:7d:74:fc"}}
|
// Request: {"id":2,"jsonrpc":"2.0","method":"Server.DeleteClient","params":{"id":"00:21:6a:7d:74:fc"}}
|
||||||
// Response: {"id":2,"jsonrpc":"2.0","result":{"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"}}]}}}
|
// Response: {"id":2,"jsonrpc":"2.0","result":{"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
// Notification: {"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"}}]}}}
|
// Notification: {"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
ClientInfoPtr clientInfo = Config::instance().getClientInfo(request->params().get<std::string>("id"));
|
ClientInfoPtr clientInfo = Config::instance().getClientInfo(request->params().get<std::string>("id"));
|
||||||
if (clientInfo == nullptr)
|
if (clientInfo == nullptr)
|
||||||
|
@ -699,7 +699,7 @@ void StreamServer::onMessageReceived(StreamSession* streamSession, const msg::Ba
|
||||||
if (newGroup)
|
if (newGroup)
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Notification: {"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":1488025796,"usec":714671},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}}],"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","muted":false,"name":"","stream_id":"stream 2"},{"clients":[{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025798,"usec":728305},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}}],"id":"c5da8f7a-f377-1e51-8266-c5cc61099b71","muted":false,"name":"","stream_id":"stream 1"}],"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"}}]}}}
|
// Notification: {"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":1488025796,"usec":714671},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}}],"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","muted":false,"name":"","stream_id":"stream 2"},{"clients":[{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"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","lastSeen":{"sec":1488025798,"usec":728305},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}}],"id":"c5da8f7a-f377-1e51-8266-c5cc61099b71","muted":false,"name":"","stream_id":"stream 1"}],"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":{"chunk_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":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
json server = Config::instance().getServerStatus(streamManager_->toJson());
|
json server = Config::instance().getServerStatus(streamManager_->toJson());
|
||||||
json notification = jsonrpcpp::Notification("Server.OnUpdate", jsonrpcpp::Parameter("server", server)).to_json();
|
json notification = jsonrpcpp::Notification("Server.OnUpdate", jsonrpcpp::Parameter("server", server)).to_json();
|
||||||
|
@ -801,7 +801,7 @@ void StreamServer::start()
|
||||||
controlServer_.reset(new ControlServer(io_context_, settings_.tcp, settings_.http, this));
|
controlServer_.reset(new ControlServer(io_context_, settings_.tcp, settings_.http, this));
|
||||||
controlServer_->start();
|
controlServer_->start();
|
||||||
|
|
||||||
streamManager_.reset(new StreamManager(this, io_context_, settings_.stream.sampleFormat, settings_.stream.codec, settings_.stream.streamReadMs));
|
streamManager_.reset(new StreamManager(this, io_context_, settings_.stream.sampleFormat, settings_.stream.codec, settings_.stream.streamChunkMs));
|
||||||
// throw SnapException("xxx");
|
// throw SnapException("xxx");
|
||||||
for (const auto& streamUri : settings_.stream.pcmStreams)
|
for (const auto& streamUri : settings_.stream.pcmStreams)
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,7 +58,7 @@ template <typename ReadStream>
|
||||||
AsioStream<ReadStream>::AsioStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const StreamUri& uri)
|
AsioStream<ReadStream>::AsioStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const StreamUri& uri)
|
||||||
: PcmStream(pcmListener, ioc, uri), read_timer_(ioc), state_timer_(ioc)
|
: PcmStream(pcmListener, ioc, uri), read_timer_(ioc), state_timer_(ioc)
|
||||||
{
|
{
|
||||||
chunk_ = std::make_unique<msg::PcmChunk>(sampleFormat_, pcmReadMs_);
|
chunk_ = std::make_unique<msg::PcmChunk>(sampleFormat_, chunk_ms_);
|
||||||
bytes_read_ = 0;
|
bytes_read_ = 0;
|
||||||
buffer_ms_ = 50;
|
buffer_ms_ = 50;
|
||||||
try
|
try
|
||||||
|
@ -76,7 +76,7 @@ void AsioStream<ReadStream>::check_state()
|
||||||
{
|
{
|
||||||
uint64_t last_read = bytes_read_;
|
uint64_t last_read = bytes_read_;
|
||||||
auto self = this->shared_from_this();
|
auto self = this->shared_from_this();
|
||||||
state_timer_.expires_after(std::chrono::milliseconds(500 + pcmReadMs_));
|
state_timer_.expires_after(std::chrono::milliseconds(500 + chunk_ms_));
|
||||||
state_timer_.async_wait([self, this, last_read](const boost::system::error_code& ec) {
|
state_timer_.async_wait([self, this, last_read](const boost::system::error_code& ec) {
|
||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
|
@ -142,7 +142,7 @@ void AsioStream<ReadStream>::do_read()
|
||||||
timeval now;
|
timeval now;
|
||||||
chronos::systemtimeofday(&now);
|
chronos::systemtimeofday(&now);
|
||||||
auto stream2systime_diff = chronos::diff<std::chrono::milliseconds>(now, tvEncodedChunk_);
|
auto stream2systime_diff = chronos::diff<std::chrono::milliseconds>(now, tvEncodedChunk_);
|
||||||
if (stream2systime_diff > chronos::sec(5) + chronos::msec(pcmReadMs_))
|
if (stream2systime_diff > chronos::sec(5) + chronos::msec(chunk_ms_))
|
||||||
{
|
{
|
||||||
LOG(WARNING) << "Stream and system time out of sync: " << stream2systime_diff.count() << "ms, resetting stream time.\n";
|
LOG(WARNING) << "Stream and system time out of sync: " << stream2systime_diff.count() << "ms, resetting stream time.\n";
|
||||||
first_ = true;
|
first_ = true;
|
||||||
|
@ -154,10 +154,10 @@ void AsioStream<ReadStream>::do_read()
|
||||||
nextTick_ = chronos::getTickCount() + buffer_ms_;
|
nextTick_ = chronos::getTickCount() + buffer_ms_;
|
||||||
}
|
}
|
||||||
encoder_->encode(chunk_.get());
|
encoder_->encode(chunk_.get());
|
||||||
nextTick_ += pcmReadMs_;
|
nextTick_ += chunk_ms_;
|
||||||
long currentTick = chronos::getTickCount();
|
long currentTick = chronos::getTickCount();
|
||||||
|
|
||||||
// Synchronize read to pcmReadMs_
|
// Synchronize read to chunk_ms_
|
||||||
if (nextTick_ >= currentTick)
|
if (nextTick_ >= currentTick)
|
||||||
{
|
{
|
||||||
read_timer_.expires_after(std::chrono::milliseconds(nextTick_ - currentTick));
|
read_timer_.expires_after(std::chrono::milliseconds(nextTick_ - currentTick));
|
||||||
|
|
|
@ -50,7 +50,7 @@ FileStream::~FileStream()
|
||||||
void FileStream::worker()
|
void FileStream::worker()
|
||||||
{
|
{
|
||||||
timeval tvChunk;
|
timeval tvChunk;
|
||||||
std::unique_ptr<msg::PcmChunk> chunk(new msg::PcmChunk(sampleFormat_, pcmReadMs_));
|
std::unique_ptr<msg::PcmChunk> chunk(new msg::PcmChunk(sampleFormat_, chunk_ms_));
|
||||||
|
|
||||||
ifs.seekg(0, ifs.end);
|
ifs.seekg(0, ifs.end);
|
||||||
size_t length = ifs.tellg();
|
size_t length = ifs.tellg();
|
||||||
|
@ -85,8 +85,8 @@ void FileStream::worker()
|
||||||
encoder_->encode(chunk.get());
|
encoder_->encode(chunk.get());
|
||||||
if (!active_)
|
if (!active_)
|
||||||
break;
|
break;
|
||||||
nextTick += pcmReadMs_;
|
nextTick += chunk_ms_;
|
||||||
chronos::addUs(tvChunk, pcmReadMs_ * 1000);
|
chronos::addUs(tvChunk, chunk_ms_ * 1000);
|
||||||
long currentTick = chronos::getTickCount();
|
long currentTick = chronos::getTickCount();
|
||||||
|
|
||||||
if (nextTick >= currentTick)
|
if (nextTick >= currentTick)
|
||||||
|
|
|
@ -32,24 +32,24 @@ using namespace std;
|
||||||
|
|
||||||
|
|
||||||
PcmStream::PcmStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const StreamUri& uri)
|
PcmStream::PcmStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const StreamUri& uri)
|
||||||
: active_(false), pcmListener_(pcmListener), uri_(uri), pcmReadMs_(20), state_(ReaderState::kIdle), ioc_(ioc)
|
: active_(false), pcmListener_(pcmListener), uri_(uri), chunk_ms_(20), state_(ReaderState::kIdle), ioc_(ioc)
|
||||||
{
|
{
|
||||||
encoder::EncoderFactory encoderFactory;
|
encoder::EncoderFactory encoderFactory;
|
||||||
if (uri_.query.find("codec") == uri_.query.end())
|
if (uri_.query.find(kUriCodec) == uri_.query.end())
|
||||||
throw SnapException("Stream URI must have a codec");
|
throw SnapException("Stream URI must have a codec");
|
||||||
encoder_.reset(encoderFactory.createEncoder(uri_.query["codec"]));
|
encoder_.reset(encoderFactory.createEncoder(uri_.query[kUriCodec]));
|
||||||
|
|
||||||
if (uri_.query.find("name") == uri_.query.end())
|
if (uri_.query.find(kUriName) == uri_.query.end())
|
||||||
throw SnapException("Stream URI must have a name");
|
throw SnapException("Stream URI must have a name");
|
||||||
name_ = uri_.query["name"];
|
name_ = uri_.query[kUriName];
|
||||||
|
|
||||||
if (uri_.query.find("sampleformat") == uri_.query.end())
|
if (uri_.query.find(kUriSampleFormat) == uri_.query.end())
|
||||||
throw SnapException("Stream URI must have a sampleformat");
|
throw SnapException("Stream URI must have a sampleformat");
|
||||||
sampleFormat_ = SampleFormat(uri_.query["sampleformat"]);
|
sampleFormat_ = SampleFormat(uri_.query[kUriSampleFormat]);
|
||||||
LOG(INFO) << "PcmStream sampleFormat: " << sampleFormat_.getFormat() << "\n";
|
LOG(INFO) << "PcmStream sampleFormat: " << sampleFormat_.getFormat() << "\n";
|
||||||
|
|
||||||
if (uri_.query.find("buffer_ms") != uri_.query.end())
|
if (uri_.query.find(kUriChunkMs) != uri_.query.end())
|
||||||
pcmReadMs_ = cpt::stoul(uri_.query["buffer_ms"]);
|
chunk_ms_ = cpt::stoul(uri_.query[kUriChunkMs]);
|
||||||
|
|
||||||
// meta_.reset(new msg::StreamTags());
|
// meta_.reset(new msg::StreamTags());
|
||||||
// meta_->msg["stream"] = name_;
|
// meta_->msg["stream"] = name_;
|
||||||
|
|
|
@ -45,6 +45,12 @@ enum class ReaderState
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static constexpr auto kUriCodec = "codec";
|
||||||
|
static constexpr auto kUriName = "name";
|
||||||
|
static constexpr auto kUriSampleFormat = "sampleformat";
|
||||||
|
static constexpr auto kUriChunkMs = "chunk_ms";
|
||||||
|
|
||||||
|
|
||||||
/// Callback interface for users of PcmStream
|
/// Callback interface for users of PcmStream
|
||||||
/**
|
/**
|
||||||
* Users of PcmStream should implement this to get the data
|
* Users of PcmStream should implement this to get the data
|
||||||
|
@ -105,7 +111,7 @@ protected:
|
||||||
PcmListener* pcmListener_;
|
PcmListener* pcmListener_;
|
||||||
StreamUri uri_;
|
StreamUri uri_;
|
||||||
SampleFormat sampleFormat_;
|
SampleFormat sampleFormat_;
|
||||||
size_t pcmReadMs_;
|
size_t chunk_ms_;
|
||||||
std::unique_ptr<encoder::Encoder> encoder_;
|
std::unique_ptr<encoder::Encoder> encoder_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
ReaderState state_;
|
ReaderState state_;
|
||||||
|
|
|
@ -46,7 +46,7 @@ PipeStream::PipeStream(PcmListener* pcmListener, boost::asio::io_context& ioc, c
|
||||||
if ((mkfifo(uri_.path.c_str(), 0666) != 0) && (errno != EEXIST))
|
if ((mkfifo(uri_.path.c_str(), 0666) != 0) && (errno != EEXIST))
|
||||||
throw SnapException("failed to make fifo \"" + uri_.path + "\": " + cpt::to_string(errno));
|
throw SnapException("failed to make fifo \"" + uri_.path + "\": " + cpt::to_string(errno));
|
||||||
}
|
}
|
||||||
chunk_ = make_unique<msg::PcmChunk>(sampleFormat_, pcmReadMs_);
|
chunk_ = make_unique<msg::PcmChunk>(sampleFormat_, chunk_ms_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +81,8 @@ void PipeStream::do_read()
|
||||||
int count = read(fd_, chunk_->payload + len, toRead - len);
|
int count = read(fd_, chunk_->payload + len, toRead - len);
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
{
|
{
|
||||||
LOG(DEBUG) << "count < 0: " << errno << " && idleBytes < maxIdleBytes, ms: " << 1000 * chunk_->payloadSize / (sampleFormat_.rate * sampleFormat_.frameSize) << "\n";
|
LOG(DEBUG) << "count < 0: " << errno
|
||||||
|
<< " && idleBytes < maxIdleBytes, ms: " << 1000 * chunk_->payloadSize / (sampleFormat_.rate * sampleFormat_.frameSize) << "\n";
|
||||||
memset(chunk_->payload + len, 0, toRead - len);
|
memset(chunk_->payload + len, 0, toRead - len);
|
||||||
len += toRead - len;
|
len += toRead - len;
|
||||||
break;
|
break;
|
||||||
|
@ -105,7 +106,7 @@ void PipeStream::do_read()
|
||||||
nextTick_ = chronos::getTickCount() + buffer_ms_;
|
nextTick_ = chronos::getTickCount() + buffer_ms_;
|
||||||
}
|
}
|
||||||
encoder_->encode(chunk_.get());
|
encoder_->encode(chunk_.get());
|
||||||
nextTick_ += pcmReadMs_;
|
nextTick_ += chunk_ms_;
|
||||||
long currentTick = chronos::getTickCount();
|
long currentTick = chronos::getTickCount();
|
||||||
|
|
||||||
if (nextTick_ >= currentTick)
|
if (nextTick_ >= currentTick)
|
||||||
|
|
|
@ -147,7 +147,7 @@ void ProcessStream::stderrReader()
|
||||||
void ProcessStream::worker()
|
void ProcessStream::worker()
|
||||||
{
|
{
|
||||||
timeval tvChunk;
|
timeval tvChunk;
|
||||||
std::unique_ptr<msg::PcmChunk> chunk(new msg::PcmChunk(sampleFormat_, pcmReadMs_));
|
std::unique_ptr<msg::PcmChunk> chunk(new msg::PcmChunk(sampleFormat_, chunk_ms_));
|
||||||
setState(ReaderState::kPlaying);
|
setState(ReaderState::kPlaying);
|
||||||
string lastException = "";
|
string lastException = "";
|
||||||
|
|
||||||
|
@ -206,8 +206,8 @@ void ProcessStream::worker()
|
||||||
if (!active_)
|
if (!active_)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nextTick += pcmReadMs_;
|
nextTick += chunk_ms_;
|
||||||
chronos::addUs(tvChunk, pcmReadMs_ * 1000);
|
chronos::addUs(tvChunk, chunk_ms_ * 1000);
|
||||||
long currentTick = chronos::getTickCount();
|
long currentTick = chronos::getTickCount();
|
||||||
|
|
||||||
if (nextTick >= currentTick)
|
if (nextTick >= currentTick)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "file_stream.hpp"
|
#include "file_stream.hpp"
|
||||||
#include "librespot_stream.hpp"
|
#include "librespot_stream.hpp"
|
||||||
#include "pipe_stream.hpp"
|
#include "pipe_stream.hpp"
|
||||||
|
// #include "pipe_stream_old.hpp"
|
||||||
#include "process_stream.hpp"
|
#include "process_stream.hpp"
|
||||||
#include "tcp_stream.hpp"
|
#include "tcp_stream.hpp"
|
||||||
|
|
||||||
|
@ -33,8 +34,8 @@ using namespace std;
|
||||||
|
|
||||||
|
|
||||||
StreamManager::StreamManager(PcmListener* pcmListener, boost::asio::io_context& ioc, const std::string& defaultSampleFormat, const std::string& defaultCodec,
|
StreamManager::StreamManager(PcmListener* pcmListener, boost::asio::io_context& ioc, const std::string& defaultSampleFormat, const std::string& defaultCodec,
|
||||||
size_t defaultReadBufferMs)
|
size_t defaultChunkBufferMs)
|
||||||
: pcmListener_(pcmListener), sampleFormat_(defaultSampleFormat), codec_(defaultCodec), readBufferMs_(defaultReadBufferMs), ioc_(ioc)
|
: pcmListener_(pcmListener), sampleFormat_(defaultSampleFormat), codec_(defaultCodec), chunkBufferMs_(defaultChunkBufferMs), ioc_(ioc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,14 +44,14 @@ PcmStreamPtr StreamManager::addStream(const std::string& uri)
|
||||||
{
|
{
|
||||||
StreamUri streamUri(uri);
|
StreamUri streamUri(uri);
|
||||||
|
|
||||||
if (streamUri.query.find("sampleformat") == streamUri.query.end())
|
if (streamUri.query.find(kUriSampleFormat) == streamUri.query.end())
|
||||||
streamUri.query["sampleformat"] = sampleFormat_;
|
streamUri.query[kUriSampleFormat] = sampleFormat_;
|
||||||
|
|
||||||
if (streamUri.query.find("codec") == streamUri.query.end())
|
if (streamUri.query.find(kUriCodec) == streamUri.query.end())
|
||||||
streamUri.query["codec"] = codec_;
|
streamUri.query[kUriCodec] = codec_;
|
||||||
|
|
||||||
if (streamUri.query.find("buffer_ms") == streamUri.query.end())
|
if (streamUri.query.find(kUriChunkMs) == streamUri.query.end())
|
||||||
streamUri.query["buffer_ms"] = cpt::to_string(readBufferMs_);
|
streamUri.query[kUriChunkMs] = cpt::to_string(chunkBufferMs_);
|
||||||
|
|
||||||
// LOG(DEBUG) << "\nURI: " << streamUri.uri << "\nscheme: " << streamUri.scheme << "\nhost: "
|
// LOG(DEBUG) << "\nURI: " << streamUri.uri << "\nscheme: " << streamUri.scheme << "\nhost: "
|
||||||
// << streamUri.host << "\npath: " << streamUri.path << "\nfragment: " << streamUri.fragment << "\n";
|
// << streamUri.host << "\npath: " << streamUri.path << "\nfragment: " << streamUri.fragment << "\n";
|
||||||
|
@ -63,6 +64,10 @@ PcmStreamPtr StreamManager::addStream(const std::string& uri)
|
||||||
{
|
{
|
||||||
stream = make_shared<PipeStream>(pcmListener_, ioc_, streamUri);
|
stream = make_shared<PipeStream>(pcmListener_, ioc_, streamUri);
|
||||||
}
|
}
|
||||||
|
// else if (streamUri.scheme == "pipe.old")
|
||||||
|
// {
|
||||||
|
// stream = make_shared<PipeStreamOld>(pcmListener_, ioc_, streamUri);
|
||||||
|
// }
|
||||||
else if (streamUri.scheme == "file")
|
else if (streamUri.scheme == "file")
|
||||||
{
|
{
|
||||||
stream = make_shared<FileStream>(pcmListener_, ioc_, streamUri);
|
stream = make_shared<FileStream>(pcmListener_, ioc_, streamUri);
|
||||||
|
|
|
@ -13,7 +13,7 @@ class StreamManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StreamManager(PcmListener* pcmListener, boost::asio::io_context& ioc, const std::string& defaultSampleFormat, const std::string& defaultCodec,
|
StreamManager(PcmListener* pcmListener, boost::asio::io_context& ioc, const std::string& defaultSampleFormat, const std::string& defaultCodec,
|
||||||
size_t defaultReadBufferMs = 20);
|
size_t defaultChunkBufferMs = 20);
|
||||||
|
|
||||||
PcmStreamPtr addStream(const std::string& uri);
|
PcmStreamPtr addStream(const std::string& uri);
|
||||||
void removeStream(const std::string& name);
|
void removeStream(const std::string& name);
|
||||||
|
@ -29,7 +29,7 @@ private:
|
||||||
PcmListener* pcmListener_;
|
PcmListener* pcmListener_;
|
||||||
std::string sampleFormat_;
|
std::string sampleFormat_;
|
||||||
std::string codec_;
|
std::string codec_;
|
||||||
size_t readBufferMs_;
|
size_t chunkBufferMs_;
|
||||||
boost::asio::io_context& ioc_;
|
boost::asio::io_context& ioc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue