<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> 
<base href="https://wiki.asterisk.org/wiki" /> 
<title>Message Title</title>  
<style type="text/css">@media only screen and (max-device-width: 480px) {.mobile-only {
        width: auto !important;
        height: auto !important;
        overflow: visible !important;
        line-height: normal !important;
        font-size: inherit !important;
        mso-hide: all;
}

.desktop-only {
        display: none !important;
}

/* iPhone 3GS fix for unwanted 20px right margin */
body { min-width: 100% !important; padding: 0; margin: 0; }

#center-content-table { max-width: none; !important; }
#header-pattern-container { padding: 10px 10px 10px 10px !important; line-height: 20px !important; }
#header-avatar-image-container { padding-right: 8px !important; }
#email-content-container { padding: 0 !important; }
.mobile-expand { border-radius: 0 !important; border-left: 0 !important; border-right: 0 !important; padding-left: 26px !important;}
.mobile-resize-text { font-size: 16px !important; line-height: 22px !important; }
#page-title-pattern-header { font-size: 20px !important; line-height: 28px !important; }
#page-title-pattern-icon-image-container-cell { padding-top: 7px !important; }
#inline-user-pattern { display: block !important; }
#inline-user-pattern-avatar { padding-top: 3px !important; }
.contextual-area-pattern { border-bottom: 1px solid #ccc !important; padding: 15px 10px 0 10px !important;}
.users-involved-pattern-column-table { width: 100% !important;  }
.users-involved-pattern-avatar-table-cell { padding: 3px 5px 5px 0 !important; }
.users-involved-pattern-column-container { padding-right: 0 !important; }
.contextual-excerpt-pattern, #users-involved-pattern { border: 0 !important; }

/** Aui Typography upsized for mobile **/
#content-excerpt-pattern-container, #contextual-excerpt-pattern-text-container { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h1, #contextual-excerpt-pattern-text-container h1 { font-size: 24px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h2, #contextual-excerpt-pattern-text-container h2 { font-size: 20px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h3, #contextual-excerpt-pattern-text-container h3 { font-size: 18px !important; line-height: 24px !important; }
#content-excerpt-pattern-container h4, #contextual-excerpt-pattern-text-container h4 { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h5, #contextual-excerpt-pattern-text-container h5 { font-size: 14px !important; line-height: 20px !important; }
#content-excerpt-pattern-container h6, #contextual-excerpt-pattern-text-container h6 { font-size: 14px !important; line-height: 20px !important; }
.user-mention { line-height: 18px !important; }
/** Aui Typography end **/

/* Show appropriate footer logo on mobile, display links vertically */
#footer-pattern { padding: 15px 10px !important; }
#footer-pattern-logo-desktop-container { padding: 0 !important; }
#footer-pattern-logo-desktop { width: 0 !important; height: 0 !important; }
#footer-pattern-logo-mobile {
    padding-top: 10px !important;
    width: 30px !important;
    height: 27px !important;
    display: inline !important;
}
#footer-pattern-text {
    display: block !important;
}
#footer-pattern-links-container { line-height: 0 !important;}
.footer-pattern-links.mobile-resize-text,
.footer-pattern-links.mobile-resize-text,
#footer-pattern-text.mobile-resize-text,
#footer-pattern-links-container.no-footer-links {
    font-size: 14px !important;
    line-height: 20px !important;
}
.footer-link { display: block !important; }
#footer-pattern-links-container table { display: inline-block !important; float: none !important; }
#footer-pattern-links-container, #footer-pattern-text { text-align: center !important; }
#footer-pattern-links { padding-bottom: 5px !important; }

/** Team Calendar overrides, these should be removed when notifications are updated in Team Calendars. For now CSS
    overrides are being used because the structure of the content can't change without rereleasing the plugin */
