Twilio是否支持暂停和恢复播放内容。换句话说,我有相当长的文件将播放给调用者,我正试图找到一种方法来实现暂停&恢复功能。在播放某些内容的过程中,我希望用户能够按一个数字暂停,然后再按一个数字以从暂停的音频文件中的同一点继续播放。
Twilio是否支持类似的东西?
答案 0 :(得分:3)
我确实找到了一个可行的,尽管不是完美的解决方案,如何使用Twilio暂停和恢复播放。
基本思路是计算生成播放命令与调用Gather
URL之间的时间差。差异(假设完美的世界片刻)应该是在被呼叫者打断之前播放内容的距离。然后,当调用者准备好恢复时,生成Play
命令,使其导致您的应用服务器不提供完整内容,而是部分偏移的内容,从播放应该恢复的点开始(这可能意味着需要实现仅提供部分音频文件内容的机制)。这基本上可以模拟暂停/恢复功能。
我已经实现了它,它或多或少的工作。网络延迟,处理延迟(Twilio收到Play
命令之间的时间,检索播放资源,实际开始播放)以及点击按钮和实际接收{之间的延迟时间 - 发生了不完美的世界。 {1}}调用会影响准确性。但是如果你的要求不是太严格,那么对于大多数情况来说,准确度可能还不够。
以下是我在C#中所做的概念验证(已经过了几个月 - 希望它仍然可以发布)。它还包括快进和倒带实验,只需调整恢复实际启动的位置(并跳过Gather
命令)。
以下代码适用于PausablePlayController.cs,它使用Pause
,Play
和其他命令生成TwiML。
Pause
动作(不是TwiML命令)生成用于播放内容的TwiML。播放是可中断的,因为它包含在Play
中,指向Gather
操作。 Pause
的URL包含播放开始的时间戳(如果之前已经偏移,则会及时计算)。
Gather
动作(不是TwiML命令)生成用于执行暂停或搜索的TwiML。在4以下的代码中,从开始重启5次,从快进6次重启,其他任何键都暂停。
Pause
其余的技巧是在下一个控制器中流式传输部分音频内容(不幸的是,我在其他帖子中找到的部分代码我不再参考)。它所做的就是简单地计算给定毫秒偏移量的音频内容的开始位置,并从该点开始流式传输剩余的内容。
public class PausablePlayController : ApiController
{
private const int seekDeltaMilliseconds = 5000;
// GET api/pausableplay/5
[HttpGet]
public System.Xml.Linq.XElement Play(string audio, int millisecondsOffset)
{
TwilioResponse twiml = new TwilioResponse();
twiml.BeginGather(new { action = this.Url.Link("PausablePlayPause", new { audio = audio, playStart = DateTime.UtcNow.Subtract(new TimeSpan(0, 0, 0, 0, millisecondsOffset)).Ticks/*.ToString("o", System.Globalization.CultureInfo.InvariantCulture )*/ }), method = "GET", numDigits = "1" });
twiml.Play(this.Url.Link("OffsetPresentations", new { audio = audio, millisecondsOffset = millisecondsOffset }));
twiml.EndGather();
return twiml.Element;
}
[HttpGet]
public System.Xml.Linq.XElement Pause(string audio, long playStart, int digits)
{
DateTime playStartDate = new DateTime(playStart, DateTimeKind.Utc);
int millisecondsOffset = (int)DateTime.UtcNow.Subtract(playStartDate).TotalMilliseconds;
TwilioResponse twiml = new TwilioResponse();
switch(digits)
{
case 4:
millisecondsOffset -= (millisecondsOffset < seekDeltaMilliseconds) ? millisecondsOffset : seekDeltaMilliseconds;
return Play(audio, millisecondsOffset);
case 5:
return Play(audio, 0);
case 6:
millisecondsOffset += seekDeltaMilliseconds;
return Play(audio, millisecondsOffset);
default:
{
twiml.BeginGather(new { action = this.Url.Link("PausablePlayPlay", new { audio = audio, millisecondsOffset = millisecondsOffset }), method = "GET", numDigits = "1" });
twiml.Pause(120);
twiml.EndGather();
twiml.Say("Goodbye!");
}
break;
}
return twiml.Element;
}
}
答案 1 :(得分:0)
使用TwiML无法做到这一点。您只能在服务器上使用此逻辑,然后使用另一个Play标签重新启动音频文件,但我相信这会引入相当多的延迟,因为Twilio需要从您的服务器下载音频文件,然后在它之前进行转码可以播放(除了服务器需要重新生成新音频文件的时间)