diff --git a/src/mod/applications/mod_conference/conference_file.c b/src/mod/applications/mod_conference/conference_file.c index eceff51148..801aab168a 100644 --- a/src/mod/applications/mod_conference/conference_file.c +++ b/src/mod/applications/mod_conference/conference_file.c @@ -275,7 +275,16 @@ switch_status_t conference_file_play(conference_obj_t *conference, char *file, u const char *vol = switch_event_get_header(fnode->fh.params, "vol"); const char *position = switch_event_get_header(fnode->fh.params, "position"); const char *canvasstr = switch_event_get_header(fnode->fh.params, "canvas"); + const char *loopsstr = switch_event_get_header(fnode->fh.params, "loops"); int canvas_id = -1; + + if (loopsstr) { + fnode->loops = atoi(loopsstr); + + if (!strcasecmp(loopsstr, "inf") || !strcasecmp(loopsstr, "infinite")) { + fnode->loops = -1; + } + } if (canvasstr) { canvas_id = atoi(canvasstr) - 1; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index dbcb80299a..2d0b55bb1b 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -410,6 +410,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob } } else if (conference->fnode->type == NODE_TYPE_FILE) { switch_core_file_read(&conference->fnode->fh, file_frame, &file_sample_len); + if (conference->fnode->fh.vol) { switch_change_sln_volume_granular((void *)file_frame, (uint32_t)file_sample_len * conference->fnode->fh.channels, conference->fnode->fh.vol); @@ -420,7 +421,20 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob } if (file_sample_len <= 0) { - conference->fnode->done++; + if (conference->fnode->loops) { + if (--conference->fnode->loops < 0) { + conference->fnode->loops = -1; + } + + if (conference->fnode->loops) { + uint32_t pos = 0; + switch_core_file_seek(&conference->fnode->fh, &pos, 0, SEEK_SET); + } + } + + if (!conference->fnode->loops) { + conference->fnode->done++; + } } else { has_file_data = 1; } @@ -438,7 +452,20 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob conference_al_process(conference->async_fnode->al, file_frame, file_sample_len * 2, conference->async_fnode->fh.samplerate); } if (file_sample_len <= 0) { - conference->async_fnode->done++; + if (conference->async_fnode->loops) { + if (--conference->async_fnode->loops < 0) { + conference->async_fnode->loops = -1; + } + + if (conference->async_fnode->loops) { + uint32_t pos = 0; + switch_core_file_seek(&conference->async_fnode->fh, &pos, 0, SEEK_SET); + } + } + + if (!conference->async_fnode->loops) { + conference->async_fnode->done++; + } } else { if (has_file_data) { switch_size_t x; diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index 02503f6110..42bba3574b 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -386,6 +386,7 @@ typedef struct conference_file_node { int canvas_id; struct conference_obj *conference; char *res_id; + int loops; } conference_file_node_t; typedef enum {