[asterisk-commits] russell: trunk r68502 - in /trunk: apps/ include/asterisk/ main/ res/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Jun 8 14:02:47 MST 2007


Author: russell
Date: Fri Jun  8 16:02:46 2007
New Revision: 68502

URL: http://svn.digium.com/view/asterisk?view=rev&rev=68502
Log:
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)

Modified:
    trunk/apps/app_controlplayback.c
    trunk/apps/app_voicemail.c
    trunk/include/asterisk/app.h
    trunk/main/app.c
    trunk/res/res_agi.c

Modified: trunk/apps/app_controlplayback.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_controlplayback.c?view=diff&rev=68502&r1=68501&r2=68502
==============================================================================
--- trunk/apps/app_controlplayback.c (original)
+++ trunk/apps/app_controlplayback.c Fri Jun  8 16:02:46 2007
@@ -61,11 +61,29 @@
 "  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 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 @@
 		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 @@
 	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 @@
 		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 @@
 		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");
 				}
@@ -147,6 +169,9 @@
 		} else
 			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);
 

Modified: trunk/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_voicemail.c?view=diff&rev=68502&r1=68501&r2=68502
==============================================================================
--- trunk/apps/app_voicemail.c (original)
+++ trunk/apps/app_voicemail.c Fri Jun  8 16:02:46 2007
@@ -4363,7 +4363,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, const char *category)

Modified: trunk/include/asterisk/app.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/app.h?view=diff&rev=68502&r1=68501&r2=68502
==============================================================================
--- trunk/include/asterisk/app.h (original)
+++ trunk/include/asterisk/app.h Fri Jun  8 16:02:46 2007
@@ -163,8 +163,14 @@
 /*! 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);

Modified: trunk/main/app.c
URL: http://svn.digium.com/view/asterisk/trunk/main/app.c?view=diff&rev=68502&r1=68501&r2=68502
==============================================================================
--- trunk/main/app.c (original)
+++ trunk/main/app.c Fri Jun  8 16:02:46 2007
@@ -395,13 +395,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; /* XXX Assumes 8kHz */
 
 	if (stop)
 		blen += strlen(stop);
@@ -440,9 +444,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 %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);
 		}
@@ -481,6 +494,19 @@
 		if (stop && strchr(stop, res))
 			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);
 

Modified: trunk/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/trunk/res/res_agi.c?view=diff&rev=68502&r1=68501&r2=68502
==============================================================================
--- trunk/res/res_agi.c (original)
+++ trunk/res/res_agi.c Fri Jun  8 16:02:46 2007
@@ -551,7 +551,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);
 



More information about the asterisk-commits mailing list