在 C# 和 MVC 中直接从 URL 将音频流式传输到 Web 浏览器 ASP.NET?



我正在使用ASP.NET MVC和C#进行项目。

一个任务是:当用户单击链接时,它需要从链接中获取ID,然后使用此链接生成外部链接,即音频文件,然后在Web浏览器中播放(不要保存为文件)。

当前的解决方案是:从外部链接下载音频文件,获取字节,然后将其放在响应中,为音频/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[]保存在内存中?有时,数据大小很大。

谢谢

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

WebClient.DownloadData将整个远程资源返回为byte[]。如果您使用的是WebClient.OpenRead(即wc.OpenRead(url);),则获得读取远程资源的Stream

此外,您正在实例化ByteArrayContent,以向远程客户端提供音频数据。我看到还有一个StreamContent类,您可以使用它指定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;
}

最新更新