FFMpegCore icon indicating copy to clipboard operation
FFMpegCore copied to clipboard

4.8.0: NotifyOnProgress only reports on 100%

Open Rhywden opened this issue 2 years ago • 8 comments

The following code is working reliably with 4.7.0:

Action<double> progressHandler = new Action<double>(async p =>
            {
                evtArgs.Progress = p;
                await conversionProgressEvent.Update(evtArgs);

                logger.LogInformation($"Progress on encode: {p}");
            });

var result = await FFMpegArguments
                    .FromFileInput(input)
                    .OutputToFile(output, false, options => options
                        .WithVideoCodec(VideoCodec.LibX264)
                        .WithConstantRateFactor(23)
                        .WithAudioCodec(AudioCodec.Aac)
                        .WithFastStart())
                    .NotifyOnProgress(progressHandler, media.Duration)
                    .ProcessAsynchronously();

The logs then do indeed show a progression of percentages. After the update to 4.8.0 I basically only get the final notification of Progress on encode: 100.00 and that's it. Downgrading to 4.7.0 immediately gets it working again.

Rhywden avatar May 18 '22 15:05 Rhywden

I posted mine before I saw yours... no response in over two weeks is not encouraging. Anyway, I tried downgrading to 4.7.0 but get this error when running ffprobe:

System.MissingMethodException: Method not found: 'Int32 Instances.Instance.BlockUntilFinished()'. at FFMpegCore.FFProbe.Analyse(String filePath, Int32 outputCapacity, FFOptions ffOptions)

Then this one when I call FFMpegArguments... which options are pretty much the same as yours:

System.MissingMethodException: Method not found: 'Void Instances.Instance..ctor(System.String, System.String)'. at FFMpegCore.FFMpeg.ParsePartOfCodecs(Dictionary2 codecs, String arguments, Func2 parser) at FFMpegCore.FFMpeg.GetCodecsInternal() at FFMpegCore.FFMpegCache.get_Codecs() at FFMpegCore.FFMpeg.TryGetCodec(String name, Codec& codec) at FFMpegCore.FFMpeg.GetCodec(String name) at CADEmessaging.clsExchange.<>c.<FindSenderDatabase>b__23_1(FFMpegArgumentOptions options) in D:\Data\CADE.Net\Classes\Email\clsExchange.cs:line 599 at FFMpegCore.FFMpegArguments.ToProcessor(IOutputArgument argument, Action`1 addArguments)

So, at a loss. Neither 4.7.0 or 4.8.0 work for me.

Velocedge avatar Jun 04 '22 09:06 Velocedge

Well, downgrading only works in Windows as it turned out. As soon as I pushed the whole thing to production (which is a Linux server) I got a similar exception (for me it was FFProbe throwing because I got media information before trying to encode).

Updating FFMpeg or changing versions doesn't do much either.

Rhywden avatar Jun 04 '22 13:06 Rhywden

I'm on a Windows 2019 server but no joy there. Maybe I'll try 4.6.0 ;-)

Velocedge avatar Jun 04 '22 16:06 Velocedge

Not nearly as nice as NotifiyOnProgress is but NotifyOnError does fire the event and has enough information to do a countdown in time: "frame= 1440 fps= 16 q=-1.0 Lsize= 6938kB time=00:00:47.94 bitrate=1185.3kbits/s speed=0.517x"

private Action onError = new Action(s => { Debug.WriteLine(s); string[] ary = s.Split(' '); string[] pAry = null;

for (int i=0; i < ary.Length; i++)
{
    if (ary[i] != "")
    {
        pAry = ary[i].Split('=');
        if (pAry[0] == "time")
        {
            TimeSpan timeComplete = TimeSpan.Parse(pAry[1]);
            TimeSpan timeLeft = videoDuration - timeComplete;
            double secondsLeft = timeLeft.TotalSeconds;
            s = CADEmain.DisplayTime(secondsLeft);  // convert to display time
            signalR.SendSignalR(itm["org_int"], itm["person_int"], "message", $"{s}"); // send to user via  SignalR
        }
    }
}

});

Velocedge avatar Jun 05 '22 15:06 Velocedge

no response in over two weeks is not encouraging

@rosenbjerg is managing this repo all on their own, so I'd try to cut them some slack. With that out of the way, a diff between versions (perhaps even a few versions back) would give you an idea of what's changed (and therefore where a problem might lie).

It's also possible for it to be an upstream issue (something might have changed in ffmpeg itself) - have you verified that the issue exists regardless of the version of ffmpeg.exe that's available at runtime?

tiesont avatar Jun 07 '22 04:06 tiesont

Adding another data point. I got the same issue on 4.8.0, and downgrading to 4.7.0 fixes it. I'm running Windows 10 Pro, targeting .NET 6, and using ffprobe/ffmpeg version 4.2.

keg247 avatar Jun 13 '22 20:06 keg247

It's also possible for it to be an upstream issue (something might have changed in ffmpeg itself) - have you verified that the issue exists regardless of the version of ffmpeg.exe that's available at runtime?

Unlikely as the mentioned onError event is still outputting valid data. And I did try to change ffmpeg versions, didn't make a difference.

Rhywden avatar Jun 13 '22 20:06 Rhywden

I think this is caused by ffmpeg outputting to standard error. Looks like 4.8.0 separated the handling of standard error from standard output. According to some of the answers here and here, ffmpeg outputs to standard error to leave standard output free (and this seems to be the case for version 4.2 on Windows). So 4.8.0 is looking on standard output for the time information to calculate the progress and fire NotifyOnProgress, but it never shows up (and NotifyOnOutput never fires because there is never any standard output).

The reason that the Video_UpdatesProgress test succeeds nevertheless is because HandleCompletion sets the percentage and time progress and fires the events (this is also why NotifyOnProgress fires on 100%).

I'll submit a pull request.

keg247 avatar Jun 20 '22 04:06 keg247

Fixed in the PR by @keg247

rosenbjerg avatar Feb 04 '23 21:02 rosenbjerg