Twilio播放暂停/恢复

Twilio播放暂停/恢复,twilio,twilio-twiml,Twilio,Twilio Twiml,Twilio是否支持暂停和恢复播放内容。换句话说,我有相当长的文件可以播放给调用者,我正试图找到一种实现暂停和恢复功能的方法。在一些内容的播放过程中,我想让用户有能力按下一个数字来暂停,然后再按下一个数字,从暂停的音频文件中的同一点恢复播放。p> Twilio支持这样的东西吗?使用TwiML无法做到这一点。您只能在服务器上使用此逻辑,然后使用另一个播放标签重新初始化音频文件,但我相信这会带来相当大的延迟,因为Twilio需要从您的服务器下载音频文件,然后在播放之前对其进行转码(此外,您的服务器还

Twilio是否支持暂停和恢复播放内容。换句话说,我有相当长的文件可以播放给调用者,我正试图找到一种实现暂停和恢复功能的方法。在一些内容的播放过程中,我想让用户有能力按下一个数字来暂停,然后再按下一个数字,从暂停的音频文件中的同一点恢复播放。p>
Twilio支持这样的东西吗?

使用TwiML无法做到这一点。您只能在服务器上使用此逻辑,然后使用另一个播放标签重新初始化音频文件,但我相信这会带来相当大的延迟,因为Twilio需要从您的服务器下载音频文件,然后在播放之前对其进行转码(此外,您的服务器还需要重新生成新的音频文件)

我确实找到了一个可行的解决方案,尽管不是完美的解决方案,来解决如何使用Twilio暂停和恢复播放的问题

基本思想是计算生成play命令和调用URL之间的时间差。区别(假设完美世界暂时存在)应该是内容在被调用者打断之前播放了多远。然后,当调用者准备好继续播放时,生成
Play
命令,使您的应用程序服务器交付的内容不是全部内容,而是部分偏移的内容,该内容从应恢复播放的点开始(这可能意味着需要实现仅交付部分音频文件内容的机制)。这基本上模拟了暂停/恢复功能

我已经实现了这一点,它或多或少是有效的。网络延迟、处理延迟(Twilio接收
play
命令、检索播放资源和实际开始播放之间的时间)以及点击按钮和实际接收
Gather
调用之间的延迟都会影响准确性。但是,如果您的要求不太严格,那么在大多数情况下,准确度可能足够高

这是我在C#中所做的概念证明(已经过了几个月了,希望它仍能像发布的那样工作)。它还包括快进和快退的实验,这只是调整恢复实际开始的位置(并跳过
Pause
命令)


下面的代码用于PausablePlayController.cs,它使用
Play
Pause
和其他命令生成TwiML

Play
action(不是TwiML命令)为播放内容生成TwiML。播放可以中断,因为它被包装在
聚集
中,指向
暂停
操作。
Gather
的URL包含播放开始位置的时间戳(如果之前已经偏移,则将其计算回时间)

Pause
操作(不是TwiML命令)生成用于执行暂停或查找的TwiML。在下面的代码中,4次倒带,5次从头开始重新启动,6次快进,任何其他键都会暂停

公共类PausablePlayController:ApicController
{
私有常量int seekDeltaMilliseconds=5000;
//获取api/pausableplay/5
[HttpGet]
public System.Xml.Linq.XElement播放(字符串音频,整数毫秒)
{
TwilioResponse twiml=新的TwilioResponse();
twiml.BeginGather(new{action=this.Url.Link(“PausablePlayPause”,new{audio=audio,playStart=DateTime.UtcNow.Subtract(new TimeSpan(0,0,0,0,毫秒soffset)).Ticks/*.ToString(“o”,System.Globalization.CultureInfo.InvariantCulture)*/}),method=“GET”,numDigits=“1”});
Play(this.Url.Link(“OffsetPresentations”,new{audio=audio,毫秒soffset=毫秒soffset}));
twiml.EndGather();
返回twiml.Element;
}
[HttpGet]
public System.Xml.Linq.XElement暂停(字符串音频、长播放开始、整数位数)
{
DateTime playStartDate=新的日期时间(playStart,DateTimeKind.Utc);
int毫秒soffset=(int)DateTime.UtcNow.Subtract(playStartDate.totalmillizes;
TwilioResponse twiml=新的TwilioResponse();
开关(数字)
{
案例4:
毫秒soffset-=(毫秒soffset
技巧的其余部分在下一个控制器中,该控制器流式传输部分音频内容(不幸的是,我在其他文章中找到的部分代码,我不再参考)。它所做的只是计算给定毫秒偏移量的音频内容从何处开始,并从该点流式传输其余内容

公共类OffsetedContentController:ApplicationController
{
常量int BufferSize=32*1024;
//获取api/prompts/5
公共任务获取(字符串音频,[FromUri]int毫秒soffset)
{
string contentFilePath=audio;//为音频内容构建物理路径
如果(!File.Exists(contentFilePath))
{ 
返回Task.FromResult(Request.CreateResponse(HttpStatusCode.NotFound));
}            
//打开文件并从中读取响应。如果读取失败