AydinAdn / MediaToolkit

A .NET library to convert and process all your video & audio files.
MIT License
648 stars 199 forks source link

Engine.CustomCommand() will execute for the second time using same instance #40

Open Japollack opened 8 years ago

Japollack commented 8 years ago

Suggestion for improvement:

As an user I want to be able to formalise a full FFMpeg command and expect the method to accept everything as it is without adding any additional parameter or conversion.

2nd suggestion:

As an user I would expect the Engine.CustomCommand() to be executed right away or to be added to the task queue for later execution.

It all started when I wanted to cut and merge my video without re-encoding. I have the following commands what I know work well:

ffmpeg -ss 30 -t 60 -i D:\VideoCutting\Sample.avi -c copy -avoid_negative_ts make_zero -fflags +genpts D:\VideoCutting\Segment1.ts ffmpeg -ss 3600 -t 60 -i D:\VideoCutting\Sample.avi -c copy -avoid_negative_ts make_zero -fflags +genpts D:\VideoCutting\Segment2.ts ffmpeg -i "concat:D:\VideoCutting\Segment1.ts|D:\VideoCutting\Segment2.ts" -c copy -flags +global_header -fflags +genpts D:\VideoCutting\Merged.mp4

Converted them into two separate CustomCommand. I learned the following:

Did I misunderstood or do something wrong? I apologise if I did.

AydinAdn commented 8 years ago

Are you sure it was doing nothing after you called CustomCommand?

The issue that you encountered was because you called Engine.Convert, CustomCommand doesn't raise any progress or completion events, so please make sure that Engine.CustomCommand really is doing nothing and I can investigate further.

Japollack commented 8 years ago

You are right, my mistake. The engine.CustomCommand(firstPartCommand) produces a video file just fine. Just any following custom command is not executed:

engine.CustomCommand(firstPartCommand); // executes just fine
engine.CustomCommand(secondPartCommand); // not executed and no progress or completion event is rised!

Probably I should dispose the current Engine and use a fresh instance of the Engine. Is it indended to use it so?

However, the CustomCommand DOES rise a completion and should also rise the progress event if the job would be not that small as mines was.

The CustomCommand and Convert call the same StartFFmpegProcess method:

// public void CustomCommand(string ffmpegCommand)
this.StartFFmpegProcess(new EngineParameters()
{
      CustomArguments = ffmpegCommand
});

vs

// private void FFmpegEngine(EngineParameters engineParameters)
try
{
      this.Mutex.WaitOne();
      this.StartFFmpegProcess(engineParameters);
}
finally
{
      this.Mutex.ReleaseMutex();
}
AydinAdn commented 8 years ago

There's definitely a bug there, not being able to use the same instance of Engine after the first conversion...

I'm refactoring a lot of the things in there at the moment and unit testing it all as I go along. Instead of attempting to serialize the raw data that is put out byFFmpeg, I'll be raising new events to push that data out to the client. I think that's the most sensible solution as we'll never be able to cover every use case.