0

I've been able to get most of the manipulations I want on various PTS/timestamp things.. except this one. I have a case where we have a running PTS that gets stamped via drawtext. I currently use the %{pts:flt} which outputs millisecond accurate seconds. This is great, but I ultimately need to format this in the format SS.ff, by which I mean we always keep only the last two digits of the seconds, and we ONLY print two significant digits of the fractional (micro/milli) second portion.

I've been through a truckload of various gmtime/strftime() attempts, and I'm stymied in part because it appears that only flt provides the fractional seconds part that I want, and it doesn't look like strftime() has support for width/padding/truncating?

2 Answers 2

2

The FFMPEG does not support strtime %f option; therefore, the fractional second works with AVTB only. The parameter is

-filter_complex "drawtext=fontsize=90:x=20:y=20:text='pts=%{pts\:gmtime\:0\:%S %f} AVTB=%{eif\:trunc(t)\:d\:2}.%{eif\:(1M*t-1M*trunc(t))/10000\:d\:2}':box=1"

and the result is

enter image description here

0

Since a lot of this was unfamiliar to me, I went ahead and wrote up how I worked through it in the hope that it would be useful to someone else down the road...

Here's our starting expression, let's break this down and go through it:

%{eif:trunc(t):d:2}.%{eif:(1M*t-1M*trunc(t))/10000:d:2}

eif is 'evaluate_int_format', it evaluates the expression’s value and outputs as formatted integer. From the docs:

The first argument is the expression to be evaluated, just as for the expr function. The second argument specifies the output format. Allowed values are x, X, d and u. They are treated exactly as in the printf function. The third parameter is optional and sets the number of positions taken by the output. It can be used to add padding with zeros from the left.... so :d:2 means a decimal integer padded to two digits.

t is the timestamp in seconds. ffmpeg appears to keep this down to millisecond accuracy, so by manipulating this we can get the output we want.

So:

%{eif:trunc(t):d:2} trunc(t) is just the integer part of the timestamp. the eif call here just formats that to two zero-padded digits.

(1M*t-1M*trunc(t))/10000 this is slick: 1M*t basically shifts the whole timestamp by 10e6, which gives us the total number of microseconds as an integer - or said another way we just cast the timestamp to an integer... similarly: 1M*trunc(t) rounds down that value to the nearest second.

1.746826 seconds becomes 1,746,826 microseconds which then trunc's down to 1,000,000 microseconds.

subtracting them leaves us with just the remainder (in microseconds).

Since we want the output in hundredths of seconds, we divide by 10000 (really another shift) and this gives us the fractional leftovers, as another integer, which we then format to two digits with zero padding.

ffmpeg-utils docs

ffmpeg text expansion docs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.