Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFMPEG: embed current time in milliseconds into video

Tags:

video

ffmpeg

I would like to embed the computer's local time in milliseconds into a stream using FFMPEG.

I can embed the local time in seconds using drawtext like so:

ffmpeg -i <input> -vf "drawtext=text='%{localtime\:%T}'" -f flv <output>

Looking through the documentation for drawtext, doing some tests, and Googling around, it seems like localtime and gmtime don't provide milliseconds -- just seconds. However the pts options does have milliseconds:

ffmpeg -i <input> -vf "drawtext=text='%{pts\:hms}'" -f flv <output>

I also found out that pts supports an offset, so I was able to use something like this to display local time (kind of):

ffmpeg -i <input> -vf "drawtext=text='%{pts\:hms\:$(date +%s.%N)}'" -f flv <output>

This had two problems:

  1. It displayed something like 17499:17:29 for the time... I found a (rather complex) way to work around this
  2. It uses the server's current time when you first run the ffmpeg command as the offset -- not the server's current time when ffmpeg actually starts decoding video. I noticed ffmpeg had about a 2-second startup time, causing the clock to be off by roughly 2 seconds

Is there a way to modify my solution, or an entirely separate solution, that can embed server local time in milliseconds into the stream?

like image 855
stevendesu Avatar asked Nov 29 '17 01:11

stevendesu


1 Answers

Use

ffmpeg -i input
       -vf "settb=AVTB,
            setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)',
            drawtext=text='%{localtime}.%{eif\:1M*t-1K*trunc(t*1K)\:d}'"
       -f flv out

First, the incoming timestamps are represented as microsecond precision by forcing the timebase to the default AVTB which is 10e-6.

Second, a new PTS is set, which comprises of the original PTS reduced to milliseconds and left-shifted (decimally) three digits. To this, is added the wallclock's milliseconds component. RTCTIME is available in setpts and returns an integer with microsecond precision.

Third, the text string has three parts. The first is the localtime which is formatted as a Y-M-D-H-M-S string and returns second precision. Then a dot to demarcate the milliseconds. In the third, t returns fractional seconds. The millisecond component is extracted and printed as an integer.

like image 122
Gyan Avatar answered Oct 20 '22 15:10

Gyan