Add ControlPlayback manager action

This patch adds the capability for asynchronous manipulation of audio being
played back to a channel though a new AMI action "ControlPlayback". The
ControlPlayback action supports a number of operations, the availability of
which depend on the application being used to send audio to the channel.
When the audio playback was initiated using the ControlPlayback application
or CONTROL STREAM FILE AGI command, the audio can be paused, stopped,
restarted, reversed, or skipped forward. When initiated by other mechanisms
(such as the Playback application), the audio can be stopped, reversed, or
skipped forward.

Review: https://reviewboard.asterisk.org/r/2265/

(closes issue ASTERISK-20882)
Reported by: mjordan



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@379830 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Matthew Jordan
2013-01-22 15:16:20 +00:00
parent 985ea8b2c9
commit 7d9871b394
10 changed files with 392 additions and 53 deletions

View File

@@ -1004,24 +1004,37 @@ static int control_streamfile(struct ast_channel *chan,
}
/* We go at next loop if we got the restart char */
if (restart && strchr(restart, res)) {
if ((restart && strchr(restart, res)) || res == AST_CONTROL_STREAM_RESTART) {
ast_debug(1, "we'll restart the stream here at next loop\n");
pause_restart_point = 0;
ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
"Control: %s\r\n",
ast_channel_name(chan),
"Restart");
continue;
}
if (suspend && strchr(suspend, res)) {
if ((suspend && strchr(suspend, res)) || res == AST_CONTROL_STREAM_SUSPEND) {
pause_restart_point = ast_tellstream(ast_channel_stream(chan));
ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
"Control: %s\r\n",
ast_channel_name(chan),
"Pause");
for (;;) {
ast_stopstream(chan);
if (!(res = ast_waitfordigit(chan, 1000))) {
continue;
} else if (res == -1 || strchr(suspend, res) || (stop && strchr(stop, res))) {
} else if (res == -1 || (suspend && strchr(suspend, res)) || (stop && strchr(stop, res))
|| res == AST_CONTROL_STREAM_SUSPEND || res == AST_CONTROL_STREAM_STOP) {
break;
}
}
if (res == *suspend) {
if ((suspend && (res == *suspend)) || res == AST_CONTROL_STREAM_SUSPEND) {
res = 0;
ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
"Control: %s\r\n",
ast_channel_name(chan),
"Unpause");
continue;
}
}
@@ -1031,7 +1044,11 @@ static int control_streamfile(struct ast_channel *chan,
}
/* if we get one of our stop chars, return it to the calling function */
if (stop && strchr(stop, res)) {
if ((stop && strchr(stop, res)) || res == AST_CONTROL_STREAM_STOP) {
ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
"Control: %s\r\n",
ast_channel_name(chan),
"Stop");
break;
}
}
@@ -1050,11 +1067,6 @@ static int control_streamfile(struct ast_channel *chan,
*offsetms = offset / 8; /* samples --> ms ... XXX Assumes 8 kHz */
}
/* If we are returning a digit cast it as char */
if (res > 0 || ast_channel_stream(chan)) {
res = (char)res;
}
ast_stopstream(chan);
return res;