c# - 如何正确地为<audio>提供数据?

标签 c# asp.net html cross-browser html5-audio

我正在通过 .aspx 页面为 HTML5 音频提供二进制数据。该文件可以播放,但在 Safari (iPad)、Chrome 和 Firefox 中 SeekBar 和重播有问题。
编辑 我已简化(希望不要太多)代码并提供完整列表(页面文件名显然是 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-LengthContent-Type提供 header 。两个 <audio>当直接访问文件或通过 .aspx 页面访问文件时,标记启用比较行为。

问题是如何向<audio>提供数据标记在所有必需的浏览器(ff、safari、chrome、IE9+)上都能正常运行。

问题

Safari (iPad):按下播放按钮时会播放声音,但出现的是“Streaming ...”而不是 Seek Bar,并且播放似乎永远持续,声音无法重播。
Firefox(windows): 显示搜索栏,但显示增加的时间直到结束,并且在重播时行为正确。
Chrome(windows): 搜索栏正确但无法重播。
IE10: 好的

我在上找到了类似的问题但没有答案。通过观察另一个带有 fiddler 的页面,标题似乎是 Accept-Ranges: bytesContent-Range: bytes 0-8100780/8100781可以帮忙。但是提供必要的功能似乎太难了,只是尝试所以我没有尝试。

注意 我正在 How to play .m4a with HTML5 audio in IE(9+) and Safari (Pad)? 中寻找其他相关问题的解决方案

最佳答案

简单回答:需要处理浏览器range request .

完整故事

比较Fiddler时捕获 Firefox 和 IIS 之间的通信 我注意到直接链接的响应状态是 206 Partial Content而对于间接链接 200 OK .
对请求的更仔分割析表明 Firefox 请求 Range: bytes=0-和 iPad Range: bytes=0-1之后 Range: bytes=0-fullsize (Capture Traffic from iOS Device)。
设置Response.StatusCode = 206足以骗过 Firefox 而不是 Safari。但我知道了关键信息,剩下的就很简单了。有必要兑现range请求见:SO:HTML5 video will not loop .我在 Aha! #1 – ASP.NET ASHX Video Streaming for HTML5 Video 中找到了如何操作的说明.所以新的代码是(只呈现事件部分其余与答案中的相同):

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

添加其他 header (Content-DispositionAccept-RangesAccess-Control-Allow-Origin)可能很方便,但目的是尽可能简单地提供解决方案。

经验教训:如果我没有固定到 <audio>并且还寻找了<video> ,我会更快地找到解决方案。

关于c# - 如何正确地为<audio>提供数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18336174/

相关文章:

c# - EF Code-First 继承单个基类以实现简单的历史性

c# - 适用于 IEnumerable<T> 和 IQueryable<T> 的扩展方法?

asp.net - Gridview中的Parent和NamingContainer有什么区别

javascript - 未捕获的 TypeError : $(. ..).tabs 不是函数

javascript - HTML 中是否存在属性节点?

android - 在android应用程序中加载非缓存的webview

javascript - 获取动态创建元素的整个 HTML

c# - 从 WPF 执行存储过程

c# - 在 C# 解决方案中,您在哪里声明解决方案范围的枚举?

jquery - 如何返回Web API数据