How can I overlay the captured timestamp onto a video using ffmpeg in YYYY-MM-DD HH:MM:SS format?

4

2

I am trying to overlay a timestamp (date and time when frame captured) on video frames for a stored video file using ffmpeg.

This succeeds in displaying time in seconds since the beginning of the video:

ffmpeg -i in.webm -filter_complex "drawtext=fontfile=/usr/share/fonts/truetype/arial.ttf: text='%{pts \:flt}': x=100 : y=50 : box=1" -c:a copy out.webm

The documentation indicates that the pts can also take a gmtime argument to print out the date and time,

pts

The timestamp of the current frame. It can take up to three arguments.

The first argument is the format of the timestamp; it defaults to flt for seconds as a decimal number with microsecond accuracy; hms stands for a formatted [-]HH:MM:SS.mmm timestamp with millisecond accuracy. gmtime stands for the timestamp of the frame formatted as UTC time; localtime stands for the timestamp of the frame formatted as local time zone time.

The second argument is an offset added to the timestamp.

If the format is set to localtime or gmtime, a third argument may be supplied: a strftime() format string. By default, YYYY-MM-DD HH:MM:SS format will be used.

But when I try to use ffmpeg -i in.webm -filter_complex "drawtext=fontfile=/usr/share/fonts/truetype/arial.ttf: text='%{pts \:gmtime}': x=100 : y=50 : box=1" -c:a copy out.webm I get the error Invalid format 'gmtime'.

ffmpeg version 2.8.3 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 4.8 (SUSE Linux)
  configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include/ffmpeg --extra-cflags='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g' --optflags='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g' --disable-htmlpages --enable-pic --disable-stripping --enable-shared --disable-static --enable-runtime-cpudetect --enable-gpl --disable-openssl --enable-avresample --enable-libcdio --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libcelt --enable-libcdio --enable-libdc1394 --enable-libfreetype --enable-libgsm --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-pic --enable-pthreads --enable-vaapi --enable-vdpau --disable-decoder=dca --enable-libdcadec --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtwolame --enable-libvo-aacenc --enable-libx264 --enable-libx265 --enable-libxvid --enable-version3 --enable-x11grab
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
Input #0, matroska,webm, from 'in.webm':
  Metadata:
    encoder         : Lavf56.40.101
  Duration: 00:01:43.32, start: 0.007000, bitrate: 504 kb/s
    Stream #0:0(eng): Video: vp8, yuv420p, 480x640, SAR 1:1 DAR 3:4, 1k fps, 1k tbr, 1k tbn, 1k tbc (default)
    Metadata:
      title           : Video
    Stream #0:1: Audio: opus, 48000 Hz, stereo, fltp (default)
[libvpx-vp9 @ 0x2083580] v1.3.0
[webm @ 0x20823a0] Codec for stream 1 does not use global headers but container format requires global headers
Output #0, webm, to 'out.webm':
  Metadata:
    encoder         : Lavf56.40.101
    Stream #0:0: Video: vp9 (libvpx-vp9), yuv420p, 480x640 [SAR 1:1 DAR 3:4], q=-1--1, 200 kb/s, 1k fps, 1k tbn, 1k tbc (default)
    Metadata:
      encoder         : Lavc56.60.100 libvpx-vp9
    Stream #0:1: Audio: opus, 48000 Hz, stereo (default)
Stream mapping:
  Stream #0:0 (vp8) -> drawtext
  drawtext -> Stream #0:0 (libvpx-vp9)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[Parsed_drawtext_0 @ 0x2084ea0] Invalid format 'gmtime'
    Last message repeated 1 times
Past duration 0.999992 too large
[Parsed_drawtext_0 @ 0x2084ea0] Invalid format 'gmtime'
    Last message repeated 28 times

How do I get the overlayed text to display the UTC time in a YYYY-MM-DD HH:MM:SS format?

mattm

Posted 2015-12-15T17:31:26.773

Reputation: 315

It's used like this: text='%{gmtime}', but that will display current time formatted as UTC. I'm not sure if that's what you want or not. – llogan – 2015-12-16T20:08:28.487

@LordNeckbeard No unfortunately that is not what I am looking for, I am looking for the time the frame was captured. I have included the section of the documentation that describes what I was hoping to do. – mattm – 2015-12-16T20:24:48.307

Answers

1

You can use a start time as a Unix Epoch integer (1507046400 below) and alternatively inform the date-time format (%d-%m-%Y %T below):

text='%{pts\:gmtime\:1507046400\:%d-%m-%Y %T}'

Denio Mariz

Posted 2015-12-15T17:31:26.773

Reputation: 129

Informing a start time is useful when you are marking a video that was recorded in (or contains images from) the past. – Denio Mariz – 2017-10-04T14:47:52.297

0

'gmtime' seems to work now.

I'm using this string:

"drawtext=fontfile=FreeSerif.ttf:fontcolor=white:text='%{pts\\:gmtime}:fontsize=14'[out]"

I use it from c++ code so you may need to escape it differently.

Alternatively you could use a combination of static text for the date and 'hms' with offset parameter to rebuild the time in whatever time zone you need:

"drawtext=fontfile=FreeSerif.ttf:fontcolor=white:text='1970-01-01 %{pts\\:HMS\\:7200}:fontsize=14'[out]"

Vali

Posted 2015-12-15T17:31:26.773

Reputation: 1