Drawtext - complex expression to show feet+frames

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Drawtext - complex expression to show feet+frames

Mark Burton
New here, hope this is an appropriate question layout...

I’ve been trying to learn more about expression evaluation and some of the more complex aspects of controlling drawing text. I’m trying to achieve something which is a bit far fetched, but I’d love to get any help I can and this would be a huge feature for me if we can get it working. I’ve not come across this anywhere in my numerous searches, but perhaps someone has an existing solution to this?

The idea is to write a drawtext expression which can draw a film footage counter onto my video. The 35mm 4perf counter I want to use counts 16 frames per foot, like so:

0+00
0+01
0+02
0+03
0+04
0+05
0+06
0+07
0+08
0+09
0+10
0+11
0+12
0+13
0+14
0+15
1+00
1+01
… and so on.

Although a single filter expression would be much more useful in the long run, I figured it may be easier to break the display into 3 drawtext filters to get started. One for the feet counter, one for the ‘+’ character and one for the frames counter. So far I have the feet working almost right, but I’m not getting anywhere with the third.

My source material is always going to be 24fps Avid DNx115.

Here is the basic command:

inputFile="in.mov"
outputFile="out.mov"
fontFile="/System/Library/Fonts/Helvetica.dfont"
ffmpeg \
-i $inputFile \
-y \
-c:v mjpeg -qscale:v 4 -pix_fmt yuvj422p \
-vf "
drawtext=fontsize=80:fontcolor=white:fontfile=$fontFile:text='%{eif\:0+(t/((1/24)*16))\:d}':x=(w/2)-text_w:y=(h-text_h)/2,
drawtext=fontsize=55:fontcolor=white:fontfile=$fontFile:text='+':x=(w/2)+5:y=(h-text_h)/2" \
-an \
$outputFile

The first drawtext for the feet value is 99% accurate, but sometimes it does not change to the next number of the exact frame it should. Is there a way to use a per frame value instead of ’t’? I’m guessing its this calculation is not producing an accurate enough result to calculate the exact frame each time? It needs to iterate to the next number every 16 frames exactly.

Any advice on where to begin with the frames counter. It needs to start at 0, count on every frame to 15 and then restart at 0 on the next frame.

Lastly (perhaps I’m dreaming here!) could this theoretically all be combined into a single expression with ability to set the starting counter to 12+06 for example and have it count accurately from there? Had to ask!

Thanks for your help,
Regards
Mark



_______________________________________________
ffmpeg-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Drawtext - complex expression to show feet+frames

Moritz Barsnick
On Tue, Apr 11, 2017 at 19:36:36 +0100, Mark Burton wrote:
> New here, hope this is an appropriate question layout...

To start things off, we always prefer to see the (or an example of an)
actual ffmpeg command line and its complete, uncut console output. I'll
show you why below.

> I’ve been trying to learn more about expression evaluation and some
> of the more complex aspects of controlling drawing text.

Good job so far!

> 0+00
> 0+01
> 0+02
> 0+03
> 0+04
> 0+05
> 0+06
> 0+07
> 0+08
> 0+09
> 0+10
> 0+11
> 0+12
> 0+13
> 0+14
> 0+15
> 1+00
> 1+01
> … and so on.

Mathematically, the first part is the frame number divided by 16
(rounded down to integer), the second part the frame number modulo 16 -
is that right?

> Although a single filter expression would be much more useful in the
> long run, I figured it may be easier to break the display into 3
> drawtext filters to get started. One for the feet counter, one for
> the ‘+’ character and one for the frames counter. So far I have the
> feet working almost right, but I’m not getting anywhere with the
> third.

Actually, you can use several expressions in the "text" parameter:
   ...:text=%{eif\:.....\:d}+%{eif\:.....)\:d}

> drawtext=fontsize=80:fontcolor=white:fontfile=$fontFile:text='%{eif\:0+(t/((1/24)*16))\:d}':x=(w/2)-text_w:y=(h-text_h)/2,
> drawtext=fontsize=55:fontcolor=white:fontfile=$fontFile:text='+':x=(w/2)+5:y=(h-text_h)/2" \
[...]
> The first drawtext for the feet value is 99% accurate, but sometimes
> it does not change to the next number of the exact frame it should.

This is where the output from your ffmpeg command comes in handy. It
would/might tell us the actual framerate. My guess is it's 23.976, or
more precisely 24000/1001, and not 24. That would explain the slight
offset.

> Is there a way to use a per frame value instead of ’t’?

You did obviously read the documentation. :-) You seem to have missed
the expression variable "n, frame_num" though.

> Any advice on where to begin with the frames counter. It needs to
> start at 0, count on every frame to 15 and then restart at 0 on the
> next frame.

The frame counter is 'n', it starts at zero, as documented. The rest is
just math, as explained above. This is called a "modulo operation". The
expression evaluation for "text" also supports the modulo operation:
mod(n,16).

To achieve what you desire, I used:
$ ffmpeg .... -vf "drawtext=fontsize=80:fontcolor=white:text='%{eif\:n/16\:d}+%{eif\:mod(n,16)\:d}'" [...]

