From 7f603b262e29ba9aa7cd52cf8f67c90e8af5f176 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Sat, 7 Apr 2018 09:23:20 +0300 Subject: [PATCH] recording-daemon: added possibility to store audio streams to database - added new column 'stream mediumblob' to 'recording_streams' table for audio streams - added new option 'output-storage' with values 'file' (= default), 'db' or 'both' --- recording-daemon/db.c | 57 ++++++++++++++++++++++++++++++++++++++--- recording-daemon/main.c | 2 ++ recording-daemon/main.h | 1 + 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/recording-daemon/db.c b/recording-daemon/db.c index 24e55c9cd..5a50ae5af 100644 --- a/recording-daemon/db.c +++ b/recording-daemon/db.c @@ -85,7 +85,7 @@ static int check_conn() { "end_timestamp = ?, status = 'completed' where id = ?")) goto err; if (prep(&stm_close_stream, "update recording_streams set " \ - "end_timestamp = ? where id = ?")) + "end_timestamp = ?, stream = ? where id = ?")) goto err; if (prep(&stm_config_stream, "update recording_streams set channels = ?, sample_rate = ? where id = ?")) goto err; @@ -295,6 +295,7 @@ void db_close_call(metafile_t *mf) { execute_wrap(&stm_close_call, b, NULL); } + void db_close_stream(output_t *op) { if (check_conn()) return; @@ -303,11 +304,61 @@ void db_close_stream(output_t *op) { double now = now_double(); - MYSQL_BIND b[2]; + str stream; + char *filename = 0; + MYSQL_BIND b[3]; + stream.s = 0; + stream.len = 0; + + if (!strcmp(output_storage, "db") || !strcmp(output_storage, "both")) { + filename = malloc(strlen(op->full_filename) + + strlen(op->file_format) + 2); + if (!filename) { + ilog(LOG_ERR, "Failed to allocate memory for filename"); + if (!strcmp(output_storage, "both")) + goto file; + return; + } + strcpy(filename, op->full_filename); + strcat(filename, "."); + strcat(filename, op->file_format); + FILE *f = fopen(filename, "rb"); + if (!f) { + ilog(LOG_ERR, "Failed to open file: %s", filename); + if (!strcmp(output_storage, "both")) + goto file; + free(filename); + return; + } + fseek(f, 0, SEEK_END); + stream.len = ftell(f); + fseek(f, 0, SEEK_SET); + stream.s = malloc(stream.len); + if (stream.s) { + size_t count = fread(stream.s, 1, stream.len, f); + if (count != stream.len) { + ilog(LOG_ERR, "Failed to read from stream"); + if (!strcmp(output_storage, "both")) + goto file; + free(filename); + return; + } + } + fclose(f); + } + +file: my_d(&b[0], &now); - my_ull(&b[1], &op->db_id); + my_str(&b[1], &stream); + my_ull(&b[2], &op->db_id); execute_wrap(&stm_close_stream, b, NULL); + + if (stream.s) + free(stream.s); + if (!strcmp(output_storage, "db")) + remove(filename); + free(filename); } void db_config_stream(output_t *op) { diff --git a/recording-daemon/main.c b/recording-daemon/main.c index ef5b2ff5e..732ae5eb5 100644 --- a/recording-daemon/main.c +++ b/recording-daemon/main.c @@ -29,6 +29,7 @@ int ktable = 0; int num_threads = 8; +const char *output_storage = "file"; const char *spool_dir = "/var/spool/rtpengine"; const char *output_dir = "/var/lib/rtpengine-recording"; static const char *output_format = "wav"; @@ -138,6 +139,7 @@ static void options(int *argc, char ***argv) { { "table", 't', 0, G_OPTION_ARG_INT, &ktable, "Kernel table rtpengine uses", "INT" }, { "spool-dir", 0, 0, G_OPTION_ARG_STRING, &spool_dir, "Directory containing rtpengine metadata files", "PATH" }, { "num-threads", 0, 0, G_OPTION_ARG_INT, &num_threads, "Number of worker threads", "INT" }, + { "output-storage", 0, 0, G_OPTION_ARG_STRING, &output_storage,"Where to store audio streams", "file|db|both" }, { "output-dir", 0, 0, G_OPTION_ARG_STRING, &output_dir, "Where to write media files to", "PATH" }, { "output-format", 0, 0, G_OPTION_ARG_STRING, &output_format, "Write audio files of this type", "wav|mp3|none" }, { "resample-to", 0, 0, G_OPTION_ARG_INT, &resample_audio,"Resample all output audio", "INT" }, diff --git a/recording-daemon/main.h b/recording-daemon/main.h index f11b39105..cbfeb17c4 100644 --- a/recording-daemon/main.h +++ b/recording-daemon/main.h @@ -7,6 +7,7 @@ extern int ktable; extern int num_threads; +extern const char *output_storage; extern const char *spool_dir; extern const char *output_dir; extern int output_mixed;