AydinAdn/MediaToolkit

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

Opened this issue · 3 comments

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:

  • I had to remote the 'ffmpeg' at the start. Fine with that.
  • The CustomCommand is not executed right away.
  • Had to call the Engine.Convert() method.
  • The Engine.Convert() method did something which took so long time I had to kill the FFMPeg process from the Task Manager.
  • The Engine.CustomCommand() and Engine.Convert() did something to my commands which caused the video to be re-encoded. I was NOT able to execute my commands as they were to avoid the fr34king re-encoding the 6GB file!
  • I was not able to batch the custom commands for "conversion".
  • I was not able to cancel currently running task.
  • The Engine.Dispose() did not end or kill the FFMpeg background task!

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

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.

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();
}

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.