如何使用 ASP.NET MVC 流式传输视频文件
本文关键字:传输 视频 文件 MVC 何使用 ASP NET | 更新日期: 2023-09-27 18:34:28
我正在开发一个网站,人们可以在其中访问音频和视频文件。我有下载文件的代码,它由以下两种操作方法组成......
public ActionResult GetAudioFile(int id) {
return GetFile(id, true);
}
public ActionResult GetVideoFile(int id) {
return GetFile(id, false);
}
private ActionResult GetFile(int id, bool isAudio) {
// Code to get info about the file, etc omitted for clarity
string downloadFileName = // full path to audio/video file
byte[] bytes = GetFileBytes(fileName); // also omitted
return File(bytes, (isAudio ? "audio/mpeg" : "video/mp4"), downloadFileName + (isAudio ? ".mp3" : ".mp4"));
}
这些都可以正常工作,我可以下载任何一种类型的文件。
我现在想添加两个 Razor 视图,一个用于收听音频文件,另一个用于查看视频。我在音频视图上做了以下操作,它工作正常...
<audio src='@Url.Action("GetAudioFile", "Search", new {ID = @Model.ID})'
controls preload="auto"></audio>
然后我尝试对视频视图做同样的事情......
<video src='@Url.Action("GetVideoFile", "Search", new {ID = @Model.ID})'
controls preload="auto" width="640" height="368"></video>
但是,当我尝试运行它时,这会产生一个System.OutOfMemoryException。每个视频平均约为400-500Mb。
然后,我尝试使用Response.TransmitFile方法,如下所示...
Response.ContentType = "video/mp4";
Response.AddHeader("content-disposition", "attachment; filename=myvideo.mp4"));
Response.TransmitFile(fileName);
Response.End();
return null;
。但这行不通。在Chrome中,我可以在控制台中看到消息"资源解释为文档,但使用MIME类型视频/mp4传输",而在FireFox中,我在视频控件中收到相同的消息。
有人知道我该如何解决这个问题吗?理想情况下,我想流式传输文件,以便在第一个字节到达用户后立即开始播放,而不是让他们等到文件完全下载。
我已经尝试了几个Javascript视频播放器,但都取得了任何成功。
更新我想知道问题是否根本不是控制器操作,因为我尝试将 Web 浏览器直接指向视频文件,我得到了看起来像音频播放器的东西,但没有视频窗格,当我单击播放按钮时没有任何反应。不确定这是否有帮助。
MvcController
的File
方法返回一个FileContentResult
。后者不流式传输内容。据我所知,MvcController
根本不支持流媒体。
您可能想尝试ApiController
和PushStreamContent
。后者提供了通过回调方法异步写入输出流的可能性。为此,您需要在解决方案中使用实际流。使用 byte[]
将始终将整个文件内容加载到内存中。
在此处查看详细教程:使用 ASP.NET Web API 异步流式传输视频
从数据库/PC播放视频的可能方法
<div height="240" width="320" controls>
<video>
<source src="@Url.Content(Model.VideoTable.VideoPath)" type='video/mp4' />
</video>
</div>
源属性需要获取 url 而不是字符串,
所以@Url.Content
将视频路径转换为 URL
控制器
Imports System.Web.Mvc
Namespace Controllers
Public Class HomeController
Inherits Controller
Function Index() As ActionResult
Return View()
End Function
Sub movie(id As Integer) 'As ActionResult
Dim fm As String = "D:'Downloads'Rhoma Irama Riza Umami - Suratan (Official Music Video).mp4"
If id = 2 Then fm = "D:'Downloads'JERA riza umami lagu dangdut YouTube.mp4"
If id = 3 Then fm = "D:'Downloads'FTV Trans TV CINTANYA ANAK HITS KEKINIAN RIDWAN GHANI.mp4"
Dim fi As New IO.FileInfo(fm)
Dim fs As IO.FileStream = IO.File.OpenRead(fm)
Dim buff_size As Integer = 1048576 '1Mb buffering
Dim buff(buff_size) As Byte, max_l As Integer = fs.Length - 1
If Not Request.ServerVariables("HTTP_RANGE") Is Nothing Then
Dim r() As String = Request.ServerVariables("HTTP_RANGE").Split("=")
Dim s() As String = r(1).Split("-")
Dim bs As Integer = 0, be As Integer = 0, l As Integer = 0
If IsNumeric(s(0)) Then bs = s(0)
If IsNumeric(s(1)) Then be = s(1)
If bs >= 0 And bs <= max_l Then
Response.StatusCode = 206
Response.ContentType = "video/" & fi.Extension
Response.AddHeader("Accept-Ranges", "0-" & max_l)
Response.AddHeader("Content-Range", "bytes " & bs & "-" & bs + buff_size & "/" & max_l)
Response.AddHeader("Content-Length", buff_size)
fs.Position = bs
l = fs.Read(buff, 0, buff.Length)
If l > 0 Then Response.OutputStream.Write(buff, 0, buff.Length)
End If
End If
End Sub
End Class
End Namespace
视图(我使用剃刀(
<body>
<button onclick="video1.src='@Url.Action("movie", "home", New With {.id = 1})'">1</button>
<button onclick="video1.src='@Url.Action("movie", "home", New With {.id = 2})'">2</button>
<button onclick="video1.src='@Url.Action("movie", "home", New With {.id = 3})'">3</button>
<video controls autoplay="autoplay" id="video1" width="920">
<source src="@Url.Action("movie", "home", New With {.id = 1})" type="video/mp4">
Your browser does not support HTML5 video.
</video>
</body>