diff --git a/daemon/cli.c b/daemon/cli.c
index 18d00408e..2f0d489a9 100644
--- a/daemon/cli.c
+++ b/daemon/cli.c
@@ -111,6 +111,7 @@ static void cli_incoming_tag_detdtmf(str *instr, struct cli_writer *cw, const cl
static void cli_incoming_media_list_files(str *instr, struct cli_writer *cw, const cli_handler_t *);
static void cli_incoming_media_list_dbs(str *instr, struct cli_writer *cw, const cli_handler_t *);
+static void cli_incoming_media_list_caches(str *instr, struct cli_writer *cw, const cli_handler_t *);
static void cli_incoming_media_reload_file(str *instr, struct cli_writer *cw, const cli_handler_t *);
static void cli_incoming_media_reload_files(str *instr, struct cli_writer *cw, const cli_handler_t *);
@@ -197,6 +198,7 @@ static const cli_handler_t cli_params_handlers[] = {
static const cli_handler_t cli_media_list_handlers[] = {
{ "files", cli_incoming_media_list_files, NULL },
{ "dbs", cli_incoming_media_list_dbs, NULL },
+ { "caches", cli_incoming_media_list_caches, NULL },
{ NULL, },
};
static const cli_handler_t cli_media_reload_handlers[] = {
@@ -1900,4 +1902,12 @@ static void cli_incoming_media_evict_dbs(str *instr, struct cli_writer *cw, cons
unsigned int num = media_player_evict_db_medias();
cw->cw_printf(cw, "%u DB media entries evicted\n", num);
}
+
+static void cli_incoming_media_list_caches(str *instr, struct cli_writer *cw, const cli_handler_t *handler) {
+ GQueue list = media_player_list_caches();
+ while (list.head) {
+ void *id = g_queue_pop_head(&list);
+ cw->cw_printf(cw, "%llu\n", (unsigned long long) GPOINTER_TO_UINT(id));
+ }
+}
#endif
diff --git a/daemon/media_player.c b/daemon/media_player.c
index dc874c216..8d7f0b400 100644
--- a/daemon/media_player.c
+++ b/daemon/media_player.c
@@ -2374,3 +2374,43 @@ GQueue media_player_list_dbs(void) {
#endif
return ret;
}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(DIR, closedir)
+
+typedef union {
+ GQueue *q;
+} iterate_db_cache_arg __attribute__((__transparent_union__));
+
+static void media_player_iterate_db_cache(void (*callback)(unsigned long long, iterate_db_cache_arg),
+ iterate_db_cache_arg arg)
+{
+#ifdef WITH_TRANSCODING
+ if (!rtpe_config.db_media_cache)
+ return;
+
+ g_autoptr(DIR) dir = opendir(rtpe_config.db_media_cache);
+ if (!dir) {
+ ilog(LOG_ERR, "Failed to open media cache directory: %s", strerror(errno));
+ return;
+ }
+
+ struct dirent *de;
+ while ((de = readdir(dir))) {
+ char *errp;
+ unsigned long long id = strtoull(de->d_name, &errp, 10);
+ if (!id || strcmp(errp, ".blob"))
+ continue;
+ callback(id, arg);
+ }
+#endif
+}
+
+static void media_player_add_to_queue(unsigned long long id, GQueue *q) {
+ g_queue_push_tail(q, GUINT_TO_POINTER(id));
+}
+
+GQueue media_player_list_caches(void) {
+ GQueue ret = G_QUEUE_INIT;
+ media_player_iterate_db_cache(media_player_add_to_queue, &ret);
+ return ret;
+}
diff --git a/include/media_player.h b/include/media_player.h
index da0e28b07..ab6a68ddb 100644
--- a/include/media_player.h
+++ b/include/media_player.h
@@ -163,6 +163,7 @@ bool media_player_evict_db_media(unsigned long long);
unsigned int media_player_evict_db_medias(void);
str_q media_player_list_files(void);
GQueue media_player_list_dbs(void);
+GQueue media_player_list_caches(void);
struct send_timer *send_timer_new(struct packet_stream *);
void send_timer_push(struct send_timer *, struct codec_packet *);
diff --git a/utils/rtpengine-ctl b/utils/rtpengine-ctl
index 2371ad201..92c48a088 100755
--- a/utils/rtpengine-ctl
+++ b/utils/rtpengine-ctl
@@ -167,6 +167,7 @@ sub showusage {
print " list