diff --git a/daemon/main.c b/daemon/main.c index a0e2c9a45..3dc281343 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -678,6 +678,7 @@ static void options(int *argc, char ***argv, GHashTable *templates) { { "preload-db-media",0,0,G_OPTION_ARG_STRING_ARRAY,&rtpe_config.preload_db_media,"Preload media from database for playback into memory","INT"}, { "db-media-reload",0,0,G_OPTION_ARG_INT, &rtpe_config.db_refresh,"Reload preloaded media from DB at a certain interval","SECONDS"}, { "db-media-cache",0,0, G_OPTION_ARG_FILENAME, &rtpe_config.db_media_cache,"Directory to store media loaded from database","PATH"}, + { "preload-db-cache",0,0,G_OPTION_ARG_STRING_ARRAY,&rtpe_config.preload_db_cache,"Preload media from database for playback into file cache","INT"}, { "audio-buffer-length",0,0, G_OPTION_ARG_INT,&rtpe_config.audio_buffer_length,"Length in milliseconds of audio buffer","INT"}, { "audio-buffer-delay",0,0, G_OPTION_ARG_INT,&rtpe_config.audio_buffer_delay,"Initial delay in milliseconds for buffered audio","INT"}, { "audio-player",0,0, G_OPTION_ARG_STRING, &use_audio_player, "When to enable the internal audio player","on-demand|play-media|transcoding|always"}, @@ -1491,9 +1492,14 @@ static void create_everything(void) { if (!media_player_preload_db(rtpe_config.preload_db_media)) die("Failed to preload media from database"); - if (rtpe_config.db_media_cache) + if (rtpe_config.db_media_cache) { if (g_mkdir_with_parents(rtpe_config.db_media_cache, 0700)) die("Failed to create cache directory for media loaded from DB: %s", strerror(errno)); + + if (!media_player_preload_cache(rtpe_config.preload_db_cache)) + die("Failed to preload media from database into cache"); + + } } diff --git a/daemon/media_player.c b/daemon/media_player.c index ee162522f..2197f8d00 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -1772,6 +1772,9 @@ static void media_player_add_cache_file(const char *s, size_t len, unsigned long } } +static str dummy_dup(const char *s, size_t l) { + return STR_NULL; +} static const char *media_player_get_db_id(str *out, unsigned long long id, str (*dup_fn)(const char *, size_t)) { @@ -1826,9 +1829,9 @@ success:; err: if (query) - ilog(LOG_ERR, "Failed to start media playback from database (used query '%s'): %s", query, err); + ilog(LOG_ERR, "Failed to read media from database (used query '%s'): %s", query, err); else - ilog(LOG_ERR, "Failed to start media playback from database: %s", err); + ilog(LOG_ERR, "Failed to read media from database: %s", err); return err; } @@ -2439,3 +2442,30 @@ unsigned int media_player_evict_caches(void) { media_player_iterate_db_cache(media_player_evict_caches_all, &ret); return ret; } + +bool media_player_preload_cache(char **ids) { +#ifdef WITH_TRANSCODING + if (!ids || !ids[0]) + return true; + + for (char **idp = ids; *idp; idp++) { + char *id_s = *idp; + + char *endp = NULL; + unsigned long long id = strtoull(id_s, &endp, 0); + if (id == 0 || id == ULLONG_MAX || (endp && *endp != '\0')) { + ilog(LOG_CRIT, "Invalid DB ID string number: '%s'", id_s); + return false; + } + + ilog(LOG_DEBUG, "Reading media ID %llu from DB for caching", id); + + str out; + const char *err = media_player_get_db_id(&out, id, dummy_dup); + if (err) + return false; // error has been logged already + } +#endif + + return true; +} diff --git a/docs/rtpengine.md b/docs/rtpengine.md index 52f86569f..173221679 100644 --- a/docs/rtpengine.md +++ b/docs/rtpengine.md @@ -1199,6 +1199,11 @@ call to inject-DTMF won't be sent to __\-\-dtmf-log-dest=__ or __\-\-listen-tcp- then *rtpengine* will create the cache file for the next time the same media is requested. +- __\-\-preload-db-cache=__*INT* + + Similar to __preload-db-media__ but populates the filesystem-backed cache + instead of storing the media in memory. + - __\-\-audio-buffer-length=__*INT* Set the buffer length used by the audio player (see below) in milliseconds. The diff --git a/etc/rtpengine.conf b/etc/rtpengine.conf index bd5a9575f..2b6ae711b 100644 --- a/etc/rtpengine.conf +++ b/etc/rtpengine.conf @@ -170,6 +170,7 @@ recording-method = proc # preload-db-media = 1; 2; 3; 4; on-demand # db-media-reload = 3600 # db-media-cache = /var/cache/rtpengine +# preload-db-cache = 1; 2; 3; 4 # signalling templates (see key `templates` above) [templates] diff --git a/include/main.h b/include/main.h index e12715ebc..6671f368f 100644 --- a/include/main.h +++ b/include/main.h @@ -187,6 +187,7 @@ enum endpoint_learning { X(https_ifs) \ X(preload_media_files) \ X(preload_db_media) \ + X(preload_db_cache) \ // these are not automatically included in rtpe_config due to different types #define RTPE_CONFIG_ENUM_PARAMS \ diff --git a/include/media_player.h b/include/media_player.h index a0990ae23..56bf115e7 100644 --- a/include/media_player.h +++ b/include/media_player.h @@ -166,6 +166,7 @@ GQueue media_player_list_dbs(void); GQueue media_player_list_caches(void); bool media_player_evict_cache(unsigned long long); unsigned int media_player_evict_caches(void); +bool media_player_preload_cache(char **); struct send_timer *send_timer_new(struct packet_stream *); void send_timer_push(struct send_timer *, struct codec_packet *);