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)
}
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.
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: