Add a "run_this_when_volume_is_set" facility to call a program when the volume is set. The AirPlay volume is passed.
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
@@ -454,6 +455,53 @@ uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void command_set_volume(double volume) {
|
||||
if (config.cmd_set_volume) {
|
||||
/*Spawn a child to run the program.*/
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) { /* child process */
|
||||
size_t command_buffer_size = strlen(config.cmd_set_volume)+32;
|
||||
char* command_buffer = (char*)malloc(command_buffer_size);
|
||||
if (command_buffer==NULL) {
|
||||
inform("Couldn't allocate memory for set_volume argument string");
|
||||
} else {
|
||||
memset(command_buffer,0,command_buffer_size);
|
||||
sprintf(command_buffer, "%s%f", config.cmd_set_volume,volume);
|
||||
// debug(1,"command_buffer is \"%s\".",command_buffer);
|
||||
int argC;
|
||||
char **argV;
|
||||
// debug(1,"set_volume command found.");
|
||||
if (poptParseArgvString(command_buffer, &argC, (const char ***)&argV) !=
|
||||
0) {
|
||||
// note that argV should be free()'d after use, but we expect this fork to exit
|
||||
// eventually.
|
||||
warn("Can't decipher on-set-volume command arguments \"%s\".",command_buffer);
|
||||
free(argV);
|
||||
free(command_buffer);
|
||||
} else {
|
||||
free(command_buffer);
|
||||
// debug(1,"Executing on-set-volume command %s with %d arguments.",argV[0],argC);
|
||||
execv(argV[0], argV);
|
||||
warn("Execution of on-set-volume command \"%s\" failed to start", config.cmd_set_volume);
|
||||
// debug(1, "Error executing on-set-volume command %s", config.cmd_set_volume);
|
||||
exit(127); /* only if execv fails */
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (config.cmd_blocking) { /* pid!=0 means parent process and if blocking is true, wait for
|
||||
process to finish */
|
||||
pid_t rc = waitpid(pid, 0, 0); /* wait for child to exit */
|
||||
if (rc != pid) {
|
||||
warn("Execution of on-set-volume command returned an error.");
|
||||
debug(1, "on-set-volume command %s finished with error %d", config.cmd_set_volume,errno);
|
||||
}
|
||||
}
|
||||
// debug(1,"Continue after on-set-volume command");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void command_start(void) {
|
||||
if (config.cmd_start) {
|
||||
/*Spawn a child to run the program.*/
|
||||
|
||||
@@ -113,7 +113,7 @@ typedef struct {
|
||||
int logOutputLevel; // log output level
|
||||
int statistics_requested, use_negotiated_latencies;
|
||||
enum playback_mode_type playback_mode;
|
||||
char *cmd_start, *cmd_stop;
|
||||
char *cmd_start, *cmd_stop, *cmd_set_volume;
|
||||
int cmd_blocking;
|
||||
double tolerance; // allow this much drift before attempting to correct it
|
||||
enum stuffing_type packet_stuffing;
|
||||
@@ -203,6 +203,7 @@ config_t config_file_stuff;
|
||||
|
||||
void command_start(void);
|
||||
void command_stop(void);
|
||||
void command_set_volume(double volume);
|
||||
|
||||
void shairport_shutdown();
|
||||
// void shairport_startup_complete(void);
|
||||
|
||||
@@ -2109,6 +2109,8 @@ void player_volume(double airplay_volume, rtsp_conn_info* conn) {
|
||||
// Thus, we ask our vol2attn function for an appropriate dB between -96.3 and 0 dB and translate
|
||||
// it back to a number.
|
||||
|
||||
command_set_volume(airplay_volume);
|
||||
|
||||
int32_t hw_min_db, hw_max_db, hw_range_db, range_to_use, min_db,
|
||||
max_db; // hw_range_db is a flag; if 0 means no mixer
|
||||
|
||||
|
||||
@@ -499,6 +499,10 @@ int parse_options(int argc, char **argv) {
|
||||
config.volume_max_db_set = 1;
|
||||
}
|
||||
|
||||
if (config_lookup_string(config.cfg, "general.run_this_when_volume_is_set", &str)) {
|
||||
config.cmd_set_volume = (char *)str;
|
||||
}
|
||||
|
||||
/* Get the playback_mode setting */
|
||||
if (config_lookup_string(config.cfg, "general.playback_mode", &str)) {
|
||||
if (strcasecmp(str, "stereo") == 0)
|
||||
|
||||
Reference in New Issue
Block a user