Asp.net
ASP.Net Core Web Api 中的非同步影片流不起作用
我以前使用過http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/這種技術,並且非常適合非同步影片流。
但對於 ASP.NET Core,這種方式無法按預期工作。
按影片流類是:
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(); } } }對於影片流請求,我有以下操作:
[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; }由於預設情況下 Asp.Net Core 沒有用於影片/mp4 的內置媒體格式化程序,因此我創建了以下自定義媒體格式化程序
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 ??? } }並將以下行添加到 Startup.cs
services.AddMvc(options => { options.OutputFormatters.Add(new VideoOutputFormatter()); });它實際上呼叫了我的自定義格式化程序。我不知道如何為影片/mp4 實現這個自定義媒體格式化程序。任何人都可以幫助我嗎?
查看 Asp.NET Core 的原始碼確實幫助我找到了這個問題的答案。他們有一個非常接近您想要使用的StreamOutputFormatter類。我只需要修改它來尋找
PushStreamContent它,它就像一個魅力。這是我完整的 VideoOutputFormatter:
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); } } }與其將 in 包裝
HttpResponseMessage在ObjectResult控制器中,不如將PushStreamContent對象推入in 中ObjectResult。您仍然需要MediaTypeHeaderValue在ObjectResult.