res_musiconhold: Add new 'playlist' mode

Allow the list of files to be played to be provided explicitly in the
music class's configuration. The primary driver for this change is to
allow URLs to be used for MoH.

Change-Id: I9f43b80b43880980b18b2bee26ec09429d0b92fa
This commit is contained in:
Sean Bright
2019-09-18 07:56:05 -04:00
parent f2367e56c0
commit 966488ab52
5 changed files with 139 additions and 2 deletions

View File

@@ -1081,6 +1081,20 @@ static void moh_parse_options(struct ast_variable *var, struct mohclass *mohclas
ast_copy_string(mohclass->name, var->value, sizeof(mohclass->name));
} else if (!strcasecmp(var->name, "mode")) {
ast_copy_string(mohclass->mode, var->value, sizeof(mohclass->mode));
} else if (!strcasecmp(var->name, "entry")) {
if (ast_begins_with(var->value, "/") || ast_begins_with(var->value, "http://") || ast_begins_with(var->value, "https://")) {
char *dup = ast_strdup(var->value);
if (!dup) {
continue;
}
if (ast_begins_with(dup, "/") && strrchr(dup, '.')) {
ast_log(LOG_WARNING, "The playlist entry '%s' may include an extension, which could prevent it from playing.\n",
dup);
}
AST_VECTOR_APPEND(&mohclass->files, dup);
} else {
ast_log(LOG_ERROR, "Playlist entries must be a URL or absolute path, '%s' provided.\n", var->value);
}
} else if (!strcasecmp(var->name, "directory")) {
ast_copy_string(mohclass->dir, var->value, sizeof(mohclass->dir));
} else if (!strcasecmp(var->name, "application")) {
@@ -1130,6 +1144,8 @@ static void moh_parse_options(struct ast_variable *var, struct mohclass *mohclas
}
}
}
AST_VECTOR_COMPACT(&mohclass->files);
}
static int moh_scan_files(struct mohclass *class) {
@@ -1333,6 +1349,13 @@ static int _moh_register(struct mohclass *moh, int reload, int unref, const char
}
return -1;
}
} else if (!strcasecmp(moh->mode, "playlist")) {
if (!AST_VECTOR_SIZE(&moh->files)) {
if (unref) {
moh = mohclass_unref(moh, "unreffing potential new moh class (no playlist entries)");
}
return -1;
}
} else if (!strcasecmp(moh->mode, "mp3") || !strcasecmp(moh->mode, "mp3nb") ||
!strcasecmp(moh->mode, "quietmp3") || !strcasecmp(moh->mode, "quietmp3nb") ||
!strcasecmp(moh->mode, "httpmp3") || !strcasecmp(moh->mode, "custom")) {
@@ -1485,6 +1508,32 @@ static struct mohclass *_moh_class_malloc(const char *file, int line, const char
static struct ast_variable *load_realtime_musiconhold(const char *name)
{
struct ast_variable *var = ast_load_realtime("musiconhold", "name", name, SENTINEL);
if (var) {
const char *mode = ast_variable_find_in_list(var, "mode");
if (ast_strings_equal(mode, "playlist")) {
struct ast_variable *entries = ast_load_realtime("musiconhold_entry", "name", name, SENTINEL);
struct ast_variable *cur = entries;
size_t entry_count = 0;
for (; cur; cur = cur->next) {
if (!strcmp(cur->name, "entry")) {
struct ast_variable *dup = ast_variable_new(cur->name, cur->value, "");
if (dup) {
entry_count++;
ast_variable_list_append(&var, dup);
}
}
}
ast_variables_destroy(entries);
if (entry_count == 0) {
/* Behave as though this class doesn't exist */
ast_variables_destroy(var);
var = NULL;
}
}
}
if (!var) {
ast_log(LOG_WARNING,
"Music on Hold class '%s' not found in memory/database. "
@@ -1551,7 +1600,7 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
ast_variables_destroy(var);
if (ast_strlen_zero(mohclass->dir)) {
if (!strcasecmp(mohclass->mode, "custom")) {
if (!strcasecmp(mohclass->mode, "custom") || !strcasecmp(mohclass->mode, "playlist")) {
strcpy(mohclass->dir, "nodir");
} else {
ast_log(LOG_WARNING, "A directory must be specified for class '%s'!\n", mohclass->name);
@@ -1605,6 +1654,11 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
}
ast_set_flag(mohclass, MOH_RANDOMIZE);
}
} else if (!strcasecmp(mohclass->mode, "playlist")) {
if (!AST_VECTOR_SIZE(&mohclass->files)) {
mohclass = mohclass_unref(mohclass, "unreffing potential mohclass (no playlist entries)");
return -1;
}
} else if (!strcasecmp(mohclass->mode, "mp3") || !strcasecmp(mohclass->mode, "mp3nb") || !strcasecmp(mohclass->mode, "quietmp3") || !strcasecmp(mohclass->mode, "quietmp3nb") || !strcasecmp(mohclass->mode, "httpmp3") || !strcasecmp(mohclass->mode, "custom")) {
if (!strcasecmp(mohclass->mode, "custom"))
@@ -1846,7 +1900,7 @@ static int load_moh_classes(int reload)
ast_copy_string(class->name, cat, sizeof(class->name));
if (ast_strlen_zero(class->dir)) {
if (!strcasecmp(class->mode, "custom")) {
if (!strcasecmp(class->mode, "custom") || !strcasecmp(class->mode, "playlist")) {
strcpy(class->dir, "nodir");
} else {
ast_log(LOG_WARNING, "A directory must be specified for class '%s'!\n", class->name);