.mail-calendar-container .day-header + table tr td:first-child {
    vertical-align: top !important;
    padding-top: 5px !important;
}}
@media (min-width: 900px) {#center-content-table { width: 900px; }}
@media all {#outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
/* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
body{-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;}
.ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
#background-table {margin:0; padding:0; width:100% !important; }
/* Needed to override highlighting on date and time links in iOS */
.grey a {color: #707070; text-decoration: none; }/* These styles are appended to the head element of a notification in order to prevent Apple Mail and similar
   clients from underlining the due dates with a blue hyperlink */
/* a lozenge outside an inline task should always be #333, lozenges inside an inline task should be
   colored according to their upcoming due dates, a completed task date lozenge or deleted task date
   lozenge should always be #707070 */
.date-time-lozenge a {color: #333333; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-upcoming a {color: #DF6F00; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-past a {color: #D04437; text-decoration: none; }
.inline-task-text-container.content-deleted-color .date-time-lozenge a,
.inline-task-text-container.checked .date-time-lozenge a {
    color: #707070; text-decoration: none;
}}
</style> 
</head>
<body>
<table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; background-color: #f5f5f5"> 
<tbody> 
<tr> 
<td id="header-pattern-container" style="padding: 0px; border-collapse: collapse; padding: 10px 20px"> 
<table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="header-avatar-image-container" valign="top" style="padding: 0px; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 9px"><a href="https://wiki.asterisk.org/wiki/display/~mjordan?src=email" style="color: #3b73af; text-decoration: none"><img id="header-avatar-image" class="image_fix" src="cid:avatar_0e82bef62b63030f8c50a1f164e27d2b" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" /></a></td>
<td id="header-text-container" valign="middle" style="padding: 0px; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">Matt Jordan <strong>edited</strong> a page</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<!-- End Header pattern --> 
<tr> 
<td id="email-content-container" style="padding: 0px; border-collapse: collapse; padding: 0 20px"> 
<table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-spacing: 0; border-collapse: separate"> 
<tbody> 
<tr> 
<td class="email-content-rounded-top mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; padding: 0 15px 0 16px; height: 15px; background-color: #fff; border-left: 1px solid #ccc; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px"> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table id="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container" valign="top" style="padding: 0px; border-collapse: collapse; width: 16px; vertical-align: top"> 
<table cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container-cell" style="padding: 0px; border-collapse: collapse; width: 16px; padding: 9px 8px 0px 0px; mso-text-raise: 5px; mso-line-height-rule: exactly"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="page icon" style="vertical-align: top;; color: #3b73af; text-decoration: none"><img style="vertical-align: top; display: block;" src="cid:page-icon" alt="page icon" title="page icon" height="16" width="16" border="0" /></a></td> 
</tr> 
</tbody> 
</table> </td>
<td style="vertical-align: top;; padding: 0px; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" id="page-title-pattern-header-container"><span id="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="Asterisk 14 Project - URI Media Playback" style="color: #3b73af; text-decoration: none">Asterisk 14 Project - URI Media Playback</a></span></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table class="content-excerpt-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td class="content-excerpt-pattern-container mobile-resize-text " style="padding: 0px; border-collapse: collapse; padding: 0 0 0 24px"> 
<div class="contentLayout2 diff-block-target"> 
<table width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody>
<tr class="columnLayout two-right-sidebar" data-layout="two-right-sidebar"> 
<td valign="top" class="cell normal" data-type="normal" style="padding: 0px; border-collapse: collapse"> 
<div class="innerCell"> 
<h1 id="Asterisk14Project-URIMediaPlayback-ProjectOverview" style="margin: 10px 0 0 0; margin-top: 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 0">Project Overview</h1> 
<p style="margin: 10px 0 0 0">One of the features that was discussed for the <a class="confluence-link unresolved" href="#" style="color: #3b73af; text-decoration: none">Asterisk 13 Projects</a> was the ability to playback media from a URI to a channel or bridge. See <a href="http://lists.digium.com/pipermail/asterisk-app-dev/2014-April/000425.html" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">http://lists.digium.com/pipermail/asterisk-app-dev/2014-April/000425.html</a> for more information.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">The conversation on the mailing list included both playback of a URI, as well as allowing for a unicast stream of media to be injected into a channel/bridge. At this time, that would be considered a separate project from this one.</p> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">The primary reason to add this feature is scalability. Allowing sounds to be placed on a remote HTTP server allows a cluster of Asterisk servers to access and pull down the sounds as needed. This is much easier for system administration, as the sounds don't have to all be pushed to individual Asterisk machines.</p> 
<h1 id="Asterisk14Project-URIMediaPlayback-RequirementsandSpecification" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Requirements and Specification</h1> 
<h3 id="Asterisk14Project-URIMediaPlayback-Extensions" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Extensions</h3> 
<p style="margin: 10px 0 0 0">Normally, Asterisk eschews usage of a file extension and instead picks the best extension available based on the native formats of the channel. In the case of a remote URI, this impractical as the URI represents a unique location to retrieve. The optimal file extension may not be present, and checking for each file extension may be costly.</p> 
<p style="margin: 10px 0 0 0">As such, the extension should be provided of the resource to retrieve; however, that may not result in a playable file depending on the channel formats. That is expected behaviour.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-URISchemes" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">URI Schemes</h3> 
<p style="margin: 10px 0 0 0">Playback of a remote URI should support both HTTP and HTTPS.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-Caching" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Caching</h3> 
<p style="margin: 10px 0 0 0">When a sound file has been retrieved, it should be cached on the local server. The management of the file should follow standard HTTP caching rules - for more information, see:</p> 
<p style="margin: 10px 0 0 0"> <a href="https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching</a> </p> 
<p style="margin: 10px 0 0 0">Generally, the rules should follow as such:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>If a <code style="font-family: monospace">Cache-Control</code> header is included, Asterisk will obey whatever rules it specifies. In particular, the following should be checked: 
<ul style="margin: 10px 0 0 0"> 
<li>If <code style="font-family: monospace">no-cache</code> is specified, the resulting file is marked as always 'dirty' - that is, we have to always retrieve a new resource from the server.</li> 
<li> <p style="margin: 10px 0 0 0; margin-top: 0">If <code style="font-family: monospace">no-store</code> is specified, Asterisk must attempt to purge the information before Asterisk shutdown and will always retrieve the resource from the server.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">We can't play back the file if we don't store it temporarily on disk. With file streams, we may not get notified when the playback completes, so it may be difficult to purge it out of the cache until Asterisk shuts down. If Asterisk does shut down however, we have an opportunity to flush it out of any semi-permanent storage we may have set up.</p> </td> 
</tr> 
</tbody> 
</table> </li> 
<li> <code style="font-family: monospace">s-maxage</code> or <code style="font-family: monospace">max-age</code>: mark the file as 'dirty' after so many seconds.</li> 
</ul> </li> 
<li>If the cached resource is 'dirty', look at the <code style="font-family: monospace">E-Tag</code> header on the remote resource and compare it to the local <code style="font-family: monospace">E-Tag</code>. If the two are different, retrieve the resource and update the entry in the cache. If the cached resource was retrieved with <code style="font-family: monospace">no-store</code>, then we always retrieve the full resource.</li> 
</ul> 
<p style="margin: 10px 0 0 0">CLI commands and an ARI resource should be provided to view the local cached files, the last time they were updated, and their originating URIs. Similar mechanisms should be provided to flush the entire cache.</p> 
</div> </td> 
<td valign="top" width="30%" class="cell aside" data-type="aside" style="padding: 0px; border-collapse: collapse"> 
<div class="innerCell"> 
<p style="margin: 10px 0 0 0; margin-top: 0"></p> 
<table class="diff-macro bodyless" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;margin: 5px 0; padding: 0; width: auto;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/toc.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Table of Contents</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">maxlevel</td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">3</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0"></p> 
</div> </td> 
</tr> 
</tbody>
</table> 
<table width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody>
<tr class="columnLayout single" data-layout="single"> 
<td valign="top" class="cell normal" data-type="normal" style="padding: 0px; border-collapse: collapse"> 
<div class="innerCell"> 
<h3 id="Asterisk14Project-URIMediaPlayback-Video" style="margin: 10px 0 0 0; margin-top: 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0; margin-top: 0">Video</h3> 
<p style="margin: 10px 0 0 0">Video is particularly difficult, as it typically requires multiple files (one video, one audio) to be useful. Container formats are beyond the scope of this project. To support video, remote playback of URIs should support a parallel form of extraction using the pipe <code style="font-family: monospace">|</code> character:</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Playback(http://myserver.com/monkeys.h264|http://myserver.com/monkeys.wav)</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">The behaviour of the files retrieved in such a fashion are as follows:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>Playback does not begin until all files are retrieved.</li> 
<li>Files are treated individually in the cache.</li> 
<li>While files with different names can be played back, the first file in the parallel list will be the actual "core sound file" played back. That is, assuming <code style="font-family: monospace">monkeys.h264</code> and <code style="font-family: monospace">monkeys.wav</code> already existed on the server, the <code style="font-family: monospace">Playback</code> operation would operate on sound file <code style="font-family: monospace">monkeys</code>, which would play both the audio and video files.</li> 
</ul> 
<h3 id="Asterisk14Project-URIMediaPlayback-Persistence" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Persistence</h3> 
<p style="margin: 10px 0 0 0">The cached entries and their metadata should be stored in the <code style="font-family: monospace">AstDB</code>. When Asterisk starts, the entries in the <code style="font-family: monospace">AstDB</code> should be verified to still be accurate (that is, that the local files still exist), and if so, the buckets for them re-created.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-PlaybackofaURI" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Playback of a URI</h3> 
<p style="margin: 10px 0 0 0">Playback of a URI can be done via any of the supported playback operations, through any API. This functionality should be a part of the Asterisk core, and available through any of the media playback operations.</p> 
<h5 id="Asterisk14Project-URIMediaPlayback-Dialplan" style="margin: 10px 0 0 0; color: #707070; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">Dialplan</h5> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Playback(http://myserver.com/monkeys.wav)</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Note that this can be combined with multiple URIs or sounds to form a playlist:</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Playback(http://myserver.com/monkeys.wav&http://myserver.com/weasels.wav)</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Since an <code style="font-family: monospace">&</code> is valid for a URI but is also used as a separator in dialplan, ampersands in a resource cannot be supported. If an ampersand is used in a URI (say, as part of a query), then the entire URI must be URI encoded.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">URIs in a resource can't be supported, as performing a URI decode on the URI cannot tell the difference between an <code style="font-family: monospace">&</code> in a resource and an <code style="font-family: monospace">&</code> in a query. That is:</p> <p style="margin: 10px 0 0 0"> <code style="font-family: monospace">http://myserver.com/media?sound=monkeys%26weasels&format=wav => http%3A%2F%2Fmyserver.com%2Fmedia%3Fsound%3dmonkeys%26weasels%26format%3Dwav</code> </p> <p style="margin: 10px 0 0 0">The latter cannot be decoded correctly as the <code style="font-family: monospace">&</code> that forms the query parameter cannot now be distinguished from the already URI encoded <code style="font-family: monospace">&</code> in the resource.</p> </td> 
</tr> 
</tbody> 
</table> 
<h5 id="Asterisk14Project-URIMediaPlayback-AGI" style="margin: 10px 0 0 0; color: #707070; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">AGI</h5> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">CONTROL STREAM FILE http://myserver.com/monkeys.wav "" 3000</pre> </td> 
</tr> 
</tbody> 
</table> 
<h5 id="Asterisk14Project-URIMediaPlayback-ARI" style="margin: 10px 0 0 0; color: #707070; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">ARI</h5> 
<p style="margin: 10px 0 0 0">Playback can be done on either a channel or a bridge. Since the resource being requested is a URI, it should be presented in the body of the request encoded using <code style="font-family: monospace">text/uri-list</code> (see <a href="https://www.ietf.org/rfc/rfc2483.txt" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">RFC 2483</a>). Note that we still need to provide a media query parameter that specifies the resource type to play - the actual 'entity' being played back is simply specified in the body of the request.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">http://localhost:8088/ari/channels/12345/play/p1?media=uri:list

Content-Type: text/uri-list
http://myserver.com/monkeys.wav</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">This format works nicely with simple playlists, as it can specify multiple files to retrieve. Note that these files should be played back sequentially as a playlist (which is not yet supported, but will need to be by the time we get here!)</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">http://localhost:8088/ari/channels/12345/play/p2?media=uri:list

Content-Type: text/uri-list
# Audio File One (I'm a comment and should be ignored)
http://myserver.com/monkeys.wav
# Comment comment comment
http://myserver.com/awesome-sound.wave</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Note that when the <code style="font-family: monospace">Content-Type</code> is <code style="font-family: monospace">text/uri-list</code>, the resource specified by the <code style="font-family: monospace">uri</code> media scheme is simply tossed away, as we can only have a single list of URIs. Note that this approach is somewhat limiting in that supporting multiples</p> 
<p style="margin: 10px 0 0 0">Another option is to provide the URIs in JSON. This would allow parallel playback of files for video support. Note that the JSON must follow the following schema:</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">http://localhost:8088/ari/channels/12345/play/p3

{
    "media": "playlist",
    "playlist": [
                  { "media_group": [
                              {
                                "scheme": "uri",
                                "resource": "http://myserver.com/monkeys.wav"
                              },
                              {
                                "scheme": "uri",
                                "resource": "http://myserver.com/monkeys.h264"
                              }
                            ]
                          }
                 { "media_group": [
                              { "scheme": "uri",
                                "resource": "http://myserver.com/awesome-sound.wav",
                              }
                            ]
                          }
                ]
}
    </pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">There's some obvious differences here:</p> 
<ol style="margin: 10px 0 0 0"> 
<li>The <code style="font-family: monospace">schema</code> type <strong>must</strong> be <code style="font-family: monospace">playlist</code>. We can't use a <code style="font-family: monospace">uri</code> schema type, as doing so would prevent combining <code style="font-family: monospace">URI</code> resources with other media resource types for playlists.</li> 
<li>The playlist must be strongly typed. Otherwise, swagger code generation turns into a nightmare. As such, that means a new strongly named body parameter must be used.</li> 
</ol> 
<h1 id="Asterisk14Project-URIMediaPlayback-Configuration" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Configuration</h1> 
<p style="margin: 10px 0 0 0">No configuration should be needed.</p> 
<h1 id="Asterisk14Project-URIMediaPlayback-Design" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Design</h1> 
<h2 id="Asterisk14Project-URIMediaPlayback-Core-media_cache" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 10px">Core - media_cache</h2> 
<p style="margin: 10px 0 0 0">This new file in the Asterisk core will provide the following:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>A universal API that the core and rest of Asterisk can do to query for something in the media cache.</li> 
<li>Caching of the bucket information in the <code style="font-family: monospace">AstDB</code> </li> 
<li>Informing the bucket implementation that a new bucket has been created during startup (or otherwise creating the buckets itself)</li> 
<li>CLI commands</li> 
</ul> 
<p style="margin: 10px 0 0 0">Implementations of a cache should implement the <code style="font-family: monospace">bucket</code> API for a particular scheme.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-API" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">API</h3> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">language</td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">cpp</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">/*
 * \brief Return whether or not a URI is currently stored in the cache
 *
 * \param uri The URI to the resource to query
 *
 * \retval 0 The item is not in the cache
 * \retval 1 The item is in the cache
 */
int ast_media_cache_exists(const char *uri);

/*
 * \brief Retrieve media from a URI or in the cache
 *
 * \param preferred_file_name If not yet retrieved from the remote server, use the preferred file name
 *                            for the media file. Note that this does not include the extension of the
 *                            file, if any.
 * \param file_path Buffer to hold the location of the media on the local file system, minus the extension
 * \param len Length of \c file_path
 *
 * \retval 0 on success
 * \retval -1 on error
 */
int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name, char *file_path, size_t len);

/*!
 * \brief Update an item in the cache
 *
 * \param uri The item to update
 * \param file_path The location to the local file to associate with \c uri
 * \param metadata A list of key/value pairs to store with the URI
 *
 * \retval 0 success
 * \retval -1 error
 */
int ast_media_cache_create_or_update(const char *uri, const char *file_path, struct ast_variable *metadata);

/*
 * \brief Remove an item from the cache
 *
 * \param uri The item to remove
 *
 * \retval 0 success
 * \retval -1 error
 */
int ast_media_cache_delete(const char *uri);
</pre> </td> 
</tr> 
</tbody> 
</table> 
<h3 id="Asterisk14Project-URIMediaPlayback-CLICommands" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">CLI Commands</h3> 
<h4 id="Asterisk14Project-URIMediaPlayback-coreshowmedia-cache" style="margin: 10px 0 0 0; font-size: 14px; line-height: 20px; margin: 20px 0 0 0; margin-top: 10px">core show media-cache</h4> 
<p style="margin: 10px 0 0 0">Just for fun! It'd be good to see what is in the cache, the timestamps, etc.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">*CLI>core show media-cache

URI                                  Last update                Local file
http://myserver.com/awesome.wav      2014-10-30 00:52:25 UTC    /var/spool/asterisk/media_cache/ahsd98d1.wav
http://myserver.com/monkeys.wav      2014-09-14 10:10:00 UTC    /var/spool/asterisk/media_cache/77asdf7a.wav
http://myserver.com/monkeys.h264     2014-09-14 10:10:00 UTC    /var/spool/asterisk/media_cache/77asdf7a.h264 

3 items found.</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Note that the last two files would have been created using a preferred file prefix. This allow the <code style="font-family: monospace">file</code> and <code style="font-family: monospace">app</code> core to "find" both the audio and the video file when opening up the stream returned by the <code style="font-family: monospace">file_path</code> by the <code style="font-family: monospace">media_cache</code>.</p> 
<h4 id="Asterisk14Project-URIMediaPlayback-coreclearmedia-cache" style="margin: 10px 0 0 0; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">core clear media-cache</h4> 
<p style="margin: 10px 0 0 0">This is really a handy way for a system administrator to force files to be pulled down.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">*CLI>core clear media-cache

3 items purged.

*CLI>core show media-cache

URI                                  Last update                Local file
0 items found.</pre> </td> 
</tr> 
</tbody> 
</table> 
<h2 id="Asterisk14Project-URIMediaPlayback-res_http_media_cache" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">res_http_media_cache</h2> 
<h3 id="Asterisk14Project-URIMediaPlayback-FileRetrieval" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0; margin-top: 10px">File Retrieval</h3> 
<p style="margin: 10px 0 0 0">A module should be implemented that does the actual work of using <code style="font-family: monospace">libcurl</code> to retrieve a media file from the system subject to caching constraints, if they exist. It should:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>Implement the HTTP caching, noted previously</li> 
<li>cURL files down to a local file, create a bucket, and store the bucket along with the appropriate metadata</li> 
</ul> 
<h2 id="Asterisk14Project-URIMediaPlayback-Core-Usageofast_openstream" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Core - Usage of ast_openstream</h2> 
<p style="margin: 10px 0 0 0">Prior to call <code style="font-family: monospace">ast_openstream</code>, users who want to support URI playback should first:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>Determine if the provided "file" is actually a URI. A simple 'strncmp' is sufficient for this.</li> 
<li>If so, ask the cache for the actual file. Use that for subsequent calls to <code style="font-family: monospace">ast_openstream</code> and <code style="font-family: monospace">ast_openvstream</code>.</li> 
<li>If not, move on as normal.</li> 
</ul> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">There are other callers of <code style="font-family: monospace">ast_openstream</code>, but it's probably not worth updating <code style="font-family: monospace">ExternalIVR</code> (sorry <img class="emoticon emoticon-sad" src="/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/emoticons/sad.png" data-emoticon-name="sad" alt="(sad)" style="vertical-align: middle" />)</p> </td> 
</tr> 
</tbody> 
</table> 
<h3 id="Asterisk14Project-URIMediaPlayback-Core-file.c::ast_streamfile" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Core - file.c::ast_streamfile</h3> 
<p style="margin: 10px 0 0 0">This covers most functionality, as most dialplan applications (and other things) end up calling <code style="font-family: monospace">ast_streamfile</code>.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-AGI-res_agi.c::handle_streamfile|handle_getoption" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">AGI - res_agi.c::handle_streamfile | handle_getoption</h3> 
<p style="margin: 10px 0 0 0">AGI implementations of basic sound playback, which emulate their dialplan counterparts. These will need to be updated in the same way as <code style="font-family: monospace">ast_streamfile</code>.</p> 
<h2 id="Asterisk14Project-URIMediaPlayback-Core-HTTPserver" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Core - HTTP server</h2> 
<p style="margin: 10px 0 0 0">Support for a new Content-Type, <code style="font-family: monospace">text/uri-list</code>, needs to be added to the HTTP server. Since we typically parse the body as JSON using <code style="font-family: monospace">ast_http_get_json</code>, this should be a new public function <code style="font-family: monospace">ast_http_get_uri_list</code> that pulls a body as a <code style="font-family: monospace">text/uri-list</code>. Since we now have core support for URIs, a bit of basic support for a list of URIs should be added to <code style="font-family: monospace">uri.h</code> and used by the HTTP server.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-http.h" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">http.h</h3> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">/*!
 * \brief Get the text/uri-list body of a request
 *
 * \param ser TCP/TLS session object
 * \param headers List of HTTP headers
 *
 * \retval NULL on error or a body not encoded as text/uri-list
 * \retval A list of URIs. This an ao2 object that must be disposed of by the caller of the function.
 */
struct ast_uri_list *ast_http_get_uri_list(struct ast_tcptls_session_instance *ser, struct ast_variable *headers);</pre> </td> 
</tr> 
</tbody> 
</table> 
<h3 id="Asterisk14Project-URIMediaPlayback-uri.h" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">uri.h</h3> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">/*!
 * \brief Get the string representation of a URI
 *
 * \param The URI
 *
 * \retval The string representation of the URI.
 */
const char *ast_uri_to_string(struct ast_uri *uri);

struct ast_uri_list;
struct ast_uri_list_iterator;

/*!
 * \brief Create a URI list
 *
 * \retval A new \c ast_uri_list on success. This is an ao2 object.
 * \retval NULL on error
 */
struct ast_uri_list *ast_uri_list_create(void);

/*!
 * \brief Append a \c ast_uri to a \c ast_uri_list
 *
 * \param uri The \c ast_uri to append
 */
void ast_uri_list_append(struct ast_uri *uri);

/*!
 * \brief Create an iterator for a \c ast_uri_list
 *
 * \param uri_list The \c ast_uri_list to iterate over
 *
 * \retval A \c ast_uri_list_iterator on success
 * \retval NULL on error
 */
struct ast_uri_list_iterator *ast_uri_list_iterator_create(struct ast_uri_list *uri_list);

/*!
 * \brief Dispose of a \c ast_uri_list_iterator
 *
 * \param iterator The \c ast_uri_list_iterator to destroy
 */
void ast_uri_list_iterator_destroy(struct ast_uri_list_iterator *iterator);

/*!
 * \brief Retrieve the next \c ast_uri in an \c ast_uri_list
 *
 * \param iterator The \c ast_uri_list_iterator for the list
 *
 * \retval NULL if no more items in the list
 * \retval The next \c ast_uri otherwise
 */
struct ast_uri *ast_uri_list_iterator_next(struct ast_uri_list_iterator *iterator);</pre> </td> 
</tr> 
</tbody> 
</table> 
<h2 id="Asterisk14Project-URIMediaPlayback-ARI.1" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">ARI</h2> 
<h3 id="Asterisk14Project-URIMediaPlayback-SwaggerSchema" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0; margin-top: 10px">Swagger Schema</h3> 
<p style="margin: 10px 0 0 0">Providing a 'type' for the <code style="font-family: monospace">media</code> parameter is a bit tricky. We have the following situation:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>If the <code style="font-family: monospace">media</code> parameter does not specify a resource type of <code style="font-family: monospace">uri</code>, treat it as a string.</li> 
<li>If the <code style="font-family: monospace">media</code> parameter does specify a resource type of <code style="font-family: monospace">uri</code>, look to the body as a URI list.</li> 
<li>If the <code style="font-family: monospace">media</code> parameter is in the body, however, it must be of type <code style="font-family: monospace">string</code>. Hence, we cannot specify the URIs directly in the <code style="font-family: monospace">media</code> parameter. Thus, to specify URIs, a body parameter of <code style="font-family: monospace">playlist</code> must be provided and the URIs provided in a <code style="font-family: monospace">Playlist</code> model object.</li> 
</ul> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">title</td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">playbacks.json</td> 
</tr> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">language</td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">js</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">    "models": {
        "Playback": {
            "id": "Playback",
            "description": "Object representing the playback of media to a channel",
            "properties": {
                "id": {
                    "type": "string",
                    "description": "ID for this playback operation",
                    "required": true
                },
                "media_uri": {
                    "type": "string",
                    "description": "URI for the media to play back.",
                    "required": true
                },
                "playlist": {
                    "$ref": "Playlist",
                    "description": "If media_uri is of schema type playlist, the playlist to play",
                    "required": false
                },
                "target_uri": {
                    "type": "string",
                    "description": "URI for the channel or bridge to play the media on",
                    "required": true
                },
                "language": {
                    "type": "string",
                    "description": "For media types that support multiple languages, the language requested for playback."
                },
                "state": {
                    "type": "string",
                    "description": "Current state of the playback operation.",
                    "required": true,
                    "allowableValues": {
                        "valueType": "LIST",
                        "values": [
                            "queued",
                            "playing",
                            "complete"
                        ]
                    }
                }
            }
        }
        "MediaResource": {
            "id": "MediaResource",
            "description": "A single media resource to operate on",
            "properties": {
                "scheme": {
                    "type": "string",
                    "description": "The type for this media resource.",
                    "required": true
                },
                "resource": {
                    "type": "string",
                    "description": "The actual media resource to manipulate.",
                    "required": true
                }
            }
        }
        "MediaGroup": {
            "id": "MediaGroup",
            "description": "One or more MediaResources that are associated together as a logical unit",
            "properties": {
                "media_group": {
                    "type": "array",
                    "description": "Array of MediaResources to treat as a single logical unit",
                    "required": true,
                    "items": {
                        "$ref": "MediaResource"
                    }
                 }
            }
        }   
        "Playlist": {
            "id": "Playlist",
            "description": "One or more MediaGroups to play sequentially",
            "properties": {
                "playlist": {
                    "type": "array",
                    "description": "Array of MediaGroups to play sequentially",
                    "required": true,
                    "items": {
                        "$ref": "MediaGroup"
                    }
                 }
             }
        }
    } </pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Note that the following for <code style="font-family: monospace">channels.json</code> would be repeated for <code style="font-family: monospace">bridges.json</code>:</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">title</td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">channels.json</td> 
</tr> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">language</td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">js</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">        {
            "path": "/channels/{channelId}/play",
            "description": "Play media to a channel",
            "operations": [
                {
                    "httpMethod": "POST",
                    "summary": "Start playback of media.",
                    "notes": "The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, uri:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)",
                    "nickname": "play",
                    "responseClass": "Playback",
                    "parameters": [
                        ...
                        {
                            "name": "playlist",
                            "description": "A play list to play.",
                            "paramType": "body",
                            "required": false,
                            "allowMultiple": false,
                            "$ref": "Playlist"
                        }
                    ],
                    "errorResponses": [
                        {
                            "code": 404,
                            "reason": "Channel not found"
                        },
                        {
                            "code": 409,
                            "reason": "Channel not in a Stasis application"
                        }
                    ]
                }
            ]
        }, </pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0"> </p> 
<h3 id="Asterisk14Project-URIMediaPlayback-MustacheTemplates" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Mustache Templates</h3> 
<p style="margin: 10px 0 0 0">The Mustache templates generated will need to be modified to check for <code style="font-family: monospace">text/uri-list</code> as a possible body type:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>The existing <code style="font-family: monospace">body_parsing.mustache</code> should be renamed to note that it parses JSON. The caller of the <code style="font-family: monospace">body_parsing</code> routines should be made to only look at the results if the function returns non-NULL. 
<ul style="margin: 10px 0 0 0"> 
<li>If it does return NULL, it should also check for a <code style="font-family: monospace">text/uri-list</code> using the new function in <code style="font-family: monospace">http.h</code>.</li> 
<li>The body parsers should be updated for a playback operation to return the structured Playback object.</li> 
</ul> </li> 
<li> <p style="margin: 10px 0 0 0; margin-top: 0">A new <code style="font-family: monospace">text_uri_body_parser</code> should be added that parses a body into a <code style="font-family: monospace">struct ast_uri_list</code>. This should be hard-typed to convert the URI list into a structured Playback object.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">This is limiting, but for now, we don't have any use for a URI list in ARI outside of specifying a list of media resources. If that assumption proves false later, that code should be re-visited.</p> </td> 
</tr> 
</tbody> 
</table> </li> 
</ul> 
<h1 id="Asterisk14Project-URIMediaPlayback-TestPlan" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Test Plan</h1> 
<h2 id="Asterisk14Project-URIMediaPlayback-UnitTests" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 10px">Unit Tests</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Category</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Test</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/exists</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Nominal test that verifies a valid item in the cache can be found</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/exists</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">non_existent</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test that verifies that an item in the cache that doesn't exist isn't located</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/exists</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_scheme</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we reject a URI with an unknown or unsupported scheme</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/exists</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_params</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Pass in bad parameters, make sure we get back a "huh?"</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Retrieve a file from the Asterisk HTTP server (using magic!) and make sure it is in the cache. Retrieve it again and make sure we didn't do an HTTP request twice.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">non_existent</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for a file that doesn't exist. Get an error back.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_scheme</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for something that has a bad URI scheme.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_params</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for something with no URI and no file_path. Make sure we reject it.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">new_file</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Retrieve a media file, cache it. Update the file, ask for the file again; make sure it gets the new copy.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">preferred_file_name</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for a file with a preferred file name; verify that we retrieve the file and set the file name accordingly (with the right extension).</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/delete</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Put something in the cache. Call delete; verify the cache is purged.</td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/empty</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Call delete on an empty cache; make sure everything is cool.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/update</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">create</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that a new item in the cache can be created</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/media_cache/update</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">update</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that an existing item in the cache can be updated</td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">to_string</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test that a constructed URI can be converted back to a string</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">list_ctor</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we can make a URI list</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">list_append_nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test appending URIs to a list</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">list_append_off_nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test appending things that aren't a URI, and make sure we fail appropriately</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">iterator_ctor</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test nominal creation of an iterator</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">iterator_ctor_off_nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test off-nominal creation of an iterator with a bad list</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">iterator_iteration</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test nominal iteration over lists. Include empty lists.</td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-AsteriskTestSuite" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Asterisk Test Suite</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Test</p> </th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Level</p> </th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Description</p> </th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <code style="font-family: monospace">funcs/func_curl/read</code> </p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">Asterisk Test Suite</p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">A regression test that verifies that the current read functionality of <code style="font-family: monospace">CURL</code> is maintained</p> </td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <code style="font-family: monospace">funcs/func_curl/write</code> </p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">Asterisk Test Suite</p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we can cURL a file down and store it</td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">funcs/func_curl/curl_opt/timestamp</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we can retrieve the timestamp from a resource</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/apps/playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the <code style="font-family: monospace">Playback</code> dialplan application can playback a remote URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/apps/control_playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the <code style="font-family: monospace">ControlPlayback</code> dialplan application can playback a remote URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/fastagi/stream-file-uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the AGI Stream File command can play a URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/fastagi/control-stream-file-uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the AGI Control Stream File command can play a URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/rest_api/channels/playback/playlist</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that a Playback resource that contains a playlist can be played back to a channel</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/rest_api/bridges/playback/playlist</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that a Playback resource that contains a playlist can be played back to a bridge</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/rest_api/channels/playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that a Playback resource can be created from a URI for a Channel</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/rest_api/bridges/playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that a Playback resource can be created from a URI for a Bridge</td> 
</tr> 
</tbody> 
</table> 
</div> 
<h1 id="Asterisk14Project-URIMediaPlayback-ProjectPlanning" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Project Planning</h1> 
<p style="margin: 10px 0 0 0">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 <code style="font-family: monospace">asterisk-dev</code> mailing list!</p> 
<p style="margin: 10px 0 0 0">The various phases are meant to be implemented as separately as possible to ease the process of peer review.</p> 
<h2 id="Asterisk14Project-URIMediaPlayback-PhaseOne-CoreMediaCache" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Phase One - Core Media Cache</h2> 
<p style="margin: 10px 0 0 0">See peer reviews:</p> 
<ul style="margin: 10px 0 0 0"> 
<li> <a href="https://gerrit.asterisk.org/#/c/487/" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://gerrit.asterisk.org/#/c/487/</a> </li> 
<li> <a href="https://gerrit.asterisk.org/#/c/488/" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://gerrit.asterisk.org/#/c/488/</a> </li> 
</ul> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Task</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
<th colspan="1" class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Status</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Implement the basic API</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Mask callbacks into the <code style="font-family: monospace">bucket</code> API based on the URI scheme being requested. Add handling for manipulating the created bucket's local file if the predefined filename is provided.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Done</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Integrate with the AstDB</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">When items are created via a bucket <code style="font-family: monospace">create</code> or <code style="font-family: monospace">retrieve</code>, update entries in the AstDB.</p> <p style="margin: 10px 0 0 0">When Asterisk is started, re-create buckets based on the entries currently in the AstDB.</p> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Done</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Add CLI commands</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Both for showing elements in the media cache as well as for purging the cache. If the cache is purged, remove entries from the AstDB.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Done</td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-PhaseTwo-res_http_media_cache" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Phase Two - res_http_media_cache</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Task</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Status</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Create <code style="font-family: monospace">http_media_cache</code>. Add bucket wizards for schema types <code style="font-family: monospace">http</code> and <code style="font-family: monospace">https</code>. 
<ul style="margin: 10px 0 0 0; margin-left: 0; padding-left: 22px"> 
<li>Define basic unit tests for creation/deletion</li> 
<li>Implement bucket wizard callbacks for basic manipulation</li> 
</ul> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Generally, get the basic structure of the the thing defined, implement unit tests, and make sure the unit tests fail. TDD.</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">In <span class="diff-html-removed" id="removed-diff-0" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">progress</span><span class="diff-html-added" id="added-diff-0" style="font-size: 100%; background-color: #ddfade;">Review</span></td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Implement retrieval. Use the underlying <code style="font-family: monospace">CURL</code> function to retrieve a provided URI and store as a temporary file (or use the predetermined filename).</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">A few observations:</p> 
<ul style="margin: 10px 0 0 0; margin-left: 0; padding-left: 22px"> 
<li>This shouldn't worry about marking the cache entries as dirty yet using the caching rules. This should: 
<ul style="margin: 10px 0 0 0; margin-top: 0; margin-left: 0; padding-left: 22px"> 
<li>Check to see if we have a bucket with the URI. If not, create the bucket.</li> 
<li> <code style="font-family: monospace">cURL</code> the resource down into the provided file path.</li> 
<li>Update the bucket entry with the now locally stored file.</li> 
<li>Return the location of the local file on the file system.</li> 
</ul> </li> 
</ul> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">In <span class="diff-html-removed" id="removed-diff-1" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">progress</span><span class="diff-html-added" id="added-diff-1" style="font-size: 100%; background-color: #ddfade;">Review</span></td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Implement 'dirtying' of cache entry based on HTTP caching rules.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Implement handling of <code style="font-family: monospace">E-Tags</code> as well as the <code style="font-family: monospace">Cache-Control</code> header.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">In <span class="diff-html-removed" id="removed-diff-2" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">progress</span><span class="diff-html-added" id="added-diff-2" style="font-size: 100%; background-color: #ddfade;">Review</span></td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-PhaseThree-Core/dialplan/AGIimplementations" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Phase Three - Core/dialplan/AGI implementations</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Task</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Status</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update the <code style="font-family: monospace">file</code> core to use the <code style="font-family: monospace">http_media_cache</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update the core <code style="font-family: monospace">file</code> users of <code style="font-family: monospace">ast_openstream</code> to first look for the resource in the <code style="font-family: monospace">http_media_cache</code>. If found, use the returned file.</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><span class="diff-html-removed" id="removed-diff-3" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span><span class="diff-html-added" id="added-diff-3" style="font-size: 100%; background-color: #ddfade;">In Review</span></td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update the dialplan users</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Same as the core, except for dialplan functions.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><span class="diff-html-removed" id="removed-diff-4" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span><span class="diff-html-added" id="added-diff-4" style="font-size: 100%; background-color: #ddfade;">In Review</span></td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Add tests for <code style="font-family: monospace">Playback</code> and <code style="font-family: monospace">ControlPlayback</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update the AGI users</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Same as the core, except for <code style="font-family: monospace">res_agi</code> functions.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Add tests for <code style="font-family: monospace">stream file</code> and <code style="font-family: monospace">control stream file</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-PhaseFour-ARIPlaylists" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Phase Four - ARI Playlists</h2> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">This is actually a completely separate and super useful feature. URI playbacks really need it to function so... here it is.</p> <p style="margin: 10px 0 0 0">Note that this does not envision complete playlist control (such as 'skip to next sound in the playlist'). That could be added either as part of this work or at a future date.</p> </td> 
</tr> 
</tbody> 
</table> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Task</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Status</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update the JSON schema with JSON playlists</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">This should require updates to the <code style="font-family: monospace">Playbacks</code> model, as well as the <code style="font-family: monospace">play</code> operations for <code style="font-family: monospace">channels</code> and <code style="font-family: monospace">bridges</code>. The mustache templates may need to be updated to properly extract this complex of a body type.</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Re-generate stubs; add connecting logic</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Re-generating the stubs will create a new body handler and a more complex 'playlist' object that can be optionally present. This will be passed to the <code style="font-family: monospace">resource_channels</code> and <code style="font-family: monospace">resource_bridges</code> operations.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Add a 'playlist' media resource type</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> 
<ul style="margin: 10px 0 0 0; margin-top: 0; margin-left: 0; padding-left: 22px"> 
<li>Update <code style="font-family: monospace">resource_channels:ari_channels_handle_play</code> and <code style="font-family: monospace">resource_bridges:ari_handle_play</code> (boiling down to <code style="font-family: monospace">ari_bridges_play_helper</code> ) to understand a body playlist. This should pass it off to <code style="font-family: monospace">stasis_app_control_play_uri</code> or an equivalent function for actual handling.</li> 
<li>Update <code style="font-family: monospace">stasis_app_control_play_uri</code> or add an equivalent function to actually play the list.</li> 
</ul> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update <code style="font-family: monospace">res_stasis_playback</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">The various function calls boil down to <code style="font-family: monospace">play_on_channel</code> in <code style="font-family: monospace">res_stasis_playback</code>. This is passed the actual <code style="font-family: monospace">Playback</code> resource object, which now can contain a <code style="font-family: monospace">Playlist</code>. The function should be updated to parse out the various items in the playlist and pass them to <code style="font-family: monospace">ast_control_streamfile_lang</code>.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Add <code style="font-family: monospace">rest_api</code> tests for playlists.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-PhaseFive-HTTPServerUpdates" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Phase Five - HTTP Server Updates</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Task</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Status</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update <code style="font-family: monospace">uri.h</code> to support URI lists and URI iterators.</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Add unit tests!</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update <code style="font-family: monospace">http.h</code> to support body types of <code style="font-family: monospace">text/uri-list</code>. Generate a <code style="font-family: monospace">ast_uri_list</code> as a result of said body type.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-PhaseSix-ARItext/uri-listsupport/URIplaybacks" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Phase Six - ARI <code style="font-family: monospace">text/uri-list</code> support/URI playbacks</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Task</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Status</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Update mustache templates to understand a body type of <code style="font-family: monospace">text/uri-list</code>. Re-generate appropriate stubs.</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Body parsing should be made to handle both JSON as well as the <code style="font-family: monospace">text/uri-list</code> body type. A <code style="font-family: monospace">text/uri-list</code> body parser can be made to explicitly return <code style="font-family: monospace">Playback</code> objects suitable for consumption in the existing playlist mechanisms.</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Wire generated code to <code style="font-family: monospace">resource_channels</code>, <code style="font-family: monospace">resource_bridges</code>. Update API callbacks as needed.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">Generally, this should "just work" (or nearly) at this point. We have:</p> 
<ul style="margin: 10px 0 0 0; margin-left: 0; padding-left: 22px"> 
<li>Understanding of URI playbacks in the core</li> 
<li>Understanding of playlists in ARI</li> 
<li>The ability to handle URI playbacks (including parallel playbacks) in <code style="font-family: monospace">ast_control_streamfile_lang</code>, which is what is used by <code style="font-family: monospace">res_stasis_playback:play_on_channel</code>.</li> 
</ul> <p style="margin: 10px 0 0 0">Most of this should be just gluing the pieces together as needed.</p> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Add URI playback tests to Asterisk Test Suite.</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> </td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-JIRAIssues" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">JIRA Issues</h2> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-removed" id="removed-diff-5" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span> </p> 
<p style="margin: 10px 0 0 0"></p> 
<table class="diff-macro bodyless diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;margin: 5px 0; padding: 0; width: auto;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" id="added-diff-5" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5639/a252d7f5e75d7a8bf7047b4b2c92f71a56a8f048.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=jira" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>JIRA</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">server</span></td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Digium/Asterisk JIRA</span></td> 
</tr> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">serverId</span></td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ee634d14-2067-31b4-9ca3-00e0845ec070</span></td> 
</tr> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">key</span></td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ASTERISK-25654</span></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0"></p> 
<h2 id="Asterisk14Project-URIMediaPlayback-Contributors" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Contributors</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Name</p> </th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">E-mail Address</p> </th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <span class="confluence-userlink user-mention" style="background-color: #f5f5f5; border: 1px solid #ddd; padding: 0 2px; border-radius: 3px; display: inline-block; mso-line-height-rule: exactly; line-height: 16px; white-space: nowrap"><span style="color: #999; font-size: 12px; line-height: 16px; mso-line-height-rule: exactly; padding-right:2px; vertical-align:top; mso-text-raise:3px;">@</span><a href="/wiki/display/~mjordan" style="color: #3b73af; text-decoration: none">Matt Jordan</a></span> </p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <a href="mailto:mjordan@digium.com" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">mjordan@digium.com</a> </p> </td> 
</tr> 
</tbody> 
</table> 
</div> 
<h1 id="Asterisk14Project-URIMediaPlayback-ReferenceInformation" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Reference Information</h1> 
<p style="margin: 10px 0 0 0">http%3A%2F%<a href="http://2Fmyserver.com" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">2Fmyserver.com</a>%2Fmedia%3Fsound%3Dmonkeys%26format%3Dwav</p> 
</div> </td> 
</tr> 
</tbody>
</table> 
</div> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand action-padding last-row-padding" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff; padding-bottom: 10px; padding-bottom: 10px"> 
<table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td id="actions-pattern-container" valign="middle" style="padding: 0px; border-collapse: collapse; padding: 15px 0 0 24px; vertical-align: middle"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="View page Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="View page Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aview-page-email-adg-footer-item%3Aicon" alt="View page Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="View page" style="color: #3b73af; text-decoration: none">View page</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Add comment Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aadd-comment-to-content-email-adg-footer-item%3Aicon" alt="Add comment Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment" style="color: #3b73af; text-decoration: none">Add comment</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=30279111&src=email" title="Like Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Like Icon" src="cid:com.atlassian.confluence.plugins.confluence-like%3Aview-email-adg-content-item%3Aicon" alt="Like Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=30279111&src=email" title="Like" style="color: #3b73af; text-decoration: none">Like</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-rounded-bottom mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; height: 5px; line-height: 5px; padding: 0 15px 0 16px; background-color: #fff; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; border-top: 0; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; mso-line-height-rule: exactly"> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern" style="padding: 0px; border-collapse: collapse; padding: 12px 20px"> 
<table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="footer-pattern-links-container" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST&src=email" title="" style="color: #3b73af; text-decoration: none">Stop watching space</a></td>
<td class="footer-pattern-links-bull" style="padding: 0px; border-collapse: collapse; padding: 0 5px; color: #999">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action?src=email" title="" style="color: #3b73af; text-decoration: none">Manage notifications</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px; display: none">This message was sent by Atlassian Confluence 5.6.6</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> 
<table id="sealed-section" border="0" cellpadding="0" cellspacing="0" width="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; display: none"> 
<tbody> 
<tr> 
<td style="padding: 0px; border-collapse: collapse; border: 0; font-size: 0px; line-height: 0; mso-line-height-rule: exactly"></td> 
</tr> 
</tbody> 
</table>
</body>
</html>