Example
No Format |
---|
POST /playbacks/1283791327846/control?operation=next |
Existing Operations
The existing operations will work as follows:
restart
- restarts the current media in the list.pause
- pauses the current media in the list.
- unpauses the current media in the list.unpause
reverse
- reverses the current media in the list. If that causes the media to reach the beginning of a sound file, it will do one of the two following actions:- If the previous media resource was a sound file, it will start playback of the previous media resource at an offset equal to the remaining jump not displaced in the existing sound file.
- If the previous media resource was not a sound file (and cannot be indexed), it will start playback at the start of that resource.
forward
- fast-forwards the current media in the list. if that causes the media to reach the end of a sound file, the sound file will complete and the next media resource will be started.- If the next media resource is a sound file, it will start playback of the next media resource at an offset equal to the remaining jump not displaced in the existing sound file.
- If the next media resource was not a sound file (and cannot be indexed), it will start playback at the start of that resource.
Configuration
No configuration should be needed.
Design/Implementation
Swagger Model updates
The channels
and bridges
resources will have their respective play
operations updated to allow multiple media
query parameters. The list is constructed in the order that the query parameters are presented.
Code Block | ||||
---|---|---|---|---|
| ||||
{ "name": "media", "description": "Media URIs to play.", "paramType": "query", "required": true, "allowMultiple": true, "dataType": "string" }, |
The playbacks
resource will have its control
operation updated with new options for the operation
query parameter.
Code Block | ||||
---|---|---|---|---|
| ||||
{ "name": "operation", "description": "Operation to perform on the playback.", "paramType": "query", "required": true, "allowMultiple": false, "dataType": "string", "allowableValues": { "valueType": "LIST", "values": [ "restart", "pause", "unpause", "reverse", "forward", "next", "prev" ] } } |
Core updates
- New control frames for
next
andprev
should be added:
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
AST_CONTROL_STREAM_STOP = 1000, /*!< Indicate to a channel in playback to stop the stream */ AST_CONTROL_STREAM_SUSPEND = 1001, /*!< Indicate to a channel in playback to suspend the stream */ AST_CONTROL_STREAM_RESTART = 1002, /*!< Indicate to a channel in playback to restart the stream */ AST_CONTROL_STREAM_REVERSE = 1003, /*!< Indicate to a channel in playback to rewind */ AST_CONTROL_STREAM_FORWARD = 1004, /*!< Indicate to a channel in playback to fast forward */ AST_CONTROL_STREAM_PREV = 1005, /*!< Indicate to a channel in playback to play the previous stream */ AST_CONTROL_STREAM_NEXT = 1006, /*!< Indicate to a channel in playback to play the next stream */ |
- Update
channel.c
to consume and ignore the two new frame types - Have
file.c
waitstream_core
handle the two new frame types. These should break out of the control loop and return the frame value.
Updatefile.c
ast_waitstream_fr_cb
to accept an arbitraryvoid *
. Updatewaitstream_core
and its variants that pass a callback to also pass avoid *
. Modifywaitstream_control
to pass thevoid *
to the callback. - Add a new function to
app.h
(because we don't have enough yet) calledast_control_streamfile_lang_w_cb
. Its usage should be somewhat obvious.
res_stasis_playback
In addition model and parameter changes that will ripple through the auto-generated HTTP server/resource bindings, the control of the playback will have to be modified in the following ways in res_stasis_playback
:
- The
stasis_app_playback
struct will have to specify a list of media resources to play, as well as the current/next file to be played. play_on_channel
will have to iterate over that list. Ifast_control_streamfile_lang
returns anext
orprev
result, it will have to handle it accordingly.- Use
ast_control_streamfile_lang_w_cb
instead ofast_control_streamfile_lang
. Pass thestasis_app_playback
object as thevoid *
. If therewind
orfast forward
operation indicates that we are at the beginning or end of a file, alter the next file to be played accordingly. - Implement handling for the control frame values corresponding to
PREV
andNEXT
.
- Use
- Add two new function handlers for
playback_opreation_cb
-playback_next
andplayback_prev
. Queue the control frames appropriately.
app_controlplayback
Currently, the ControlPlayback
dialplan application does not support playback of multiple files. As such, handling of the new feature should be defensive in nature only.
controlplayback_exec
should be modified to handle the return ofAST_CONTROL_STREAM_PREV
andAST_CONTROL_STREAM_NEXT
gracefully. Since the application does not currently handle multiple playbacks, it should simply return with the correctCPLAYBACKSTATUS
asPREVIOUS
orNEXT
, respectively.controlplayback_manager
should be updated to understand "prev" and "next" as valid control signals (as, who knows, you may want to use AMI to control a channel in ARI, if you're that crazy)
res_agi
The control stream file
AGI command does not support playback of multiple files. As such, handling of the new feature should be defensive in nature only.
handle_controlstreamfile
should be modified to handle the return ofAST_CONTROL_STREAM_PREV
andAST_CONTROL_STREAM_NEXT
gracefully. The result ofCPLAYBACKSTATUS
should mirror that ofapp_controlplayback
.
chan_iax2
- Explicitly specify that the two new control frames should not be passed over the wire.
func_frame_trace
- Do the frame trace dance
Testing
Test | Path | Purpose |
---|---|---|
control_prev | tests/apps/control_playback | Verify that sending a remote initiated prev command via AMI results in CPLAYBACKSTATUS being set to PREVIOUS . |
control_next | tests/apps/control_playback | Verify that sending a remote initiated next command via AMI results in CPLAYBACKSTATUS being set to NEXT . |
remote_prev | tests/apps/playback | Verify that sending a remote initiated prev command via AMI results in a test event indicating that the playback was broken |
remote_next | tests/apps/playback | Verify that sending a remote initiated next command via AMI results in a test event indicating that the playback was broken |
channels/playback/list | tests/rest_api | Verify that nominal playback of a list - with no user control - occurs in the expected fashion, and that each sound file in the list is played in the correct sequence |
channels/playback/list_forward | tests/rest_api | Verify that playback of a list where a user fast forwards plays through each sound file in sequence. Verify that unsupported skippable media is handled correctly. |
channels/playback/list_reverse | tests/rest_api | Verify that playback of a list where a user reverses through each sound file is handled correctly, including restarting already played media. Verify that media that cannot be reversed through is restarted as well. |
channels/playback/next | tests/rest_api | Verify that playback of a list supports skipping to the next media in the list, for multiple media resource types |
channels/playback/prev | tests/rest_api | Verify that playback of a list supports skipping to the previous media in the list, for multiple media resource types |
bridges/playback/list | tests/rest_api | Verify that nominal playback of a list - with no user control - occurs in the expected fashion, and that each sound file in the list is played in the correct sequence |
bridges/playback/list_forward | tests/rest_api | Verify that playback of a list where a user fast forwards plays through each sound file in sequence. Verify that unsupported skippable media is handled correctly. |
bridges/playback/list_reverse | tests/rest_api | Verify that playback of a list where a user reverses through each sound file is handled correctly, including restarting already played media. Verify that media that cannot be reversed through is restarted as well. |
bridges/playback/next | tests/rest_api | Verify that playback of a list supports skipping to the next media in the list, for multiple media resource types |
bridges/playback/prev | tests/rest_api | Verify that playback of a list supports skipping to the previous media in the list, for multiple media resource types |
Project Planning
The following are rough tasks that need to be done in order to complete this feature. These are meant to be guidelines, and should not necessarily be followed verbatim. Note that many of these are actually independent of each other, and can be worked out simultaneously. If you're interested in helping out with any of these tasks, please speak up on the asterisk-dev
mailing list!
The various phases are meant to be implemented as separately as possible to ease the process of peer review.
Phase One - Write Tests That Fail
In both of these cases, it is expected that the existing tests can be used as a basis.
Task | Description | Status |
---|---|---|
Write the dialplan application tests | Write tests that exercise the ControlPlayback and Playback applications with the new options. | |
Write the REST API tests | Write tests that update the existing options, as well as the new options. |
Phase Two - Update the core/non-ARI portions
Task | Description | Status |
---|---|---|
Add the control frame handling |
| |
Update non-ARI consumers | Update:
|
Phase Three - Update ARI
Task | Description | Status |
---|---|---|
Update the swagger model; generate bindings | What the task says. | |
Add operation handlers | Handle | |
Update play_on_channel to play multiple files |
| |
Update play_on_channel to handle reversing/forwarding between files in a list |
|