cmxl / FFmpeg.NET

.NET wrapper for common ffmpeg tasks
MIT License
611 stars 99 forks source link

Get Unable to cast object of type 'FFmpeg.NET.MediaFile' to type 'FFmpeg.NET.InputFile' error when trying to cut video file. #55

Closed zydjohnHotmail closed 2 years ago

zydjohnHotmail commented 3 years ago

Hello: I want to see if I can use this repo to cut one video (mp4 format). I created one C# WinForms project (target .NET 5.0), add nuget package: Install-Package xFFmpeg.NET -Version 6.0.0 The following is my C# code: using FFmpeg.NET; using System.IO;

public static async Task FFMPEG_Cut_Video1(string input_file1, string output_file1) { try { if (!File.Exists(input_file1)) { Debug.Print("Input video not found, quit!"); return "FileNOTFound"; } MediaFile video_in = new(input_file1); MediaFile video_out = new(output_file1); Engine ffmpeg = new(FFMPEG_Engine); ConversionOptions options = new(); options.CutMedia(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(25)); await ffmpeg.ConvertAsync((InputFile)video_in, (OutputFile)video_out, options); } catch (InvalidCastException ex) { Debug.Print(ex.Message); } return "Cut_OK"; }

private async void Form1_Load(object sender, EventArgs e) { await FFMPEG_Cut_Video1("C:\Videos\1.mp4", "C:\Videos\cut1.mp4"); }

However, when I run my code, I got the following error: System.InvalidCastException HResult=0x80004002 Message=Unable to cast object of type 'FFmpeg.NET.MediaFile' to type 'FFmpeg.NET.InputFile'. Source=System.Private.CoreLib StackTrace: at System.Runtime.CompilerServices.CastHelpers.ChkCast_Helper(Void toTypeHnd, Object obj) at System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void toTypeHnd, Object obj) at B20VideoSeekerSportRadarForm.Form1.d__7.MoveNext() in C:\Videos\VideoCut\Form1.cs:line 89 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at B20VideoSeekerSportRadarForm.Form1.d__8.MoveNext() in C:\Videos\VideoCut\Form1.cs:line 97

This exception was originally thrown at this call stack: B20VideoSeekerSportRadarForm.Form1.FFMPEG_Cut_Video1(string, string) in Form1.cs [External Code] B20VideoSeekerSportRadarForm.Form1.Form1_Load(object, System.EventArgs) in Form1.cs Please advise how I can fix this? Using ffmpeg command, I can cut the video file, but I would like to use API in my C# program. PS: I am using Windows 10 (Version 21H1), and Visual Studio 2019 (Version 16.10.4) Thanks,

DaveCS1 commented 3 years ago

Your code MediaFile video_in = new(input_file1); MediaFile video_out = new(output_file1); needs to look as such MediaFile video_in = new MediaFile(input_file1); MediaFile video_out = new MediaFile(output_file1);

That's why you received the type mismatch error.

//ffmpegPath is your path to ffmpeg.exe. eg "c:\ffmpeg\ffmpeg.exe" public async Task MakeVideoSegment(string input, string output, string ffmpegPath, int TrimStart, int TrimEnd) { var inputFile = new MediaFile(input); var outputFile = new MediaFile(output); var ffmpeg = new FFmpeg.NET.Engine(ffmpegPath); var options = new ConversionOptions(); int SecondsToTrim = TrimEnd - TrimStart; options.CutMedia(TimeSpan.FromSeconds(TrimStart), TimeSpan.FromSeconds(SecondsToTrim)); await ffmpeg.ConvertAsync(inputFile, outputFile, options); TrimmedFileNameFullPath = outputFile.FileInfo.FullName.ToString(); return TrimmedFileNameFullPath;

    }
cmxl commented 2 years ago

Use InputFile and OutputFile instead of MediaFile. MediaFile will now actually become an abstract class and does not implement IInputArguments which is used by ConvertAsync.

var inputFile = new InputFile(@"C:\Path\To_Video.flv");
var outputFile = new OutputFile(@"C:\Path\To_Save_ExtractedVideo.flv");
var ffmpeg = new Engine("C:\ffmpeg\ffmpeg.exe");
var options = new ConversionOptions();
options.CutMedia(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(25));
await ffmpeg.ConvertAsync(inputFile, outputFile, options, default);