0

I'm trying to stream a Video, that is saved as an attachment in a Ravendb-Database, through an ASP.NET MVC 5 Action to a WebBrowser. It is working with the following Code, but the Video gets fully downloaded before the Video starts. I don't get what I'm doing wrong.

I found some ways to do Streaming in MVC, but they seem to expect a Seekable Stream - but the stream I receive from Ravendb is not seekable; it even does not provide a length. So the only way of doing it would be to copy the ravendb-stream to a memorystream and provide a PartialContent or similar from there.

Does anybody have a better solution? I cannot be the only one that wants to stream a Video from a database without loading the full Video into Memory before sending it.

I'm fetching the attachment from ravendb like this:

public async Task<System.IO.Stream> GetAttachmentAsync(IAttachmentPossible attachedObject, string key)
{
    using (var ds = InitDatabase())
    {
        using (var session = ds.OpenAsyncSession())
        {
            try
            {
                var result = await session.Advanced.Attachments.GetAsync(attachedObject.Id, key);
                return result.Stream;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }
}

After that I send the stream to the browser like this:

var file = await _database.GetAttachmentAsync(entry, attachmentId);

HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.OK);
msg.Content = new StreamContent(file);
msg.Content.Headers.ContentType = new MediaTypeHeaderValue("video/mp4");
return msg;

Any ideas? Thank you very much!

Camilo Terevinto
  • 26,697
  • 6
  • 67
  • 99
TopperDEL
  • 5
  • 5
  • This is an answer that would help me if my ravendb-stream would be seekable: https://stackoverflow.com/a/39247028/10291808 – TopperDEL Aug 29 '18 at 19:49

1 Answers1

0

I think that it is correct to copy the stream into a memory stream. With the answer you linked (https://stackoverflow.com/a/39247028/10291808) you can do streaming.

Maybe could be an idea to think about the multiple calls that will done to retrieve the file from the db (maybe you could cache the file for a limited time to improve performance).

Embri
  • 592
  • 2
  • 15
  • But what if I have GB sized Video files? Holding them in Memory might lead to Problems. And I would still have to wait for the Video to load from ravendb to Memory until I could serve the first Byte to the Client. – TopperDEL Aug 30 '18 at 14:38
  • @TopperDEL You could store it splitted by the range you want to download. If you have GB of video the problem remain also if you load it from Raven or if you keep it in memory. – Embri Aug 31 '18 at 07:05
  • Well, the main Problem seems to be that raven does not provide a way to Access a range from a binary attachment. It wouldn't be a Problem if this would be possible. Keeping only a Portion of that GB-Video in Memory doesn't work with the curretn raven-implementation, as I can only download the whole file at once. Nevertheless, Thank you. – TopperDEL Aug 31 '18 at 11:03