C # core HTML5 видео не будет загружаться в Chrome с тегами диапазона - PullRequest
0 голосов
/ 22 сентября 2019

В настоящее время мы работаем над простой HTML-страницей, которая загружает видео через тег HTML5.На бэкэнде у нас есть конечная точка webapi, которая возвращает видео (или фрагмент видео) с заголовком «Accept-Ranges: bytes».

Кажется, что Chrome выполняет два вызова конечной точки, один с байтами: 0- и один с байтами: 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

1 Ответ

0 голосов
/ 25 сентября 2019

Есть несколько проблем с вашей реализацией (и, пожалуйста, опубликуйте полный код, с этими фрагментами невозможно понять, что такое s, когда вы используете s.Item2):

  1. fs.Seek(0, SeekOrigin.Begin); - либо это опечатка, либо вы не поняли, как работает заголовок диапазона.Вы должны стремиться к смещению, указанному как начало диапазона, и обслуживать его только до конца диапазона.
  2. При обработке значений диапазона вы в настоящее время оставляете last равным 0, если оно не предоставлено, нопомните, что в этом случае вам все равно нужно подавать содержимое от начала до конца файла.
  3. Чтобы играть хорошо, вы также должны установить заголовок Content-Range в ответе,поскольку вы отвечаете с помощью 206.

Редактировать: Если вы используете FileResult вместо FileStreamResult, он позаботится о самом заголовке Range, просто имейте в виду, что поведение меняется в 2.1 - ниже 2.1 класс выполняет обработку автоматически, так как в 2.1 вам нужно включить свойство EnableRangeProcessing в FileResult, чтобы обработка произошла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...