Search code examples
asp.net-mvc-5video-processingazure-blob-storage

ASP.NET MVC upload video file and convert it from HttpPostedFileBase to image files(frames)


I want to upload a video file and get the first frame(or maybe specified frame) as thumbnail in my ASP.NET MVC project.

Controller:

[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
   // How to get the video file frames(or first frame) here
   // or Microsoft Azure Blob Storage provide the service to do this?
   // (I upload file to Microsoft Azure Blob)
}

Solution

  • Per my understanding, you could use the wrapper VideoFileReader utilizing FFmpeg library to read video files. Here is the example from the official documentation:

    // create instance of video reader
    VideoFileReader reader = new VideoFileReader();
    // open video file
    reader.Open("test.avi");
    // check some of its attributes
    Console.WriteLine("width:  " + reader.Width);
    Console.WriteLine("height: " + reader.Height);
    Console.WriteLine("fps:    " + reader.FrameRate);
    Console.WriteLine("codec:  " + reader.CodecName);
    // read 100 video frames out of it
    for(int i = 0; i < 100; i++)
    {
        Bitmap videoFrame = reader.ReadVideoFrame();
        // process the frame somehow
        // ...
    
        // dispose the frame when it is no longer required
        videoFrame.Dispose();
    }
    reader.Close();
    

    Note: You may need to copy FFmpeg binaries (DLLs) into your web application. For the AForge.Video.FFMPEG package, you could follow here or this similar issue.

    Back to your scenario, you may need to temporarily store HttpPostedFileBase.InputStream into a temp file, then use this temp file to initialize the VideoFileReader instance.

    For uploading file(s) to Azure Blob storage, you could leverage UploadFromFile or UploadFromStream,etc. Detailed tutorials, you could follow here.


    UPDATE:

    I checked AForge.Video.FFMPEG and found it could not work anymore. Per my test, you could install the Accord.Video.FFMPEG package which origins from the AForge.NET Framework and is part of the Accord.NET Framework to handle video. You just need to change the referenced namespace, and here is my test code on a console application:

    using Accord.Video.FFMPEG;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleFfmpeg
    {
        class Program
        {
            static void Main(string[] args)
            {
                // create instance of video reader
                VideoFileReader reader = new VideoFileReader();
                // open video file
                reader.Open(AppDomain.CurrentDomain.BaseDirectory+ @"Videos\FlickAnimation.avi");
                // check some of its attributes
                Console.WriteLine("width:  " + reader.Width);
                Console.WriteLine("height: " + reader.Height);
                Console.WriteLine("fps:    " + reader.FrameRate);
                Console.WriteLine("codec:  " + reader.CodecName);
                //read video frames
                for (int i = 0; i < reader.FrameCount; i++)
                {
                    Bitmap videoFrame = reader.ReadVideoFrame();
                    // process the frame somehow
                    videoFrame.Save(AppDomain.CurrentDomain.BaseDirectory + $"Videos\\{i}.bmp");
                    // dispose the frame when it is no longer required
                    videoFrame.Dispose();
                }
                reader.Close();
                Console.ReadLine();
            }
        }
    }
    

    RESULT:

    enter image description here