How can I transfer a video using ASP.NET MVC?

I am developing a website where people can access audio and video files. I have code for downloading files, which consists of two action methods, as shown below.

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

Both of these work fine, and I can upload any type of file.

Now I want to add two types of Razor, one for listening to the audio file and one for watching the video. I did the following in audio form and it works great ...

 <audio src='@Url.Action("GetAudioFile", "Search", new {ID = @Model.ID})' controls preload="auto"></audio> 

Then I tried to do the same for watching the video ...

 <video src='@Url.Action("GetVideoFile", "Search", new {ID = @Model.ID})' controls preload="auto" width="640" height="368"></video> 

However, this gives a System.OutOfMemoryException exception when I try to run it. Videos averaged around 400-500 MB.

Then I tried to use the Response.TransmitFile method as follows:

  Response.ContentType = "video/mp4"; Response.AddHeader("content-disposition", "attachment; filename=myvideo.mp4")); Response.TransmitFile(fileName); Response.End(); return null; 

... but it does not work. In Chrome, I see the message β€œResource interpreted as a Document but transmitted with the MIME type of video / mp 4” in the console, and in FireFox I get the same message in the video control.

Does anyone know how I can fix this? Ideally, I would like to transfer the file so that it starts playing as soon as the first bytes reach the user, instead of waiting for them until the file is fully loaded.

I tried a couple of Javascript video players but was successful with them as well.

Update . I am wondering if this controller is not a problem, since I tried to point my web browser directly to the video file, and I got what looked like an audio player, but without a video panel, and nothing happens when I press the play button. Not sure if this helps.

+6
source share
3 answers

The File MvcController method returns a FileContentResult . The latter does not transmit the content stream. As far as I know, MvcController does not support streaming at all.

You can try ApiController and PushStreamContent . The latter makes it possible to write to the output stream asynchronously via the callback method. To do this, you will need to work with real threads in your solution. Working with byte[] will always load the entire file into memory.

See the detailed tutorial here: Asynchronous Streaming Video with ASP.NET Web Interface

+3
source

Possible way to play videos from a database / PC

 <div height="240" width="320" controls> <video> <source src="@Url.Content(Model.VideoTable.VideoPath)" type='video/mp4' /> </video> </div> 

the source property should get a url not a string,

therefore @Url.Content converts the video path as Url

0
source

controller

 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 (I use 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> 
-1
source

Source: https://habr.com/ru/post/979811/


All Articles