Twilio播放暂停/恢复

时间:2013-11-09 18:00:50

标签: twilio twiml

Twilio是否支持暂停和恢复播放内容。换句话说,我有相当长的文件将播放给调用者,我正试图找到一种方法来实现暂停&恢复功能。在播放某些内容的过程中,我希望用户能够按一个数字暂停,然后再按一个数字以从暂停的音频文件中的同一点继续播放。

Twilio是否支持类似的东西?

2 个答案:

答案 0 :(得分:3)

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

基本思路是计算生成播放命令与调用Gather URL之间的时间差。差异(假设完美的世界片刻)应该是在被呼叫者打断之前播放内容的距离。然后,当调用者准备好恢复时,生成Play命令,使其导致您的应用服务器不提供完整内容,而是部分偏移的内容,从播放应该恢复的点开始(这可能意味着需要实现仅提供部分音频文件内容的机制)。这基本上可以模拟暂停/恢复功能。

我已经实现了它,它或多或少的工作。网络延迟,处理延迟(Twilio收到Play命令之间的时间,检索播放资源,实际开始播放)以及点击按钮和实际接收{之间的延迟时间 - 发生了不完美的世界。 {1}}调用会影响准确性。但是如果你的要求不是太严格,那么对于大多数情况来说,准确度可能还不够。

以下是我在C#中所做的概念验证(已经过了几个月 - 希望它仍然可以发布)。它还包括快进和倒带实验,只需调整恢复实际启动的位置(并跳过Gather命令)。


以下代码适用于PausablePlayController.cs,它使用PausePlay和其他命令生成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需要从您的服务器下载音频文件,然后在它之前进行转码可以播放(除了服务器需要重新生成新音频文件的时间)