c# - C# 核心 HTML5 视频不会在带有范围标签的 chrome 中加载
问题描述
我们目前正在开发一个通过 HTML5 标签加载视频的简单 HTML 页面。在后端,我们有一个 webapi 端点,它返回带有“Accept-Ranges: bytes”标头的视频(或视频块)。
Chrome 似乎对端点进行了两次调用,一次调用 bytes:0- 一次调用 bytes:10452992-
视频是 MP4 和 10498677 字节长。
但是,视频不会播放,只是加载为黑屏。
我们的端点如下所示:
public async Task<IActionResult> StreamVideoWithToken(string token, long id)
要获取起始字节位置,我们使用:
var range = Request.Headers["Range"].First();
var rangeType = range.Split('=');
if (rangeType[0] == "bytes")
{
var firstLast = rangeType[1].Split('-');
long first = 0;
if (firstLast.Length > 0 && firstLast[0] != "")
if (!long.TryParse(firstLast[0], out first)) first = 0;
long last = 0;
if (firstLast.Length > 1)
if (!long.TryParse(firstLast[1], out last)) last = 0;
byteRange.start = first;
byteRange.end = last;
}
这将获取起始字节。
然后我们从服务器获取流并将其作为响应传回。
// Returns a stream of only the required bytes (start to EOF)
var fs = _assetService.GetContentStream(asset.Id, byteRange.start);
fs.Seek(0, SeekOrigin.Begin);
Response.ContentLength = byteRange.start + s.fetchedLength;
if (byteRange.start > 0)
{
Response.StatusCode = (int)HttpStatusCode.PartialContent;
Response.Headers.Add("Content-Range", byteRange.start + "-" + (byteRange.start + s.fetchedLength));
}
return new FileStreamResult(fs, "video/mp4")~;
如果我们关闭“Accept-Ranges: bytes”标头,它会对完整视频发出一个请求,该视频成功播放,但无法导航到任何特定时间。
请求如下所示:
GET: https://localhost:44392/api/asset/StreamVideo/xxx/1261
Accept-Encoding: identity;q=1, *;q=0
Range: bytes=10452992-
Referer: http://localhost:4200/catalogue/a/1261
Sec-Fetch-Mode: no-cors
响应如下所示:
Status Code: 206 (Partial Content)
accept-ranges: bytes
access-control-allow-credentials: true
access-control-allow-headers: Authorization, Content-Type, x-auth-token
access-control-allow-origin: *
access-control-expose-headers: X-Error-Message
content-length: 45685
content-range: 10452992-10498677
content-type: video/mp4
date: Sun, 22 Sep 2019 14:49:14 GMT
server: Kestrel
status: 206
x-powered-by: ASP.NET
x-sourcefiles: xxx
解决方案
您的实现存在几个问题(请发布完整的代码,使用这些代码段无法理解s
您正在使用的内容s.Item2
):
fs.Seek(0, SeekOrigin.Begin);
- 要么这是一个错字,要么你不明白范围标题是如何工作的。您必须寻找指定为范围开始的偏移量,并且只提供到范围的结束。- 在处理范围值时,如果未提供,则当前保留
last
为 0,但请记住,在这种情况下,您仍然需要提供从文件开头到结尾的内容。 - 为了玩得好,您还应该在响应中设置Content-Range标头,因为您正在回复 206。
编辑:
如果您使用FileResult而不是FileStreamResult
它将处理Range
标头本身,请注意 2.1 中的行为更改 - 低于 2.1 类会自动进行处理,因为 2.1 您需要启用EnableRangeProcessing
属性FileResult
才能进行处理。
推荐阅读
- django - 在 django 中使用位置的最佳方式是什么
- three.js - 十二面体表面的星暴
- google-sheets - 将值包含逗号的列中的每一行拆分为转置行
- ios - onAppear SwiftUI iOS 14.4
- python - Python中向量化矩阵的对应坐标
- r - 为什么我无法在我的新 Windows 计算机上安装 R 包?
- javascript - 在我点击隐藏后,屏幕将向下,精确到页脚
- c# - 接受与剧作家夏普的对话
- node.js - 如何使用 PouchDB (leveldb) 将我的电子应用程序与 Cloudant 或任何其他支持 couchDB 和同步的数据库连接起来
- r - 在解释回归模型中的 beta 估计值时,排序顺序是否重要?