How to make a video file available for viewing in the browser as PDF?

Asked

Viewed 139 times

4

How to make a file available for download and viewing in browser?
For example, files of the type pdf and mp4.

When I want to make available to download the file I simply use the following routine:

public ActionResult Download(string fileName)
{
    var path = Server.MapPath("~/Arquivos/Biblioteca/") + fileName;
    return File(path, MimeMapping.GetMimeMapping(path), Path.GetFileName(path));
}

While trying to make available to be viewed in the browser I tried the following:

public ActionResult OpenFile(string fileName)
{
    var path = Server.MapPath("~/Arquivos/Biblioteca/") + fileName;
    return File(path, MimeMapping.GetMimeMapping(path));
}

The difference is that I did not inform the property referring to the file name for download.

On my computer (mode debug) the video and PDF are shown in the browser as expected.

Vídeo no browser

But when trying to make available on the server, both are not opened and thus is made to download the file.

First I was trying to open the file directly, without passing a controller and an action, then time worked, not time, as it gave file error not found. Probably due to the size of the name.

For it to be possible I needed to register the mime on the server IIS (video/mp4).

But as I said, directly gives error and for the sake of good practices, I wish not to access the file directly.

So, how to make files available for viewing in the browser, when possible?

1 answer

1

You should not serve video as a file, but as a Stream.

To do this, implement a class that prepares the Stream from the video to you:

public class VideoStream
{
   private readonly string _arquivo;

   public VideoStream(string arquivo)
   {
      _filename = @"C:\Seu\Diretorio\De\Video\" + arquivo;
   }

   public async void WriteToStream(Stream outputStream, HttpContent content = null, TransportContext context = null)
   {
      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 (HttpException ex)
      {
         return;
      }
      finally
      {
         outputStream.Close();
      }
   }
}

Here we can have two solutions: one for MVC, the other for Web API.

Web API

public class VideosController : ApiController
{
   public HttpResponseMessage Get(string videoNome)
   {
      var video = new VideoStream(videoNome + ".mp4");

      var response = Request.CreateResponse();
      response.Content = new PushStreamContent(video.WriteToStream, new MediaTypeHeaderValue("video/mp4"));

      return response;
   }
}

MVC

Implement before a VideoResult:

public class VideoResult : ActionResult 
{ 
    public override void ExecuteResult(ControllerContext context) 
    { 
        var queryString = context.Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value);
        var videoStream = new VideoStream(queryString["videoNome"]);
        // Header
        context.HttpContext.Response.AddHeader("Content-Disposition", "attachment; filename=" + queryString["videoNome"] + ".mp4"); 
        videoStream.WriteToStream(context.HttpContext.Response.OutputStream);
    } 
} 

And the Action:

    public ActionResult Index(string videoNome)
    { 
        return new VideoResult(); 
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.