7

Tôi đã sử dụng http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/ kỹ thuật này trước đây và hoạt động hoàn hảo để phát video không đồng bộ.Chạy video không đồng bộ trong ASP.Net Core Web Api không hoạt động

Nhưng đối với ASP.NET Core theo cách này không hoạt động như mong đợi.

By lớp video streaming là:

public class VideoStream 
{ 
    private readonly string _filename; 
    public VideoStream(string filename) 
    { 
     _filename = filename; 
    } 

    public async Task WriteToStream(Stream outputStream, HttpContent content, TransportContext context) 
    { 
     try 
     { 
      var buffer = new byte[65536]; 
      using (var video = File.Open(_filename, FileMode.Open, FileAccess.Read)) 
      { 
       var length = (int)video.Length; 
       var bytesRead = 1; 
       while (length > 0 && bytesRead > 0) 
       { 
        bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length)); 
        await outputStream.WriteAsync(buffer, 0, bytesRead); 
        length -= bytesRead; 
       } 
      } 
     } 
     catch (Exception) 
     { return; } 
     finally 
     { 
      outputStream.Flush(); 
      outputStream.Dispose(); 
     } 
    } 
} 

và tôi có hành động sau đây để yêu cầu streaming video:

[HttpGet] 
    [Route("[action]")] 
    public IActionResult GetVideo(int id) 
    { 
     var fileName = GetVideoFileName(id); 
     var video = new VideoStream(fileName); 
     var response = new HttpResponseMessage 
     { 
      Content = new PushStreamContent(video.WriteToStream, new MediaTypeHeaderValue("video/mp4")) 
     }; 
     var objectResult = new ObjectResult(response); 
     objectResult.ContentTypes.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("video/mp4")); 
     return objectResult; 
    } 

Kể từ khi theo mặc định Asp.Net Core không có built-in Truyền thông Trình định dạng cho video/mp4 Tôi đã tạo Hình thức Truyền thông tùy chỉnh sau đây

public class VideoOutputFormatter : IOutputFormatter 
{ 
    public bool CanWriteResult(OutputFormatterCanWriteContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException(nameof(context)); 
      return true; 
    } 
    public async Task WriteAsync(OutputFormatterWriteContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException(nameof(context)); 
     var response = context.HttpContext.Response; 
     response.ContentType = "video/mp4"; 

     How to impelemnt ??? 
    } 
} 

và thêm f ollowing line to Startup.cs

services.AddMvc(options => 
     { 
       options.OutputFormatters.Add(new VideoOutputFormatter()); 
     }); 

Nó thực sự gọi trình định dạng tùy chỉnh của tôi. Tôi không biết cách triển khai trình định dạng phương tiện tùy chỉnh này cho video/mp4. Bất cứ ai cũng có thể giúp tôi?

Trả lời

3

Nhìn vào mã nguồn cho Asp.NET Core thực sự đã giúp tôi tìm câu trả lời cho câu hỏi này. Họ có một lớp học StreamOutputFormatter thực sự gần với những gì bạn muốn sử dụng. Tôi chỉ phải sửa đổi nó để tìm kiếm PushStreamContent và nó hoạt động như một sự quyến rũ.

Dưới đây là VideoOutputFormatter hoàn chỉnh của tôi:

public class VideoOutputFormatter : IOutputFormatter 
{ 
    public bool CanWriteResult(OutputFormatterCanWriteContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException(nameof(context)); 

     if (context.Object is PushStreamContent) 
      return true; 

     return false; 
    } 

    public async Task WriteAsync(OutputFormatterWriteContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException(nameof(context)); 

     using (var stream = ((PushStreamContent)context.Object)) 
     { 
      var response = context.HttpContext.Response; 
      if (context.ContentType != null) 
      { 
       response.ContentType = context.ContentType.ToString(); 
      } 

      await stream.CopyToAsync(response.Body); 
     } 
    } 
} 

Thay vì gói các HttpResponseMessage trong ObjectResult trong điều khiển của bạn, bạn sẽ muốn chỉ xô đối tượng PushStreamContent vào ObjectResult để thay thế. Bạn vẫn cần đặt MediaTypeHeaderValue trên ObjectResult.

+0

cảm ơn bạn đã chia sẻ nhưng tôi không thể tìm thấy PushStreamContent trong lõi mạng, bạn có mẫu hay gì không? – Soren

+1

@ Thật không may, tôi không thể tìm thấy giải pháp nào cả và kết thúc chỉ phục vụ video thông qua proxy ngược như nginx. – villecoder

Các vấn đề liên quan