【问题标题】:Audio stream missing HTML <audio> duration音频流缺少 HTML <audio> 持续时间
【发布时间】:2021-11-28 00:20:28
【问题描述】:

我需要隐藏 Twilio 资源的 URL 并将一些授权内容附加到请求中。调用时,此函数应返回 Recording(最好是 Stream),并包含浏览器的 &lt;audio&gt; 标签所需的任何数据,以显示音频的持续时间。

如果我将它直接指向一个 .wav 文件,这将“开箱即用”。但是,当我流式传输时,我会丢失持续时间,因为我猜浏览器在流式传输时没有收到必要的元数据。

所以我的问题是:我如何通过 .NET Core 方法并使用任何必要的信息流式传输另一端 (Twilio) 上的任何内容,以向&lt;audio&gt; 播放器提供持续时间。

我拥有的是这样的:

        public MyClass(IHttpClientFactory httpClientFactory) {
            _httpClient = httpClientFactory.CreateClient("AudioHttpClient");
            _httpClient.DefaultRequestHeaders.Add("x-api-key", "some-api-key");
        }

        [HttpGet("/audio/{id}")]
        public async Task<Stream> GetFile(string id)
        {
            return await _httpClient.GetStreamAsync($"https://api.twilio.com/Account/something/Recordings/{id}.wav");
        }

...被原版播放器调用:

    function createAudioPlayer(filename) {
            var element = document.createElement("audio");
            element.setAttribute("controls", "controls");
            element.setAttribute("controlsList", "nodownload");
            element.setAttribute("preload", "auto");
            element.setAttribute("src", "/audio/" + filename); // will invoke the GET Controller above
            element.oncontextmenu = function () {
                return false;
            }

            var container = document.getElementById("audiocontainer");
            container.appendChild(element);
        }

...

    createAudioPlayer("something");

当我这样做时,文件可以正常播放。问题是它缺少持续时间。所以音频播放器说“0:00”,我需要它说“0:00 / 9:20”。

听起来这是因为它是流式传输的,但奇怪的是,如果我通过 Postman 执行相同的 GET 请求,我确实得到了持续时间。

所以,这是可能的。邮递员正在以某种方式做到这一点。我不知道还有什么可以尝试的。我什至尝试根据控制器中设置的 Content-Length 标头在&lt;audio&gt; 上设置duration,但没有运气。那些字段只读但我想我会尝试。

如果我必须,我可以返回一个文件(这应该可以解决这个问题,因为根是它是一个流)但我不确定如何在不让用户等待两次下载的情况下做到这一点(一次是我的控制器从 Twilio 请求它,并再次让我的控制器将它传送到我的 UI)。非常感谢您以不只是下载文件然后重新传输的方式提供任何帮助。

我真的不在乎我如何解决这个问题。 JS/C#,流/文件..只要有持续时间,不引起2个全同步传输。

【问题讨论】:

  • 当您的浏览器通过您的代理请求音频文件时,与直接访问文件相比,它是否返回正确的Content-Type 和其他标题?我想知道是否是浏览器无法识别文件类型并且没有读取元数据,因此没有正确设置持续时间。
  • @philnash 好主意。我会检查。我假设直接返回流意味着它将通过所有标题,但这种假设可能是错误的。如果错了,你知道我如何从GetStreamAsync 获取标题吗?我知道要采取什么步骤(从响应 A 复制标头,将它们添加到响应 B,也许也复制请求标头)但我不知道如何在 C# 中表达(我对 C# 很陌生)
  • @philnash 基本上就是这样。我必须弄清楚如何表达“带他们前进”,但我明白了。我为其他好奇如何做到这一点的人提供了一个答案——谢谢你的帮助。
  • 啊,很高兴你整理了它!您也应该将您的答案标记为正确!

标签: c# .net-core twilio


【解决方案1】:

我最终通过将 Twilio 标头带到我的响应中来解决这个问题。我怀疑是这样,但感谢@PhilNash 的提醒。非常感谢。

我想出了类似的方法,可能会在未来帮助人们,但请注意,我不确定这是实现这一目标的最佳方式。

        public async Task<Stream> GetFile(string id)
        {
            var response = await _httpClient.GetAsync($"https://api.twilio.com/whatever/Recordings/{id}.wav", HttpCompletionOption.ResponseHeadersRead);

            Response.ContentType = response.Content.Headers.ContentType.ToString();
            Response.ContentLength = response.Content.Headers.ContentLength;

            return await response.Content.ReadAsStreamAsync();
        }

这个想法只是获取GetAsync 的响应标头并将它们添加到“我的”响应标头中。特别是 Content-Length,因为这是 &lt;audio&gt; 用来推断“比特率与大小 = 持续时间”之类的东西

【讨论】:

    猜你喜欢
    • 2015-02-08
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 2017-03-09
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多