Reputation: 819
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
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
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
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