Stream.WriteAsync throws The remote host closed the connection exception

6

I have an asp.net webforms application and to retrieve video from database that saved in varbinary format and show it as html5 video tag.

after a googled it, i found a way that i should play it asynchronously using ASP.Net WebApi, it works fine

First problem

When video played first time and the user click on play button to replay the video, The remote host closed the connection. The error code is 0x800704CD exception throws at line await outputStream.WriteAsync(buffer, 0, bytesRead);.

Second Problem

When user click on seek bar, the video goes to played from first.

NOTE

Internet Explorer 11 plays the video without any problem, but firefox and chrome have both problems.

how can i solve this problem?

Here is my codes:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "VideoApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

public class VideoController : ApiController
{
    public IVideoRepository videoRepository;

    public HttpResponseMessage Get(long id)
    {
        try
        {
            videoRepository = new VideoRepository();
            Video video = videoRepository.load(id);

            if (video != null)
            {
                var videoStream = new VideoStream(video.fileContent);
                string ext = video.extension;

                var response = Request.CreateResponse();

                response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)videoStream.WriteToStream, new MediaTypeHeaderValue("video/" + ext));

                response.Content.Headers.Add("Content-Disposition", "attachment;filename=" + video.fullName.Replace(" ", ""));
                response.Content.Headers.Add("Content-Length", videoStream.FileLength.ToString());

                return response;
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
        }
        catch (Exception e)
        {
            return Request.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, e);
        }
    }
}

public class VideoStream
{
    private readonly byte[] _fileContent;
    private long _contentLength;

    public long FileLength
    {
        get { return _contentLength; }
    }

    public VideoStream(byte[] content)
    {
        _contentLength = content.Length;
        _fileContent = content;
    }

    public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
    {
        try
        {
            var buffer = new byte[65536];

            MemoryStream memoryStream = new MemoryStream();
            memoryStream.Write(_fileContent, 0, _fileContent.Length);
            memoryStream.Position = 0;
            using (memoryStream)
            {
                var length = (int)memoryStream.Length;
                var bytesRead = 1;

                while (length > 0 && bytesRead > 0)
                {
                    bytesRead = memoryStream.Read(buffer, 0, Math.Min(length, buffer.Length));
                    await outputStream.WriteAsync(buffer, 0, bytesRead);
                    length -= bytesRead;
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            outputStream.Close();
        }
    }
}

UPDATE

after this way didn't worked properly, i had to use this way, but the new way have seekbar problem, when user click on seek bar to seek to time it dosn't work in Chrome and FireFox.

asp.net
asp.net-web-api
webforms
video-streaming
html5-video
asked on Stack Overflow May 15, 2015 by Rasool Ghafari • edited May 23, 2017 by Community

1 Answer

0

ASP.NET is not very good at video streaming. Third-party video streaming solution is the best option.

There are a few video-streaming servers (like Wowza), but they require installation and you have to buy license.

Cloud streaming service is another option. I personally prefer AWS Cloudfront. They propose distribution in various globally distributed content delivery zones. It costs really cheap and you can be sure that it will survive any traffic amount (even if all your users will watch the same video simultaneously).

answered on Stack Overflow May 30, 2015 by kreig

User contributions licensed under CC BY-SA 3.0