简体   繁体   中英

Audio stream missing HTML <audio> duration

I need to obscure the URL of a Twilio resource and attach some authorization stuff to the request. When invoked, this function should return the Recording (preferably as a Stream ) and include with it whatever data is necessary for the browser's <audio> tag to show the duration of the audio.

This works "out of the box" if I point it straight to a.wav file. But, when I stream it, I lose the duration because I guess browsers don't receive the necessary metadata when streaming.

So my question is this: how can I pass through a .NET Core method and stream whatever's on the other end (Twilio) with whatever necessary information to provide the duration to the <audio> player.

What I have is this:

        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");
        }

...which gets invoked by a vanilla player:

    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");

When I do this, the file plays fine. The problem is that it's missing the duration. So the audio player says "0:00" and I need it to say something like "0:00 / 9:20".

It sounds like this is because it's streaming but what's strange is that if I do this same GET request via Postman, I do get the duration.

So, it's possible. Postman is doing it somehow. I'm out of ideas what else to try. I've even tried setting duration on <audio> based on Content-Length header set in my Controller, but no luck. That fields read only but figured I'd try.

If I must, I can return a file (which should fix this problem cuz the root is that it's a Stream) but I'm not sure how to do that without making the user wait twice for the download (once for my Controller to request it from Twilio, and again for my Controller to deliver it to my UI). Any help doing that in a way which doesn't just download the file then re-transmit it is very appreciated.

I dont really care how I solve this. JS/C#, stream/file.. It just needs to have the duration and not cause 2 full synchronous transmissions.

I wound up solving this by carrying the Twilio headers forward into my response. I suspected it was that but thanks to @PhilNash for the reminder. Many thanks.

I came up with something like this which maybe helps people in the future but please be warned that I'm not sure this is the best way to accomplish this.

        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();
        }

The idea being just to take the GetAsync 's response Headers and add them to "my" Response headers. In particular, it's the Content-Length since that's what <audio> uses to deduce something like "bitrate vs. size = duration"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM