如何使用ASP.NET MVC流式传输视频文件?

时间:2014-12-17 22:14:26

标签: c# asp.net-mvc video video-streaming

我正在开发一个人们可以访问音频和视频文件的网站。我有下载文件的代码,它包含两个动作方法,如下所示......

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中,我可以看到消息&#34;资源被解释为文档但是使用MIME类型转换为video / mp4&#34;在控制台和FireFox中,我在视频控件中收到相同的消息。

任何人都知道如何解决这个问题?理想情况下,我想流式传输文件,以便在第一个字节到达用户时立即开始播放,而不是让它们等到文件完全下载完毕。

我已尝试过几个Javascript视频播放器,但这些播放器也取得了成功。

更新我想知道控制器操作是否完全没问题,因为我尝试将网络浏览器直接指向视频文件,我看起来像一个音频播放器,但没有视频窗格,当我点击播放按钮时没有任何反应。不确定这是否有帮助。

3 个答案:

答案 0 :(得分:5)

File MvcController方法返回FileContentResult。后者不会流式传输内容。据我所知,MvcController根本不支持流式传输。

您可以尝试ApiControllerPushStreamContent。后者提供了通过回调方法异步写入输出流的可能性。您需要在解决方案中使用实际流。使用byte[]将始终将整个文件内容加载到内存中。

请在此处查看详细教程:Asynchronously streaming video with ASP.NET Web API

答案 1 :(得分:0)

从数据库/ PC播放视频的可能方式

<form id="form1" name="form1" action='page2.php' method="post">
<input type="text" id="test" name="test" value="<?php echo 'test'; ?>" />
<input type='submit' value='submit' />
</form>

//i want to get the value here but it's not working because all value pass to page2.php
$value = $_POST['test'];
echo $value; 

source属性需要获取url而不是字符串,

所以<div height="240" width="320" controls> <video> <source src="@Url.Content(Model.VideoTable.VideoPath)" type='video/mp4' /> </video> </div> 将视频路径转换为Url

答案 2 :(得分:-1)

控制器

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

VIEWS(我使用Razor)

<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>