Index: app.c =================================================================== --- app.c (revision 38802) +++ app.c (working copy) @@ -366,14 +366,17 @@ 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; + if (stop) blen += strlen(stop); if (pause) @@ -411,9 +414,18 @@ 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 %d 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 %d\n",offset); + ast_seekstream(chan->stream, offset, SEEK_SET); + offset = 0; }; res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms); } @@ -452,6 +464,17 @@ 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 */ + ast_stopstream(chan); return res; Index: apps/app_controlplayback.c =================================================================== --- apps/app_controlplayback.c (revision 38802) +++ apps/app_controlplayback.c (working copy) @@ -62,9 +62,12 @@ " 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" +" 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"; LOCAL_USER_DECL; @@ -77,6 +80,8 @@ { int res = 0, priority_jump = 0; int skipms = 0; + long offsetms = 0; + char offsetbuf[20]; struct localuser *u; char *tmp; int argc; @@ -128,9 +133,12 @@ if (argv[options]) { if (strchr(argv[options], 'j')) priority_jump = 1; + if ((tmp = strchr(argv[options], 'o'))) { + offsetms = atol(tmp+1); + } } - 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)) { @@ -149,6 +157,10 @@ pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS"); } + snprintf( offsetbuf, sizeof(offsetbuf), "%d", offsetms); + offsetbuf[sizeof(offsetbuf)-1] = '\0'; + pbx_builtin_setvar_helper(chan, "CPLAYBACKOFFSET", offsetbuf); + LOCAL_USER_REMOVE(u); return res; Index: apps/app_voicemail.c =================================================================== --- apps/app_voicemail.c (revision 38802) +++ apps/app_voicemail.c (working copy) @@ -3656,7 +3656,7 @@ 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, char *category) Index: include/asterisk/app.h =================================================================== --- include/asterisk/app.h (revision 38802) +++ include/asterisk/app.h (working copy) @@ -162,7 +162,7 @@ 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); +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); Index: res/res_agi.c =================================================================== --- res/res_agi.c (revision 38802) +++ res/res_agi.c (working copy) @@ -532,7 +532,7 @@ 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);