如何正确地为<;音频>;
本文关键字:音频 gt lt 正确地 | 更新日期: 2023-09-27 18:28:17
我正在为HTML5 audio-through.aspx页面提供二进制数据。该文件可以播放,但SeekBar和Safari(iPad)、Chrome和Firefox中的回放存在问题
编辑我已经简化了代码(希望不要太多),并显示了完整的列表(页面文件名显然是play.aspx)。
<%@ Page Language="C#" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if ( Request["filename"] != null)
{
string FilePath = MapPath(Request["filename"]);
long fSize = (new System.IO.FileInfo(FilePath)).Length;
//Headers
Response.AddHeader("Content-Length",fSize.ToString());
Response.ContentType = "audio/mp3";
//Data
Response.WriteFile(FilePath);
Response.End();
};
}
</script>
<body>
<p>Direct</p>
<audio controls="controls" preload="none">
<source src="sound.mp3" type="audio/mp3" />
</audio>
<p>Provided</p>
<audio controls="controls" preload="none">
<source src="play.aspx?filename=sound.mp3" type="audio/mp3" />
</audio>
</body>
</html>
因此提供了Content-Length
和Content-Type
报头。当直接或通过.aspx页面访问文件时,两个<audio>
标记启用比较行为。
问题是如何向<audio>
标签提供数据,使其在所有必需的浏览器(ff、safari、chrome、IE9+)上都能正常工作。
问题
Safari(iPad):当按下播放按钮时,声音会播放,但有"流媒体…"而不是"搜索栏",播放似乎会持续很久,声音无法重放
Firefox(windows):搜索栏显示,但显示的时间越来越长,直到结束,回放时行为正确
Chrome(windows):搜索栏正确,但无法重播
IE10:正常
我在上发现了类似的问题,但没有答案。从用fiddler观察另一个页面来看,标题Accept-Ranges: bytes
和Content-Range: bytes 0-8100780/8100781
似乎会有所帮助。然而,提供必要的功能似乎太难了,因为只是一个尝试,所以我没有尝试它
注意我正在寻找在IE(9+)和Safari(Pad)中如何使用HTML5音频播放.m4a的其他连接问题的解决方案?
简单答案:有必要处理浏览器range request
。
完整故事
当比较Firefox和IIS之间Fiddler捕获的通信时,我注意到直接链接的响应状态为206 Partial Content
,而间接链接的响应为200 OK
对请求的更仔细分析表明,Firefox在Range: bytes=0-fullsize
(从iOS设备捕获流量)上请求Range: bytes=0-
和iPad Range: bytes=0-1
以及更高版本
设置Response.StatusCode = 206
足以欺骗Firefox,但不能欺骗Safari。但我已经知道了关键信息,休息很简单。有必要遵守range
请求,请参阅:SO:HTML5视频不会循环。我在Aha中找到了如何做到这一点的解释#1–用于HTML5视频的ASP.NET ASHX视频流。因此,新代码是(只显示活动部分,其余部分与答案相同):
protected void Page_Load(object sender, EventArgs e)
{
if ( Request["filename"] != null)
{
string FilePath = MapPath(Request["filename"]);
long fSize = (new System.IO.FileInfo(FilePath)).Length;
long startbyte = 0;
long endbyte=fSize-1;
int statusCode =200;
if ((Request.Headers["Range"] != null))
{
//Get the actual byte range from the range header string, and set the starting byte.
string[] range = Request.Headers["Range"].Split(new char[] { '=','-'});
startbyte = Convert.ToInt64(range[1]);
if (range.Length >2 && range[2]!="") endbyte = Convert.ToInt64(range[2]);
//If the start byte is not equal to zero, that means the user is requesting partial content.
if (startbyte != 0 || endbyte != fSize - 1 || range.Length > 2 && range[2] == "")
{statusCode = 206;}//Set the status code of the response to 206 (Partial Content) and add a content range header.
}
long desSize = endbyte - startbyte + 1;
//Headers
Response.StatusCode = statusCode;
Response.ContentType = "audio/mp3";
Response.AddHeader("Content-Length",desSize.ToString());
Response.AddHeader("Content-Range", string.Format("bytes {0}-{1}/{2}", startbyte, endbyte , fSize));
//Data
Response.WriteFile(FilePath,startbyte,desSize);
Response.End();
};
}
添加其他标头(Content-Disposition
、Accept-Ranges
、Access-Control-Allow-Origin
)可能很方便,但目的是尽可能简单地提供解决方案。
吸取的教训:如果我没有固定到<audio>
,并且也在寻找<video>
,我会更快地找到解决方案。