diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-06-08 21:02:46 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-06-08 21:02:46 +0000 |
commit | aae89d91628f6d3e2191d8578461a826f76fc846 (patch) | |
tree | 9980f4b3704ece77e3b9166bc57e0a5e33c971c6 | |
parent | 809ba665791d0a64139cdc2b588bac4a039b49ca (diff) |
Add an option for ControlPlayback to be able to start at an offset from
the beginning of the file. Also, add a channel variable that indicates
the location in the file where the Playback was stopped.
(closes issue #7655, patch from sharkey)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@68502 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | apps/app_controlplayback.c | 49 | ||||
-rw-r--r-- | apps/app_voicemail.c | 2 | ||||
-rw-r--r-- | include/asterisk/app.h | 10 | ||||
-rw-r--r-- | main/app.c | 32 | ||||
-rw-r--r-- | res/res_agi.c | 2 |
5 files changed, 76 insertions, 19 deletions
diff --git a/apps/app_controlplayback.c b/apps/app_controlplayback.c index 8a5a845cd..73a800479 100644 --- a/apps/app_controlplayback.c +++ b/apps/app_controlplayback.c @@ -61,11 +61,29 @@ static const char *descrip = " pause - Pause playback when this DTMF digit is received.\n" " restart - Restart playback when this DTMF digit is received.\n" "Options:\n" -" j - Jump to priority n+101 if the requested file is not found.\n" -"This application sets the following channel variable upon completion:\n" +" j - Jump to priority n+101 if the requested file is not found.\n" +" o(#) - Start at # ms from the beginning of the file.\n" +"This application sets the following channel variables upon completion:\n" " CPLAYBACKSTATUS - This variable contains the status of the attempt as a text\n" -" string, one of: SUCCESS | USERSTOPPED | ERROR\n"; - +" string, one of: SUCCESS | USERSTOPPED | ERROR\n" +" CPLAYBACKOFFSET - This contains the offset in ms into the file where\n" +" playback was at when it stopped. -1 is end of file.\n"; + +enum { + OPT_JUMP = (1 << 0), + OPT_OFFSET = (1 << 1), +}; + +enum { + OPT_ARG_OFFSET = 0, + /* must stay as the last entry ... */ + OPT_ARG_ARRAY_LEN, +}; + +AST_APP_OPTIONS(cpb_opts, BEGIN_OPTIONS + AST_APP_OPTION('j', OPT_JUMP), + AST_APP_OPTION_ARG('o', OPT_OFFSET, OPT_ARG_OFFSET), +END_OPTIONS ); static int is_on_phonepad(char key) { @@ -74,12 +92,14 @@ static int is_on_phonepad(char key) static int controlplayback_exec(struct ast_channel *chan, void *data) { - int res = 0, priority_jump = 0; + int res = 0; int skipms = 0; + long offsetms = 0; + char offsetbuf[20]; struct ast_module_user *u; char *tmp; int argc; - char *argv[8]; + char *argv[8] = { NULL, }; enum arg_ids { arg_file = 0, arg_skip = 1, @@ -90,7 +110,9 @@ static int controlplayback_exec(struct ast_channel *chan, void *data) arg_restart = 6, options = 7, }; - + struct ast_flags opts = { 0, }; + char *opt_args[OPT_ARG_ARRAY_LEN]; + if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n"); return -1; @@ -99,7 +121,6 @@ static int controlplayback_exec(struct ast_channel *chan, void *data) u = ast_module_user_add(chan); tmp = ast_strdupa(data); - memset(argv, 0, sizeof(argv)); argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0])); @@ -125,11 +146,12 @@ static int controlplayback_exec(struct ast_channel *chan, void *data) argv[arg_restart] = NULL; if (argv[options]) { - if (strchr(argv[options], 'j')) - priority_jump = 1; + ast_app_parse_options(cpb_opts, &opts, opt_args, argv[options]); + if (ast_test_flag(&opts, OPT_OFFSET)) + offsetms = atol(opt_args[OPT_ARG_OFFSET]); } - res = ast_control_streamfile(chan, argv[arg_file], argv[arg_fwd], argv[arg_rev], argv[arg_stop], argv[arg_pause], argv[arg_restart], skipms); + res = ast_control_streamfile(chan, argv[arg_file], argv[arg_fwd], argv[arg_rev], argv[arg_stop], argv[arg_pause], argv[arg_restart], skipms, &offsetms); /* If we stopped on one of our stop keys, return 0 */ if (argv[arg_stop] && strchr(argv[arg_stop], res)) { @@ -137,7 +159,7 @@ static int controlplayback_exec(struct ast_channel *chan, void *data) pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED"); } else { if (res < 0) { - if (priority_jump || ast_opt_priority_jumping) { + if (ast_test_flag(&opts, OPT_JUMP) || ast_opt_priority_jumping) { if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { ast_log(LOG_WARNING, "ControlPlayback tried to jump to priority n+101 as requested, but priority didn't exist\n"); } @@ -148,6 +170,9 @@ static int controlplayback_exec(struct ast_channel *chan, void *data) pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS"); } + snprintf(offsetbuf, sizeof(offsetbuf), "%ld", offsetms); + pbx_builtin_setvar_helper(chan, "CPLAYBACKOFFSET", offsetbuf); + ast_module_user_remove(u); return res; diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 14a99d8ba..01f07d722 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -4363,7 +4363,7 @@ static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file static int wait_file(struct ast_channel *chan, struct vm_state *vms, char *file) { - return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms); + return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms, NULL); } static int play_message_category(struct ast_channel *chan, const char *category) diff --git a/include/asterisk/app.h b/include/asterisk/app.h index c60219b85..77e77bfb0 100644 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -163,8 +163,14 @@ int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const ch /*! Stream a filename (or file descriptor) as a generator. */ int ast_linear_stream(struct ast_channel *chan, const char *filename, int fd, int allowoverride); -/*! Stream a file with fast forward, pause, reverse, restart. */ -int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms); +/*! + * \brief Stream a file with fast forward, pause, reverse, restart. + * \param offsetms Before calling this function, set this to be the number + * of ms to start from the beginning of the file. When the function + * returns, it will be the number of ms from the beginning where the + * playback stopped. Pass NULL if you don't care. + */ +int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms, long *offsetms); /*! Play a stream and wait for a digit, returning the digit that was pressed */ int ast_play_and_wait(struct ast_channel *chan, const char *fn); diff --git a/main/app.c b/main/app.c index b3fd264f1..22a29218e 100644 --- a/main/app.c +++ b/main/app.c @@ -395,13 +395,17 @@ int ast_linear_stream(struct ast_channel *chan, const char *filename, int fd, in int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, - const char *restart, int skipms) + const char *restart, int skipms, long *offsetms) { char *breaks = NULL; char *end = NULL; int blen = 2; int res; long pause_restart_point = 0; + long offset = 0; + + if (offsetms) + offset = *offsetms * 8; /* XXX Assumes 8kHz */ if (stop) blen += strlen(stop); @@ -440,9 +444,18 @@ int ast_control_streamfile(struct ast_channel *chan, const char *file, ast_seekstream(chan->stream, pause_restart_point, SEEK_SET); pause_restart_point = 0; } - else if (end) { - ast_seekstream(chan->stream, 0, SEEK_END); + else if (end || offset < 0) { + if (offset == -8) + offset = 0; + ast_verbose(VERBOSE_PREFIX_3 "ControlPlayback seek to offset %ld from end\n", offset); + + ast_seekstream(chan->stream, offset, SEEK_END); end = NULL; + offset = 0; + } else if (offset) { + ast_verbose(VERBOSE_PREFIX_3 "ControlPlayback seek to offset %ld\n", offset); + ast_seekstream(chan->stream, offset, SEEK_SET); + offset = 0; }; res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms); } @@ -482,6 +495,19 @@ int ast_control_streamfile(struct ast_channel *chan, const char *file, break; } + if (pause_restart_point) { + offset = pause_restart_point; + } else { + if (chan->stream) { + offset = ast_tellstream(chan->stream); + } else { + offset = -8; /* indicate end of file */ + } + } + + if (offsetms) + *offsetms = offset / 8; /* samples --> ms ... XXX Assumes 8 kHz */ + ast_stopstream(chan); return res; diff --git a/res/res_agi.c b/res/res_agi.c index 46a26a4c9..5d58de4b0 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -551,7 +551,7 @@ static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc else pause = NULL; - res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms); + res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms, NULL); fdprintf(agi->fd, "200 result=%d\n", res); |