Upload stream and play video in ASP.NET

24,779

I'm gonna roll the dice that you will eventually respond...

Assuming that you can handle the file upload just fine, you can use ffmpeg to convert the file to FLV format and grab a thumbnail. As Hasan mentioned, ffmpeg works great, plus it has been around a while with lots of support. It's a command line program that operates on parameters, which means you can use it from C#.

You will need to download ffmpeg (exe, no install needed). You can use System.Diagnostics to execute ffmpeg and pass it parameters.

Convert video file to FLV

System.Diagnostics.Process.Start("ffmpeg.exe",
                                 "-i SourceVideoFile.avi ConvertedVideoFile.flv");

Capture thumbnail

System.Diagnostics.Process.Start("ffmpeg.exe",
                                 "-i SourceVideoFile.avi -f image2 -s 320x240 thumbnail.png"); 

You can also use System.Diagnostics.ProcessStartInfo if you need more control, need to capture output, etc.

Once you have the new video file, you should be able to figure out how to play it in a browser :-) If not, take a look at VideoJS or Flowplayer.

Share:
24,779
Radhi
Author by

Radhi

Working in WPF, Asp.net, Silverlight WCF Services, Sql Server, .net, iOS App development

Updated on August 17, 2020

Comments

  • Radhi
    Radhi over 3 years

    I have to make an interface to upload large videos up to 30MB then stream and convert it into FLV format and then play it in a browser... this is required on my site in the "Video Gallery" module. My web application is in C# and ASP.NET. I can also use jQuery.

    I have to send the video file in chunks then merge it at the server, stream it, create thumbnail for the video and then play it.

    Please provide me solution if anybody has.

    I found some code but it is all in PHP. I haven't found any C#, ASP.NET code.

    Finally I got the code to upload the video file in chunks... but please help me to do further processes, like create its thumbnail and display the video in a browser.

    Here is code to upload the video in chunks.

    Upload button click

     protected void btnUploadVideo_Click(object sender, EventArgs e)
            {
                UploadVideoFile obj = new UploadVideoFile();
                string FileName = fuUploadVideo.FileName;
                string DestPath = Server.MapPath("Videos");
                string strFinalFileName = Path.GetFileName(fuUploadVideo.FileName);
              long  FileLength = fuUploadVideo.PostedFile.ContentLength;
              long uploadchunklimit;
              int SizeLimit = (int)FileLength;
                if (FileLength <= 1024)
                {
                    uploadchunklimit = 1;
                    SizeLimit = (int)FileLength;
                }
                else if (FileLength > 10240)
                {
                    uploadchunklimit = FileLength / 10240;
                    SizeLimit = 10;
                }
                else if (FileLength <= 10240 && FileLength > 1024)
                {
                    uploadchunklimit = FileLength / 1024;
                }
                else
                {
                    uploadchunklimit = FileLength / 1024;
                }
    
                long lngSize = (long)SizeLimit;
                lngSize *= 1024 * 1024;
                string ext = Path.GetExtension(fuUploadVideo.PostedFile.FileName);
                string strDestFileName = Server.MapPath("videofile") + "\\" + Guid.NewGuid() + ext;
                string strSrcFile = Server.MapPath("videofile/" + Path.GetFileName(strDestFileName));
                string strDestFile = Server.MapPath("mergefile") + "//" + Path.GetFileName(strDestFileName);
                string strFinalDest = Server.MapPath("FinalFile") ;
                obj.Process(fuUploadVideo.PostedFile.FileName, strDestFileName, lngSize, fuUploadVideo.PostedFile);
                obj.MergerProcess(strSrcFile, strDestFile, strFinalDest);
            }
    

    UploadVideofile.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Web;
    //using ContestBLL;
    
    /// <summary>
    /// This Class contains methods for upload chunks
    /// </summary>
    public class UploadVideoFile
    {
        /// <summary>
        /// declaration of private members
        /// </summary>
        private FileStream fSIn, fSout;
    
        /// <summary>
        /// declaration of private members
        /// </summary>
        private int preDefinedCacheSize;
    
        /// <summary>
        /// Initializes a new instance of the Chunk class.
        /// </summary>
        public UploadChunk()
        {
            //// TODO: Add constructor logic here
        }
    
        /// <summary>
        ///  This method used to merge file
        /// </summary>
        /// <param name="strSrcPath">Source path of file</param>
        /// <param name="strDestPath">destination  path of file</param>
        /// <param name="strFilnalDest">Final destination path of file</param>
        public string MergerProcess(string strSrcPath, string strDestPath, string strFilnalDest)
        {
            try
            {
                string[] strFiles = Directory.GetFiles(strSrcPath, "*.part");
    
                this.fSout = new FileStream(strDestPath, FileMode.Create);
                BinaryWriter wFSOut = new BinaryWriter(this.fSout);
                long fileSizes = 0;
                fileSizes = this.GetSizes(strFiles);
                foreach (string a in strFiles)
                {
                    this.preDefinedCacheSize = this.DefineCache();
                    this.fSIn = new FileStream(strSrcPath + "\\" + this.FileName(a), FileMode.Open);
                    BinaryReader rFSIn = new BinaryReader(this.fSIn);
                    if (this.preDefinedCacheSize > this.fSIn.Length - this.fSIn.Position)
                    {
                        this.preDefinedCacheSize = (int)this.fSIn.Length - (int)this.fSIn.Position;
                    }
    
                    byte[] buffer = new byte[this.preDefinedCacheSize];
                    while (this.fSIn.Position != this.fSIn.Length)
                    {
                        rFSIn.Read(buffer, 0, this.preDefinedCacheSize);
                        wFSOut.Write(buffer);
                        Thread.Sleep(1);
                    }
    
                    rFSIn.Close();
                    this.fSIn.Close();
                }
    
                wFSOut.Close();
                this.fSout.Close();
                string strFolderToDelete = strSrcPath;
                if (Directory.Exists(strFolderToDelete))
                {
                    Directory.Delete(strFolderToDelete, true);
                }
    
                if (File.Exists(strDestPath))
                {
                    File.Copy(strDestPath, strFilnalDest + "//" + Path.GetFileName(strDestPath), false);
                    File.Delete(strDestPath);
                }
                return Path.GetFileName(strDestPath);
            }
            catch (Exception ex)
            {
                object[] customval = new object[0];
                //AppError.ErrorMsg(ex.StackTrace, "UploadChunk.cs", "MergerProcess", customval);
            }
        }
    
        /// <summary>
        /// this method is used to ...
        /// </summary>
        /// <param name="strSrcPath"> path of the source file</param>
        /// <param name="strDestPath">destination  path of file</param>
        /// <param name="lngFileSize"> Size of file to be split</param>
        /// <param name="fsi">object of HttpPostedFile class</param>
        public void Process(string strSrcPath, string strDestPath, long lngFileSize, System.Web.HttpPostedFile fsi)
        {
            string strDirectory = string.Empty, strNewFileNames = string.Empty;
            long fileSize = 0;
            int intCounter = 0;
            try
            {
                //// Code to Check whether it is logical or not to Continue...
    
                ////FSIn = new FileStream(strSrcPath, FileMode.Open);
                ////BinaryReader rFSIn = new BinaryReader(FSIn);
                BinaryReader rFSIn = new BinaryReader(fsi.InputStream);
                ////FileSize = FSIn.Length;
                fileSize = fsi.ContentLength;
    
                strDirectory = strDestPath;
    
                ////split it to parts in a folder Called "FileName"
                System.IO.Directory.CreateDirectory(strDirectory);
    
                ////begin writing
                ////while (FSIn.Position != FSIn.Length)
                while (rFSIn.BaseStream.Position != fsi.ContentLength)
                {
                    this.preDefinedCacheSize = this.DefineCache();
                    byte[] buffer = new byte[this.preDefinedCacheSize];
                    strNewFileNames = strDirectory + "\\" + intCounter.ToString() + ".part";
                    this.fSout = new FileStream(strNewFileNames, FileMode.Create);
                    BinaryWriter wFSOut = new BinaryWriter(this.fSout);
                    ////while ((FSout.Position < lngFileSize) && (FSIn.Position != FSIn.Length))
                    while ((this.fSout.Position < lngFileSize) && (rFSIn.BaseStream.Position != fsi.ContentLength))
                    {
                        ////if (((FSIn.Length - FSIn.Position) < Math.Min(PreDefinedCacheSize, (int)lngFileSize)) && (PreDefinedCacheSize > lngFileSize))
                        if (((fsi.ContentLength - rFSIn.BaseStream.Position) < Math.Min(this.preDefinedCacheSize, (int)lngFileSize)) && (this.preDefinedCacheSize > lngFileSize))
                        {
                            this.preDefinedCacheSize = (int)fsi.ContentLength - (int)rFSIn.BaseStream.Position;
                            rFSIn.Read(buffer, 0, this.preDefinedCacheSize);
                            wFSOut.Write(buffer);
                            Thread.Sleep(1);
                        }
                        else
                        {
                            if (this.preDefinedCacheSize > lngFileSize)
                            {
                                this.preDefinedCacheSize = (int)lngFileSize;
                            }
    
                            rFSIn.Read(buffer, 0, this.preDefinedCacheSize);
                            wFSOut.Write(buffer);
                            Thread.Sleep(1);
                        }
                    }
    
                    wFSOut.Close();
                    this.fSout.Close();
                    intCounter++;
                }
    
                ////finish
                rFSIn.Close();
            }
            catch (Exception ex)
            {
                object[] customval = new object[0];
                //AppError.ErrorMsg(ex.StackTrace, "UploadChunk.cs", "Process", customval);
            }
        }
    
        /// <summary>
        /// this i sused to define cache
        /// </summary>
        /// <returns>return integer value</returns>
        private int DefineCache()
        {
            return 8192 * 2;
        }
    
        /// <summary>
        /// this method  gives the Filename from the long Path
        /// </summary>
        /// <param name="strString">path of file</param>
        /// <returns>return string value</returns>
        private string FileName(string strString) 
        {
            return strString.Substring(strString.LastIndexOf("\\"));
        }
    
        /// <summary>
        /// This method is used to get size 
        /// </summary>
        /// <param name="strFileZ">array of files</param>
        /// <returns>return long type value</returns>
        private long GetSizes(string[] strFileZ)
        {
            long intSizeToReturn = 0;
            foreach (string a in strFileZ)
            {
                FileStream tmpFS = new FileStream(a, FileMode.Open);
                intSizeToReturn += tmpFS.Length;
                tmpFS.Close();
            }
    
            return intSizeToReturn;
        }
    }