asp.net-coresafarivideo-streamingrange-header

Stream video to Safari from .NET Core


Streaming works well in all browsers except Safari. As I know request should support range header.

Here is the code that I am using:

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

Request:

curl --range 0-99 https://localhost:44312/GetVideoStream -o D:\test

is working good and saves only 100bytes to file.

Have trying also variations of controls muted playsinline preload="metadata" and type="video/mp4"


Solution

  • Finally, I was able to force Safari stream videos. It was required to set "Content-Range" header:

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