Потоковое видео в Safari из .NET Core
Потоковая передача работает во всех браузерах, кроме Safari. Насколько я знаю, запрос должен поддерживать заголовок диапазона.
Вот код, который я использую:
public async Task<FileStreamResult> GetVideoStream()
{
if (Request.Headers.ContainsKey("Range"))
{
Request.Headers.TryGetValue("Range", out var range);
_httpClient.DefaultRequestHeaders.Add("Range", range.ToString());
}
var stream = await _httpClient.GetStreamAsync(_url);
return File(stream, "video/mp4", true);
}
Запрос:
curl --range 0-99 https://localhost:44312/GetVideoStream -o D:\test
работает нормально и сохраняет в файл только 100 байт.
Попробовали также варианты управления отключением звука playsinline preload="metadata" и type="video/mp4"
2 ответа
Решение
Наконец, я смог заставить Safari потоковое видео. Требовалось установить заголовок Content-Range:
public async Task<FileStreamResult> GetVideoStream()
{
if (Request.Headers.ContainsKey("Range"))
{
_httpClient.DefaultRequestHeaders.Remove("Range");
var headersResponse = await _httpClient.GetAsync(_url, HttpCompletionOption.ResponseHeadersRead);
Request.Headers.TryGetValue("Range", out var range);
if (headersResponse.IsSuccessStatusCode && headersResponse.Content.Headers.GetValues("Content-Length").Any())
HttpContext.Response.Headers.Add("Content-Range", $"{range[0].Replace("=", " ")}/{headersResponse.Content.Headers.GetValues("Content-Length").First()}");
_httpClient.DefaultRequestHeaders.Add("Range", range.ToString());
}
var stream = await _httpClient.GetStreamAsync(_url);
return File(stream, "video/mp4", true);
}
Я думаю, что для правильного ответа "Диапазон" вам необходимо вернуть код состояния "206 частичное содержимое"
давай попробуем:
public async Task<FileStreamResult> GetVideoStream()
{
if (Request.Headers.ContainsKey("Range"))
{
Request.Headers.TryGetValue("Range", out var range);
_httpClient.DefaultRequestHeaders.Add("Range", range.ToString());
}
var stream = await _httpClient.GetStreamAsync(_url);
HttpContext.Response.StatusCode = 206;
return File(stream, "video/mp4", true);
}