我正在使用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;
}