mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-25 12:29:18 -05:00
Merge pull request #668 from chme/jsonapi
New JSON API endpoint player/toggle and support for volume steps in endpoint player/volume
This commit is contained in:
commit
99b0b644a9
@ -23,7 +23,7 @@ JSON-Object model:
|
|||||||
| Method | Endpoint | Description |
|
| Method | Endpoint | Description |
|
||||||
| --------- | ------------------------------------------------ | ------------------------------------ |
|
| --------- | ------------------------------------------------ | ------------------------------------ |
|
||||||
| GET | [/api/player](#get-player-status) | Get player status |
|
| GET | [/api/player](#get-player-status) | Get player status |
|
||||||
| PUT | [/api/player/play, /api/player/pause, /api/player/stop](#control-playback) | Start, pause or stop playback |
|
| PUT | [/api/player/play, /api/player/pause, /api/player/stop, /api/player/toggle](#control-playback) | Start, pause or stop playback |
|
||||||
| PUT | [/api/player/next, /api/player/prev](#skip-tracks) | Skip forward or backward |
|
| PUT | [/api/player/next, /api/player/prev](#skip-tracks) | Skip forward or backward |
|
||||||
| PUT | [/api/player/shuffle](#set-shuffle-mode) | Set shuffle mode |
|
| PUT | [/api/player/shuffle](#set-shuffle-mode) | Set shuffle mode |
|
||||||
| PUT | [/api/player/consume](#set-consume-mode) | Set consume mode |
|
| PUT | [/api/player/consume](#set-consume-mode) | Set consume mode |
|
||||||
@ -93,6 +93,10 @@ PUT /api/player/pause
|
|||||||
PUT /api/player/stop
|
PUT /api/player/stop
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```http
|
||||||
|
PUT /api/player/toggle
|
||||||
|
```
|
||||||
|
|
||||||
**Response**
|
**Response**
|
||||||
|
|
||||||
On success returns the HTTP `204 No Content` success status response code.
|
On success returns the HTTP `204 No Content` success status response code.
|
||||||
@ -111,6 +115,10 @@ curl -X PUT "http://localhost:3689/api/player/pause"
|
|||||||
curl -X PUT "http://localhost:3689/api/player/stop"
|
curl -X PUT "http://localhost:3689/api/player/stop"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl -X PUT "http://localhost:3689/api/player/toggle"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Skip tracks
|
### Skip tracks
|
||||||
|
|
||||||
@ -240,8 +248,10 @@ PUT /api/player/volume
|
|||||||
| Parameter | Value |
|
| Parameter | Value |
|
||||||
| --------------- | ----------------------------------------------------------- |
|
| --------------- | ----------------------------------------------------------- |
|
||||||
| volume | The new volume (0 - 100) |
|
| volume | The new volume (0 - 100) |
|
||||||
|
| step | The increase or decrease volume by the given amount (-100 - 100) |
|
||||||
| output_id | *(Optional)* If an output id is given, only the volume of this output will be changed. If parameter is omited, the master volume will be changed. |
|
| output_id | *(Optional)* If an output id is given, only the volume of this output will be changed. If parameter is omited, the master volume will be changed. |
|
||||||
|
|
||||||
|
Either `volume` or `step` must be present as query parameter
|
||||||
|
|
||||||
**Response**
|
**Response**
|
||||||
|
|
||||||
@ -253,6 +263,10 @@ On success returns the HTTP `204 No Content` success status response code.
|
|||||||
curl -X PUT "http://localhost:3689/api/player/volume?volume=50"
|
curl -X PUT "http://localhost:3689/api/player/volume?volume=50"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl -X PUT "http://localhost:3689/api/player/volume?step=-5"
|
||||||
|
```
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl -X PUT "http://localhost:3689/api/player/volume?volume=50&output_id=0"
|
curl -X PUT "http://localhost:3689/api/player/volume?volume=50&output_id=0"
|
||||||
```
|
```
|
||||||
|
@ -512,7 +512,7 @@ playqueuecontents_add_queue_item(struct evbuffer *songlist, struct db_queue_item
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
speaker_enum_cb(struct spk_info *spk, void *arg)
|
speaker_enum_cb(struct player_speaker_info *spk, void *arg)
|
||||||
{
|
{
|
||||||
struct evbuffer *evbuf;
|
struct evbuffer *evbuf;
|
||||||
int len;
|
int len;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -1066,10 +1067,11 @@ struct outputs_param
|
|||||||
{
|
{
|
||||||
json_object *output;
|
json_object *output;
|
||||||
uint64_t output_id;
|
uint64_t output_id;
|
||||||
|
int output_volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
static json_object *
|
static json_object *
|
||||||
speaker_to_json(struct spk_info *spk)
|
speaker_to_json(struct player_speaker_info *spk)
|
||||||
{
|
{
|
||||||
json_object *output;
|
json_object *output;
|
||||||
char output_id[21];
|
char output_id[21];
|
||||||
@ -1090,7 +1092,7 @@ speaker_to_json(struct spk_info *spk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
speaker_enum_cb(struct spk_info *spk, void *arg)
|
speaker_enum_cb(struct player_speaker_info *spk, void *arg)
|
||||||
{
|
{
|
||||||
json_object *outputs;
|
json_object *outputs;
|
||||||
json_object *output;
|
json_object *output;
|
||||||
@ -1101,25 +1103,15 @@ speaker_enum_cb(struct spk_info *spk, void *arg)
|
|||||||
json_object_array_add(outputs, output);
|
json_object_array_add(outputs, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
speaker_get_cb(struct spk_info *spk, void *arg)
|
|
||||||
{
|
|
||||||
struct outputs_param *outputs_param = arg;
|
|
||||||
|
|
||||||
if (outputs_param->output_id == spk->id)
|
|
||||||
{
|
|
||||||
outputs_param->output = speaker_to_json(spk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GET /api/outputs/[output_id]
|
* GET /api/outputs/[output_id]
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
jsonapi_reply_outputs_get_byid(struct httpd_request *hreq)
|
jsonapi_reply_outputs_get_byid(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
struct outputs_param outputs_param;
|
struct player_speaker_info speaker_info;
|
||||||
uint64_t output_id;
|
uint64_t output_id;
|
||||||
|
json_object *jreply;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = safe_atou64(hreq->uri_parsed->path_parts[2], &output_id);
|
ret = safe_atou64(hreq->uri_parsed->path_parts[2], &output_id);
|
||||||
@ -1130,21 +1122,19 @@ jsonapi_reply_outputs_get_byid(struct httpd_request *hreq)
|
|||||||
return HTTP_BADREQUEST;
|
return HTTP_BADREQUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputs_param.output_id = output_id;
|
ret = player_speaker_get_byid(output_id, &speaker_info);
|
||||||
outputs_param.output = NULL;
|
|
||||||
|
|
||||||
player_speaker_enumerate(speaker_get_cb, &outputs_param);
|
if (ret < 0)
|
||||||
|
|
||||||
if (!outputs_param.output)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_WEB, "No output found for '%s'\n", hreq->uri_parsed->path);
|
DPRINTF(E_LOG, L_WEB, "No output found for '%s'\n", hreq->uri_parsed->path);
|
||||||
|
|
||||||
return HTTP_BADREQUEST;
|
return HTTP_BADREQUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_ERRNO(L_WEB, evbuffer_add_printf(hreq->reply, "%s", json_object_to_json_string(outputs_param.output)));
|
jreply = speaker_to_json(&speaker_info);
|
||||||
|
CHECK_ERRNO(L_WEB, evbuffer_add_printf(hreq->reply, "%s", json_object_to_json_string(jreply)));
|
||||||
|
|
||||||
jparse_free(outputs_param.output);
|
jparse_free(jreply);
|
||||||
|
|
||||||
return HTTP_OK;
|
return HTTP_OK;
|
||||||
}
|
}
|
||||||
@ -1440,6 +1430,33 @@ jsonapi_reply_player_stop(struct httpd_request *hreq)
|
|||||||
return HTTP_NOCONTENT;
|
return HTTP_NOCONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
jsonapi_reply_player_toggle(struct httpd_request *hreq)
|
||||||
|
{
|
||||||
|
struct player_status status;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
player_get_status(&status);
|
||||||
|
DPRINTF(E_DBG, L_WEB, "Toggle playback request with current state %d.\n", status.status);
|
||||||
|
|
||||||
|
if (status.status == PLAY_PLAYING)
|
||||||
|
{
|
||||||
|
ret = player_playback_pause();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = player_playback_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_WEB, "Error toggling playback state.\n");
|
||||||
|
return HTTP_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HTTP_NOCONTENT;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
jsonapi_reply_player_next(struct httpd_request *hreq)
|
jsonapi_reply_player_next(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
@ -2175,37 +2192,114 @@ jsonapi_reply_player_consume(struct httpd_request *hreq)
|
|||||||
return HTTP_NOCONTENT;
|
return HTTP_NOCONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
volume_set(int volume, int step)
|
||||||
|
{
|
||||||
|
int new_volume;
|
||||||
|
struct player_status status;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
new_volume = volume;
|
||||||
|
|
||||||
|
if (step != 0)
|
||||||
|
{
|
||||||
|
// Calculate new volume from given step value
|
||||||
|
player_get_status(&status);
|
||||||
|
new_volume = status.volume + step;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we are setting a correct value
|
||||||
|
new_volume = new_volume > 100 ? 100 : new_volume;
|
||||||
|
new_volume = new_volume < 0 ? 0 : new_volume;
|
||||||
|
|
||||||
|
ret = player_volume_set(new_volume);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
output_volume_set(int volume, int step, uint64_t output_id)
|
||||||
|
{
|
||||||
|
int new_volume;
|
||||||
|
struct player_speaker_info speaker_info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
new_volume = volume;
|
||||||
|
|
||||||
|
if (step != 0)
|
||||||
|
{
|
||||||
|
// Calculate new output volume from the given step value
|
||||||
|
ret = player_speaker_get_byid(output_id, &speaker_info);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_WEB, "No output found for the given output id .\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_volume = speaker_info.absvol + step;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we are setting a correct value
|
||||||
|
new_volume = new_volume > 100 ? 100 : new_volume;
|
||||||
|
new_volume = new_volume < 0 ? 0 : new_volume;
|
||||||
|
|
||||||
|
ret = player_volume_setabs_speaker(output_id, new_volume);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
jsonapi_reply_player_volume(struct httpd_request *hreq)
|
jsonapi_reply_player_volume(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
|
const char *param_volume;
|
||||||
|
const char *param_step;
|
||||||
const char *param;
|
const char *param;
|
||||||
uint64_t output_id;
|
uint64_t output_id;
|
||||||
int volume;
|
int volume;
|
||||||
|
int step;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
param = evhttp_find_header(hreq->query, "volume");
|
volume = 0;
|
||||||
if (!param)
|
step = 0;
|
||||||
return HTTP_BADREQUEST;
|
|
||||||
|
|
||||||
ret = safe_atoi32(param, &volume);
|
// Parse and validate parameters
|
||||||
|
param_volume = evhttp_find_header(hreq->query, "volume");
|
||||||
|
if (param_volume)
|
||||||
|
{
|
||||||
|
ret = safe_atoi32(param_volume, &volume);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return HTTP_BADREQUEST;
|
return HTTP_BADREQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
if (volume < 0 || volume > 100)
|
param_step = evhttp_find_header(hreq->query, "step");
|
||||||
|
if (param_step)
|
||||||
|
{
|
||||||
|
ret = safe_atoi32(param_step, &step);
|
||||||
|
if (ret < 0)
|
||||||
return HTTP_BADREQUEST;
|
return HTTP_BADREQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!param_volume && !param_step)
|
||||||
|
|| (param_volume && param_step))
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_WEB, "Invalid parameters for player/volume request. Either 'volume' or 'step' parameter required.\n");
|
||||||
|
return HTTP_BADREQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
param = evhttp_find_header(hreq->query, "output_id");
|
param = evhttp_find_header(hreq->query, "output_id");
|
||||||
if (param)
|
if (param)
|
||||||
{
|
{
|
||||||
|
// Update volume for individual output
|
||||||
ret = safe_atou64(param, &output_id);
|
ret = safe_atou64(param, &output_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_WEB, "Invalid value for parameter 'output_id'. Output id must be an integer (output_id='%s').\n", param);
|
||||||
return HTTP_BADREQUEST;
|
return HTTP_BADREQUEST;
|
||||||
|
}
|
||||||
ret = player_volume_setabs_speaker(output_id, volume);
|
ret = output_volume_set(volume, step, output_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = player_volume_set(volume);
|
// Update master volume
|
||||||
|
ret = volume_set(volume, step);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -3240,6 +3334,7 @@ static struct httpd_uri_map adm_handlers[] =
|
|||||||
{ EVHTTP_REQ_PUT, "^/api/player/play$", jsonapi_reply_player_play },
|
{ EVHTTP_REQ_PUT, "^/api/player/play$", jsonapi_reply_player_play },
|
||||||
{ EVHTTP_REQ_PUT, "^/api/player/pause$", jsonapi_reply_player_pause },
|
{ EVHTTP_REQ_PUT, "^/api/player/pause$", jsonapi_reply_player_pause },
|
||||||
{ EVHTTP_REQ_PUT, "^/api/player/stop$", jsonapi_reply_player_stop },
|
{ EVHTTP_REQ_PUT, "^/api/player/stop$", jsonapi_reply_player_stop },
|
||||||
|
{ EVHTTP_REQ_PUT, "^/api/player/toggle$", jsonapi_reply_player_toggle },
|
||||||
{ EVHTTP_REQ_PUT, "^/api/player/next$", jsonapi_reply_player_next },
|
{ EVHTTP_REQ_PUT, "^/api/player/next$", jsonapi_reply_player_next },
|
||||||
{ EVHTTP_REQ_PUT, "^/api/player/previous$", jsonapi_reply_player_previous },
|
{ EVHTTP_REQ_PUT, "^/api/player/previous$", jsonapi_reply_player_previous },
|
||||||
{ EVHTTP_REQ_PUT, "^/api/player/shuffle$", jsonapi_reply_player_shuffle },
|
{ EVHTTP_REQ_PUT, "^/api/player/shuffle$", jsonapi_reply_player_shuffle },
|
||||||
|
@ -3548,7 +3548,7 @@ mpd_command_password(struct evbuffer *evbuf, int argc, char **argv, char **errms
|
|||||||
* the shortid of output_get_param matches the given speaker/output spk.
|
* the shortid of output_get_param matches the given speaker/output spk.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
output_get_cb(struct spk_info *spk, void *arg)
|
output_get_cb(struct player_speaker_info *spk, void *arg)
|
||||||
{
|
{
|
||||||
struct output_get_param *param = arg;
|
struct output_get_param *param = arg;
|
||||||
|
|
||||||
@ -3696,7 +3696,7 @@ mpd_command_toggleoutput(struct evbuffer *evbuf, int argc, char **argv, char **e
|
|||||||
* outputvolume: 50
|
* outputvolume: 50
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
speaker_enum_cb(struct spk_info *spk, void *arg)
|
speaker_enum_cb(struct player_speaker_info *spk, void *arg)
|
||||||
{
|
{
|
||||||
struct evbuffer *evbuf;
|
struct evbuffer *evbuf;
|
||||||
|
|
||||||
|
74
src/player.c
74
src/player.c
@ -146,6 +146,12 @@ struct speaker_set_param
|
|||||||
int intval;
|
int intval;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct speaker_get_param
|
||||||
|
{
|
||||||
|
uint64_t spk_id;
|
||||||
|
struct player_speaker_info *spk_info;
|
||||||
|
};
|
||||||
|
|
||||||
struct metadata_param
|
struct metadata_param
|
||||||
{
|
{
|
||||||
struct input_metadata *input;
|
struct input_metadata *input;
|
||||||
@ -2407,29 +2413,37 @@ player_speaker_status_trigger(void)
|
|||||||
listener_notify(LISTENER_SPEAKER);
|
listener_notify(LISTENER_SPEAKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_to_speaker_info(struct player_speaker_info *spk, struct output_device *device)
|
||||||
|
{
|
||||||
|
memset(spk, 0, sizeof(struct player_speaker_info));
|
||||||
|
spk->id = device->id;
|
||||||
|
strncpy(spk->name, device->name, sizeof(spk->name));
|
||||||
|
spk->name[sizeof(spk->name) - 1] = '\0';
|
||||||
|
strncpy(spk->output_type, device->type_name, sizeof(spk->output_type));
|
||||||
|
spk->output_type[sizeof(spk->output_type) - 1] = '\0';
|
||||||
|
spk->relvol = device->relvol;
|
||||||
|
spk->absvol = device->volume;
|
||||||
|
|
||||||
|
spk->selected = device->selected;
|
||||||
|
spk->has_password = device->has_password;
|
||||||
|
spk->has_video = device->has_video;
|
||||||
|
spk->requires_auth = device->requires_auth;
|
||||||
|
spk->needs_auth_key = (device->requires_auth && device->auth_key == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static enum command_state
|
static enum command_state
|
||||||
speaker_enumerate(void *arg, int *retval)
|
speaker_enumerate(void *arg, int *retval)
|
||||||
{
|
{
|
||||||
struct spk_enum *spk_enum = arg;
|
struct spk_enum *spk_enum = arg;
|
||||||
struct output_device *device;
|
struct output_device *device;
|
||||||
struct spk_info spk;
|
struct player_speaker_info spk;
|
||||||
|
|
||||||
for (device = dev_list; device; device = device->next)
|
for (device = dev_list; device; device = device->next)
|
||||||
{
|
{
|
||||||
if (device->advertised || device->selected)
|
if (device->advertised || device->selected)
|
||||||
{
|
{
|
||||||
spk.id = device->id;
|
device_to_speaker_info(&spk, device);
|
||||||
spk.name = device->name;
|
|
||||||
spk.output_type = device->type_name;
|
|
||||||
spk.relvol = device->relvol;
|
|
||||||
spk.absvol = device->volume;
|
|
||||||
|
|
||||||
spk.selected = device->selected;
|
|
||||||
spk.has_password = device->has_password;
|
|
||||||
spk.has_video = device->has_video;
|
|
||||||
spk.requires_auth = device->requires_auth;
|
|
||||||
spk.needs_auth_key = (device->requires_auth && device->auth_key == NULL);
|
|
||||||
|
|
||||||
spk_enum->cb(&spk, spk_enum->arg);
|
spk_enum->cb(&spk, spk_enum->arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2438,6 +2452,28 @@ speaker_enumerate(void *arg, int *retval)
|
|||||||
return COMMAND_END;
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum command_state
|
||||||
|
speaker_get_byid(void *arg, int *retval)
|
||||||
|
{
|
||||||
|
struct speaker_get_param *spk_param = arg;
|
||||||
|
struct output_device *device;
|
||||||
|
|
||||||
|
for (device = dev_list; device; device = device->next)
|
||||||
|
{
|
||||||
|
if ((device->advertised || device->selected)
|
||||||
|
&& device->id == spk_param->spk_id)
|
||||||
|
{
|
||||||
|
device_to_speaker_info(spk_param->spk_info, device);
|
||||||
|
*retval = 0;
|
||||||
|
return COMMAND_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No output device found with matching id
|
||||||
|
*retval = -1;
|
||||||
|
return COMMAND_END;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
speaker_activate(struct output_device *device)
|
speaker_activate(struct output_device *device)
|
||||||
{
|
{
|
||||||
@ -3123,6 +3159,18 @@ player_speaker_set(uint64_t *ids)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
player_speaker_get_byid(uint64_t id, struct player_speaker_info *spk)
|
||||||
|
{
|
||||||
|
struct speaker_get_param param;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
param.spk_id = id;
|
||||||
|
|
||||||
|
ret = commands_exec_sync(cmdbase, speaker_get_byid, NULL, ¶m);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
player_speaker_enable(uint64_t id)
|
player_speaker_enable(uint64_t id)
|
||||||
{
|
{
|
||||||
|
11
src/player.h
11
src/player.h
@ -29,10 +29,10 @@ enum repeat_mode {
|
|||||||
REPEAT_ALL = 2,
|
REPEAT_ALL = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spk_info {
|
struct player_speaker_info {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
const char *name;
|
char name[255];
|
||||||
const char *output_type;
|
char output_type[50];
|
||||||
int relvol;
|
int relvol;
|
||||||
int absvol;
|
int absvol;
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ struct player_status {
|
|||||||
uint32_t len_ms;
|
uint32_t len_ms;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*spk_enum_cb)(struct spk_info *spk, void *arg);
|
typedef void (*spk_enum_cb)(struct player_speaker_info *spk, void *arg);
|
||||||
|
|
||||||
struct player_history
|
struct player_history
|
||||||
{
|
{
|
||||||
@ -95,6 +95,9 @@ player_speaker_enumerate(spk_enum_cb cb, void *arg);
|
|||||||
int
|
int
|
||||||
player_speaker_set(uint64_t *ids);
|
player_speaker_set(uint64_t *ids);
|
||||||
|
|
||||||
|
int
|
||||||
|
player_speaker_get_byid(uint64_t id, struct player_speaker_info *spk);
|
||||||
|
|
||||||
int
|
int
|
||||||
player_speaker_enable(uint64_t id);
|
player_speaker_enable(uint64_t id);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user