diff --git a/src/include/switch_core.h b/src/include/switch_core.h index a07ea36a1e..3ec8130d98 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1941,6 +1941,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_set_string(_In_ switch_file_han */ SWITCH_DECLARE(switch_status_t) switch_core_file_get_string(_In_ switch_file_handle_t *fh, switch_audio_col_t col, const char **string); +/*! + \brief Pre close an open file handle, then can get file size etc., no more wirte to the file + \param fh the file handle to close + \return SWITCH_STATUS_SUCCESS if the file handle was pre closed +*/ +SWITCH_DECLARE(switch_status_t) switch_core_file_pre_close(_In_ switch_file_handle_t *fh); /*! \brief Close an open file handle diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index da6d6be91e..902c5c4c98 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -298,6 +298,8 @@ struct switch_file_interface { switch_status_t (*file_set_string) (switch_file_handle_t *fh, switch_audio_col_t col, const char *string); /*! function to get meta data */ switch_status_t (*file_get_string) (switch_file_handle_t *fh, switch_audio_col_t col, const char **string); + /*! function to pre close the file to read params */ + switch_status_t (*file_pre_close) (switch_file_handle_t *fh); /*! function to control the underlying tech of the file */ switch_status_t (*file_command) (switch_file_handle_t *fh, switch_file_command_t command); /*! list of supported file extensions */ diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 652836b17c..a44d97dafe 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -583,12 +583,22 @@ typedef enum { typedef uint32_t switch_caller_profile_flag_t; typedef enum { + // flags matching libsndfile SWITCH_AUDIO_COL_STR_TITLE = 0x01, SWITCH_AUDIO_COL_STR_COPYRIGHT = 0x02, SWITCH_AUDIO_COL_STR_SOFTWARE = 0x03, SWITCH_AUDIO_COL_STR_ARTIST = 0x04, SWITCH_AUDIO_COL_STR_COMMENT = 0x05, - SWITCH_AUDIO_COL_STR_DATE = 0x06 + SWITCH_AUDIO_COL_STR_DATE = 0x06, + SWITCH_AUDIO_COL_STR_ALBUM = 0x07, + SWITCH_AUDIO_COL_STR_LICENSE = 0x08, + SWITCH_AUDIO_COL_STR_TRACKNUMBER = 0x09, + SWITCH_AUDIO_COL_STR_GENRE = 0x10, + + // custom flags + SWITCH_AUDIO_COL_STR_FILE_SIZE = 0xF0, + SWITCH_AUDIO_COL_STR_FILE_TRIMMED = 0xF1, + SWITCH_AUDIO_COL_STR_FILE_TRIMMED_MS = 0xF2 } switch_audio_col_t; typedef enum { diff --git a/src/switch_core_file.c b/src/switch_core_file.c index f7cfd7b1c3..e2b71d19d1 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -36,6 +36,30 @@ #include #include "private/switch_core_pvt.h" + +static switch_status_t get_file_size(switch_file_handle_t *fh, const char **string) +{ + switch_status_t status; + switch_file_t *newfile; + switch_size_t size = 0; + + status = switch_file_open(&newfile, fh->spool_path ? fh->spool_path : fh->file_path, SWITCH_FOPEN_READ, SWITCH_FPROT_OS_DEFAULT, fh->memory_pool); + + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + + size = switch_file_get_size(newfile); + + if (size) { + *string = switch_core_sprintf(fh->memory_pool, "%" SWITCH_SIZE_T_FMT, size); + } + + status = switch_file_close(newfile); + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line, switch_file_handle_t *fh, const char *file_path, @@ -751,18 +775,32 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_set_string(switch_file_handle_t SWITCH_DECLARE(switch_status_t) switch_core_file_get_string(switch_file_handle_t *fh, switch_audio_col_t col, const char **string) { + switch_status_t status; + switch_assert(fh != NULL); switch_assert(fh->file_interface != NULL); - if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) { + if (!switch_test_flag(fh, SWITCH_FILE_OPEN) && col < SWITCH_AUDIO_COL_STR_FILE_SIZE) { return SWITCH_STATUS_FALSE; } if (!fh->file_interface->file_get_string) { + if (col == SWITCH_AUDIO_COL_STR_FILE_SIZE) { + return get_file_size(fh, string); + } + return SWITCH_STATUS_FALSE; } - return fh->file_interface->file_get_string(fh, col, string); + status = fh->file_interface->file_get_string(fh, col, string); + + if (status == SWITCH_STATUS_SUCCESS && string) return status; + + if (col == SWITCH_AUDIO_COL_STR_FILE_SIZE) { + return get_file_size(fh, string); + } + + return status; } SWITCH_DECLARE(switch_status_t) switch_core_file_truncate(switch_file_handle_t *fh, int64_t offset) @@ -825,17 +863,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_command(switch_file_handle_t *f return status; } - -SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) +SWITCH_DECLARE(switch_status_t) switch_core_file_pre_close(switch_file_handle_t *fh) { - switch_status_t status; + switch_status_t status = SWITCH_STATUS_SUCCESS; switch_assert(fh != NULL); - if (!fh->file_interface || !switch_test_flag(fh, SWITCH_FILE_OPEN)) { + if (!fh->file_interface) { return SWITCH_STATUS_FALSE; } + if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) { + return SWITCH_STATUS_SUCCESS; + } + if (fh->pre_buffer) { if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) { switch_size_t rlen, blen; @@ -859,7 +900,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) } switch_clear_flag_locked(fh, SWITCH_FILE_OPEN); - status = fh->file_interface->file_close(fh); + + if (fh->file_interface->file_pre_close) { + status = fh->file_interface->file_pre_close(fh); + } + + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (switch_test_flag(fh, SWITCH_FILE_OPEN)) { + status = switch_core_file_pre_close(fh); + } + + fh->file_interface->file_close(fh); if (fh->params) { switch_event_destroy(&fh->params);