T4ng10r
T4ng10r

Reputation: 819

ffmpeg and timecode from movie metadata

I want to add to movie made by digital camcorder timecode. This timecodes are visible during playback in camera, some tool to extract and visualize EXIF metadata also display them.

I made few attempts to configure ffmpeg, but only succeed in adding CURRENT PC time, not time from file.

ffmpeg -y -i S1480002.MP4 -vf "drawtext=fontfile=arial.ttf :expansion=normal: text=%{metadata\\:creation_time}: \ x=(w-tw)/2: y=h-(2*lh): [email protected]" output.mp4

I need to extract creation time from input file metadata. ffprobe display this time, but ffmpeg don't.

Upvotes: 2

Views: 7178

Answers (3)

Alexandre Schmidt
Alexandre Schmidt

Reputation: 618

First of all, make sure your file has the tags you want to use in a manner ffmpeg can understand. Like this:

ffprobe -i file.jpg -show_entries frames

This will output something like this:

.
.
.
[FRAME]
media_type=video
stream_index=0
key_frame=1
pkt_pts=0
pkt_pts_time=0.000000
pkt_dts=0
pkt_dts_time=0.000000
best_effort_timestamp=0
best_effort_timestamp_time=0.000000
pkt_duration=1
pkt_duration_time=0.040000
pkt_pos=N/A
pkt_size=40439
width=501
height=493
pix_fmt=yuvj420p
sample_aspect_ratio=1:1
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
[/FRAME]

In this specific example, there is no creation time (CreateDate) in the file, so ffmpeg won't be able to do anything for you.

But now suppose you have a file with the metadata you want. Then, the output will be, for example:

.
.
.
[FRAME]
media_type=video
stream_index=0
key_frame=1
pkt_pts=0
pkt_pts_time=0.000000
pkt_dts=0
pkt_dts_time=0.000000
best_effort_timestamp=0
best_effort_timestamp_time=0.000000
pkt_duration=1
pkt_duration_time=0.040000
pkt_pos=N/A
pkt_size=40681
width=501
height=493
pix_fmt=yuvj420p
sample_aspect_ratio=1:1
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
TAG:XResolution=     72:1      
TAG:YResolution=     72:1      
TAG:ResolutionUnit=    2
TAG:DateTime=2015:12:17 19:28:47
TAG:YCbCrPositioning=    1
TAG:ExifVersion= 48,  50,  49,  48
TAG:DateTimeDigitized=2015-01-01 00:00:00
TAG:ComponentsConfiguration=  1,   2,   3,   0
TAG:FlashpixVersion= 48,  49,  48,  48
TAG:ColorSpace=65535
TAG:PixelXDimension=      0
TAG:PixelYDimension=      0
[/FRAME]

Here you can notice the lines prefixed by TAG:. These are the lines ffmpeg will like. With those, you can use this:

ffmpeg -f image2 -pattern_type glob -framerate 20 -i "myfiles*.jpg" -filter_complex "drawtext='fontfile=/usr/share/fonts/truetype/msttcorefonts/Arial.ttf:fontsize=32:fontcolor=yellow:borderw=2:bordercolor=black:x=10:y=10:text=%{metadata\:DateTimeDigitized}'" "out.avi"

Breaking that in parts:

-f image2

Use "image2" file demuxer.

-pattern_type glob -i "myfiles*.jpg"

Get all files matching global pattern "myfiles*.jpg"

drawtext=

Enable "drawtext" filter.

fontfile=/usr/share/fonts/truetype/msttcorefonts/Arial.ttf

Font to use.

fontsize=32

Font size.

fontcolor=yellow

Font color.

borderw=2

Draw a 2px border around text.

bordercolor=black

Border will be black.

x=10

Start text 10px from left side of video.

y=10

Start text 10px from top of video.

text=%{metadata\:DateTimeDigitized}

Text to be renderized, which, in this case, will be taken from "DateTimeDigitized" metadata, contained in source file.

"out.avi"

The output file name.

Well, that's it. Hope that helps!

Upvotes: 1

Nathan Beach
Nathan Beach

Reputation: 2567

I think you must be the same person I answered on the ffmpeg-user mailing list... I finally figured out a hackish way to do this with a script, using ffprobe. I'm not really a shell programmer, so forgive me if something here is really dumb. I've just pieced it together from dozens of stackoverflow posts, and it works to overlay a formatted creation_date in the bottom right corner of the video between seconds 2 and 7.

The creation_date in my files seemed to be GMT, so I had to convert them to CDT as well... maybe this will help you. This works on Mac OSX 10.10.5, and you might have to tweak some stuff on other platforms:

#!/bin/bash

for CURRENT_FILE in *.mov; do
    CREATION_TIME=`ffprobe -v quiet "$CURRENT_FILE" -print_format compact -show_entries format_tags=creation_time`

    # in the format like: "format|tag:creation_time=2015-12-08 16:13:13"
    CDATE=${CREATION_TIME:(25)}

    SECONDS=`TZ="Europe/London" date -j -f "%Y-%m-%d %T" "$CDATE" +%s`
    MY_TIME=`TZ="America/Chicago" date -r $SECONDS +"%Y-%m-%d %I:%M %p"`

    ffmpeg -i "$CURRENT_FILE" -vf "drawtext=enable='between(t,2,7)':fontfile=/Library/Fonts/Microsoft/Arial.ttf:fontcolor=white:fontsize=64:text=\'${MY_TIME}\':x=main_w-(text_w+64):y=main_h-(text_h*2)" -acodec copy -y "../output/$CURRENT_FILE"

done

I finally got this to work, but I try to assemble the videos using concat and the audio is off and the video plays back too slowly. I've been messing with this all day, and I pretty much give up. Video processing is just too hard for my cro-magnon brain.

Upvotes: 1

Status
Status

Reputation: 940

The colon between the metadata and creation_time has to be excessively and painfully escaped for it to work properly. Try text=%{metadata\\\\\:creation_time}:

Upvotes: 1

Related Questions