mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-29 15:36:00 -05:00
[jsonapi] Support changing volume by the given step (increase/decrease
volume)
This commit is contained in:
parent
db7b9c689b
commit
343c583229
@ -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,6 +1067,7 @@ 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 *
|
||||||
@ -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 spk_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;
|
||||||
}
|
}
|
||||||
@ -2202,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 spk_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
|
||||||
if (ret < 0)
|
param_volume = evhttp_find_header(hreq->query, "volume");
|
||||||
return HTTP_BADREQUEST;
|
if (param_volume)
|
||||||
|
{
|
||||||
|
ret = safe_atoi32(param_volume, &volume);
|
||||||
|
if (ret < 0)
|
||||||
|
return HTTP_BADREQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
if (volume < 0 || volume > 100)
|
param_step = evhttp_find_header(hreq->query, "step");
|
||||||
return HTTP_BADREQUEST;
|
if (param_step)
|
||||||
|
{
|
||||||
|
ret = safe_atoi32(param_step, &step);
|
||||||
|
if (ret < 0)
|
||||||
|
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)
|
||||||
return HTTP_BADREQUEST;
|
{
|
||||||
|
DPRINTF(E_LOG, L_WEB, "Invalid value for parameter 'output_id'. Output id must be an integer (output_id='%s').\n", param);
|
||||||
ret = player_volume_setabs_speaker(output_id, volume);
|
return HTTP_BADREQUEST;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user