C# Dynamic Streaming Video via Handler (.ashx) with Range Downloader ASP MVC

This tutorial is to show that how video playing is possible via a dynamic URL and hiding obsolete base URL. We have added to basic programs in it one is ProcessRequest() used to get file and process data o the file via streamer, second is RangeDownload(), which is required to download video http-range.

here is the full source class in .ashx file i used.

with following mysite.com/watch.ashx?id=1039 returns a video file.


public class Video : IHttpHandler {

    public void RangeDownload(int id, HttpContext context)
    {

        //connecton to database
        VideosDB db = new VideosDB();
        //Entity
        var get = db.MyvideosDB.FirstOrDefault(p => p.Video == id);
        //path to video ile
        string fullpath = context.Server.MapPath("~/cdn_users/" + get.Postedby + "/" + get.VideoURL);
        long size, start, end, length, fp = 0;
        using (StreamReader reader = new StreamReader(fullpath))
        {

            size = reader.BaseStream.Length;
            start = 0;
            end = size - 1;
            length = size;

            context.Response.AddHeader("Accept-Ranges", "0-" + size);

            if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
            {
                long anotherStart = start;
                long anotherEnd = end;
                string[] arr_split = context.Request.ServerVariables["HTTP_RANGE"].Split(new char[] { Convert.ToChar("=") });
                string range = arr_split[1];

                if (range.IndexOf(",") > -1)
                {
                    context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
                    throw new HttpException(416, "Requested Range Not Satisfiable");

                }

                if (range.StartsWith("-"))
                {
                    anotherStart = size - Convert.ToInt64(range.Substring(1));
                }
                else
                {
                    arr_split = range.Split(new char[] { Convert.ToChar("-") });
                    anotherStart = Convert.ToInt64(arr_split[0]);
                    long temp = 0;
                    anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt64(arr_split[1]) : size;
                }
                anotherEnd = (anotherEnd > end) ? end : anotherEnd;
                if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
                {

                    context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
                    throw new HttpException(416, "Requested Range Not Satisfiable");
                }
                start = anotherStart;
                end = anotherEnd;

                length = end - start + 1;
                fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
                context.Response.StatusCode = 206;
            }
        }
        context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
        context.Response.AddHeader("Content-Length", length.ToString());
        context.Response.WriteFile(fullpath, fp, length);
        context.Response.End();

    }

    public void ProcessRequest(HttpContext context)
    {
        string id = context.Request["id"];
        int newid;
        int.TryParse(id, out newid);

       
        VideosDB db = new VideosDB();

        var get = db.MyvideosDB.FirstOrDefault(p => p.Video == newid);

        string mimetype = "video/mp4";
        string fullpath=context.Server.MapPath("/cdn_users/"+get.Postedby+"/"+get.VideoURL);       
        if (System.IO.File.Exists(fullpath))
        {
           
            context.Response.ContentType = mimetype;
            if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
            {
                RangeDownload(newid, context);
            }
            else
            {
                long fileLength = File.OpenRead(fullpath).Length;
                context.Response.AddHeader("Content-Length", fileLength.ToString());
                context.Response.WriteFile(fullpath);            
            }
        }
        else
        {
            throw new HttpException(404, "Video Not Found Path:"+fullpath);
        }
    }
   
    public bool IsReusable {
        get {
            return false;
        }
    }

}

Thanks g . Keep Visiting.

0 comments:

Post a Comment