> Lastly (perhaps I’m dreaming here!) could this theoretically all be
> combined into a single expression with ability to set the starting
> counter to 12+06 for example and have it count accurately from there?
> Had to ask!

Stop dreaming:
"12+6" is 198 (12*16+6) higher, just add that to 'n':
$ ffmpeg .... -vf "drawtext=fontsize=80:fontcolor=white:text='%{eif\:(n+198)/16\:d}+%{eif\:mod((n+198),16)\:d}" [...]

I haven't figured out how to format "12+6" as "12+06" though. Good luck
trying! :) (I know how to fake it, but there may be a proper way with
formatting expressions.)

Cheers,
Moritz
_______________________________________________
ffmpeg-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Drawtext - complex expression to show feet+frames

Mark Burton

> On 11 Apr 2017, at 21:13, Moritz Barsnick <[hidden email]> wrote:
>
> On Tue, Apr 11, 2017 at 19:36:36 +0100, Mark Burton wrote:
>> New here, hope this is an appropriate question layout...
>
> To start things off, we always prefer to see the (or an example of an)
> actual ffmpeg command line and its complete, uncut console output. I'll
> show you why below.

Sorry about that, looking around the list I didn’t see many doing that so I left it out, but absolutely will do in future. Here is the full output of the original command (which used ’t’).

ffmpeg version N-85343-gd0a3143-tessus Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 8.0.0 (clang-800.0.42.1)
  configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzmq --enable-libzvbi --enable-version3 --disable-ffplay --disable-indev=qtkit
  libavutil      55. 60.100 / 55. 60.100
  libavcodec     57. 92.100 / 57. 92.100
  libavformat    57. 72.100 / 57. 72.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 84.100 /  6. 84.100
  libswscale      4.  7.100 /  4.  7.100
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'in.mov':
  Metadata:
    major_brand     : qt  
    minor_version   : 537199360
    compatible_brands: qt  
    creation_time   : 2017-04-11T17:11:18.000000Z
    timecode        : 01:00:00:00
  Duration: 00:01:00.00, start: 0.000000, bitrate: 118696 kb/s
    Stream #0:0(eng): Video: dnxhd (DNXHD) (AVdn / 0x6E645641), yuv422p(tv, bt709/unknown/unknown), 1920x1080, 116391 kb/s, SAR 1:1 DAR 16:9, 24 fps, 24 tbr, 24k tbn, 24k tbc (default)
    Metadata:
      creation_time   : 2017-04-11T17:11:18.000000Z
      handler_name    : Apple Alias Data Handler
      encoder         : Avid DNxHD Codec
    Stream #0:1(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, stereo, s32 (24 bit), 2304 kb/s (default)
    Metadata:
      creation_time   : 2017-04-11T17:11:18.000000Z
      handler_name    : Apple Alias Data Handler
    Stream #0:2(eng): Data: none (tmcd / 0x64636D74) (default)
    Metadata:
      creation_time   : 2017-04-11T17:11:32.000000Z
      handler_name    : Apple Alias Data Handler
      timecode        : 01:00:00:00
Stream mapping:
  Stream #0:0 -> #0:0 (dnxhd (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x7fe116012800] deprecated pixel format used, make sure you did set range correctly
Output #0, mov, to 'out.mov':
  Metadata:
    major_brand     : qt  
    minor_version   : 537199360
    compatible_brands: qt  
    timecode        : 01:00:00:00
    encoder         : Lavf57.72.100
    Stream #0:0(eng): Video: mjpeg (jpeg / 0x6765706A), yuvj422p(pc), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 24 fps, 12288 tbn, 24 tbc (default)
    Metadata:
      creation_time   : 2017-04-11T17:11:18.000000Z
      handler_name    : Apple Alias Data Handler
      encoder         : Lavc57.92.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
frame= 1440 fps=148 q=4.0 Lsize=  210807kB time=00:00:59.95 bitrate=28802.1kbits/s speed=6.18x    
video:210798kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.004177%

>> I’ve been trying to learn more about expression evaluation and some
>> of the more complex aspects of controlling drawing text.
>
> Good job so far!

It really is amazing how powerful this part of ffmpeg is, what you have given me below is quite astounding!

> 0+00
>> 0+01
>> 0+02
>> 0+03
>> 0+04
>> 0+05
>> 0+06
>> 0+07
>> 0+08
>> 0+09
>> 0+10
>> 0+11
>> 0+12
>> 0+13
>> 0+14
>> 0+15
>> 1+00
>> 1+01
>> … and so on.
>
> Mathematically, the first part is the frame number divided by 16
> (rounded down to integer), the second part the frame number modulo 16 -
> is that right?

Yes, thats correct.

>> drawtext=fontsize=80:fontcolor=white:fontfile=$fontFile:text='%{eif\:0+(t/((1/24)*16))\:d}':x=(w/2)-text_w:y=(h-text_h)/2,
>> drawtext=fontsize=55:fontcolor=white:fontfile=$fontFile:text='+':x=(w/2)+5:y=(h-text_h)/2" \
> [...]
>> The first drawtext for the feet value is 99% accurate, but sometimes
>> it does not change to the next number of the exact frame it should.
>
> This is where the output from your ffmpeg command comes in handy. It
> would/might tell us the actual framerate. My guess is it's 23.976, or
> more precisely 24000/1001, and not 24. That would explain the slight
> offset.

