【问题标题】:Stream Audio directly from an url to Web Browser in C# & ASP.NET MVC?在 C# 和 ASP.NET MVC 中将音频直接从 URL 流式传输到 Web 浏览器?
【发布时间】:2018-12-21 04:27:03
【问题描述】:

我在一个项目中使用 ASP.NET MVC 和 C#。

一个任务是:当用户点击一个链接时,需要从链接中获取id,然后使用这个链接生成一个外部链接,这是一个音频文件,然后在网络浏览器中播放(不另存为文件)。

目前的解决方案是:从外部链接下载音频文件,获取字节,然后将其作为音频/wav放入响应中

public async Task<HttpResponseMessage> StreamAudioAsync(string id)
{
    var response = Request.CreateResponse(HttpStatusCode.Moved);
    var data = GetAudio(id);

    if (data != null && data.Length > 0)
    {
        response.StatusCode = HttpStatusCode.OK;
        response.Content = new ByteArrayContent(data);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("audio/wav");
    }

    return response;
}

private byte[] GetAudio(string id)
{
    string accessKey = Cp.Service.Settings.AccessKey;
    string secretAccessKey = Cp.Service.Settings.SecretAccessKey;

    string url = string.Format("https://....../......php?access_key={0}&secret_access_key={1}&action=recording.download&format=mp3&sid={2}", accessKey, secretAccessKey, id);

    byte[] data = null;

    try
    {
        using (var wc = new System.Net.WebClient())
        {
            data = wc.DownloadData(url);
        }
    }
    catch //(Exception ex)
    {
        //forbidden, proxy issues, file not found (404) etc
        //ms = null;
    }

    return data;
}

这将首先下载音频数据。有没有办法将音频流从 url 直接流式传输到响应?这样,服务器不会在内存中保存数据bytes[]?有时,数据量很大。

谢谢

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    您的代码中有两个地方使用byte 数组。

    WebClient.DownloadData 将整个远程资源作为byte[] 返回。如果您改为使用WebClient.OpenRead(即wc.OpenRead(url);),您将获得一个Stream,通过它可以读取远程资源。

    此外,您正在实例化 ByteArrayContent 以向您的远程客户端提供音频数据。我看到还有一个StreamContent class,您可以使用它指定一个Stream 发送到远程客户端。

    这是未经测试的,我不确定在使用 response.Content 之前处置 WebClient 是否会有问题,或者是否/如何/在哪里应该明确处置 wc.OpenRead(url) 返回的 Stream,但是这个应该给你的想法...

    public async Task<HttpResponseMessage> StreamAudioAsync(string id)
    {
        var response = Request.CreateResponse(HttpStatusCode.Moved);
    
        response.StatusCode = HttpStatusCode.OK;
        using (var wc = new System.Net.WebClient())
        {
            string accessKey = Cp.Service.Settings.AccessKey;
            string secretAccessKey = Cp.Service.Settings.SecretAccessKey;
            string url = string.Format("https://....../......php?access_key={0}&secret_access_key={1}&action=recording.download&format=mp3&sid={2}", accessKey, secretAccessKey, id);
    
            response.Content = new StreamContent(wc.OpenRead(url));
        }
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("audio/wav");
    
        return response;
    }
    

    【讨论】:

    • 谢谢,它有效。也许对其他人有用: 1. Dispose WebClient 就可以了。 2. OpenRead 创建的流不应该被 Disposed,这是有道理的,因为它是流式传输的。不确定我们是否需要以及在哪里处理它。
    猜你喜欢
    • 1970-01-01
    • 2010-09-14
    • 2014-11-10
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 2014-05-29
    • 1970-01-01
    相关资源
    最近更新 更多