I am true 24fps, not 23.976. Now that your expression uses frame_num though, I don’t think this will be an issue will it.

>> Is there a way to use a per frame value instead of ’t’?
> You did obviously read the documentation. :-) You seem to have missed
> the expression variable "n, frame_num" though.

You sort of got me! I’ve been using ’n’ for straight forward frame count burnins in my other setups, but I couldn't see a way to use this for the feet and frame counter.

>> Any advice on where to begin with the frames counter. It needs to
>> start at 0, count on every frame to 15 and then restart at 0 on the
>> next frame.
>
> The frame counter is 'n', it starts at zero, as documented. The rest is
> just math, as explained above. This is called a "modulo operation". The
> expression evaluation for "text" also supports the modulo operation:
> mod(n,16).
>
> To achieve what you desire, I used:
> $ ffmpeg .... -vf "drawtext=fontsize=80:fontcolor=white:text='%{eif\:n/16\:d}+%{eif\:mod(n,16)\:d}'" [...]
>
>> Lastly (perhaps I’m dreaming here!) could this theoretically all be
>> combined into a single expression with ability to set the starting
>> counter to 12+06 for example and have it count accurately from there?
>> Had to ask!
>
> Stop dreaming:
> "12+6" is 198 (12*16+6) higher, just add that to 'n':
> $ ffmpeg .... -vf "drawtext=fontsize=80:fontcolor=white:text='%{eif\:(n+198)/16\:d}+%{eif\:mod((n+198),16)\:d}" […]

This is amazing, I’m blown away by how you have solved everything in one very neat line. I can’t thank you enough for taking the time to respond in such good detail and providing a solution beyond what I expected was possible.

> I haven't figured out how to format "12+6" as "12+06" though. Good luck
> trying! :) (I know how to fake it, but there may be a proper way with
> formatting expressions.)

Yes, thats really the only thing left to do here - I was looking at how this could work and did wonder if the same principles that apply to printf could be applied, but having tried a few variations of ‘d', it seems not. Hmm.

Thank again Moritz, this is huge for me!

Kind regards
Mark

_______________________________________________
ffmpeg-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Drawtext - complex expression to show feet+frames

Mark Burton
> On 11 Apr 2017, at 21:51, Mark Burton <[hidden email]> wrote:
>> On 11 Apr 2017, at 21:13, Moritz Barsnick <[hidden email] <mailto:[hidden email]>> wrote:

>> I haven't figured out how to format "12+6" as "12+06" though. Good luck
>> trying! :) (I know how to fake it, but there may be a proper way with
>> formatting expressions.)
>
> Yes, thats really the only thing left to do here - I was looking at how this could work and did wonder if the same principles that apply to printf could be applied, but having tried a few variations of ‘d', it seems not. Hmm.

Adding 02d as the third parameter seems to work for padding the frame number:
text='%{eif\:(n+0)/16\:d}+%{eif\:mod((n+0),16)\:d\:02d}’

One issue I am having is that as the numbers count the vertical position of the text changes ever so slightly, looks like a judder. I’m guessing this is due to the character size variations so the position of the text is recalculated by tiny fractions. Is there a way to allow for this in the x and y position? I’ve tried with max_glyph_h, but I think it would need to know the height of all characters to come as it doesn’t make any difference.

Thanks
Mark



_______________________________________________
ffmpeg-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Drawtext - complex expression to show feet+frames

Mark Burton
> On 11 Apr 2017, at 22:39, Mark Burton <[hidden email]> wrote:
>
> One issue I am having is that as the numbers count the vertical position of the text changes ever so slightly, looks like a judder. I’m guessing this is due to the character size variations so the position of the text is recalculated by tiny fractions. Is there a way to allow for this in the x and y position? I’ve tried with max_glyph_h, but I think it would need to know the height of all characters to come as it doesn’t make any difference.

OK, I added "-ascent” to the y coordinate and that fixed the text juddering. Here is the final filter:
drawtext=fontsize=60:fontcolor=white:text='%{eif\:(n+0)/16\:d}+%{eif\:mod((n+0),16)\:d\:02d}':x=200:y=75-ascent

_______________________________________________
ffmpeg-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Drawtext - complex expression to show feet+frames

Moritz Barsnick
On Tue, Apr 11, 2017 at 22:52:05 +0100, Mark Burton wrote:
> OK, I added "-ascent” to the y coordinate and that fixed the text juddering. Here is the final filter:
> drawtext=fontsize=60:fontcolor=white:text='%{eif\:(n+0)/16\:d}+%{eif\:mod((n+0),16)\:d\:02d}':x=200:y=75-ascent

Thanks for pointing out the formatting and the ascent, I didn't know
(was too lazy to work my way through the docs) and it's most certainly
valuable for other users!

Moritz
_______________________________________________
ffmpeg-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Loading...