- Date
Bulk editing media metadata using ffmpeg
I had an issue where I had factory reset my GoPro and forgot to change the datetime before using the camera. The result is that I was left with a bunch of videos that were timestamped as being from 2015. In order to fix this, I first tried ffmpeg, but found that it was not getting me the metadata I wanted. Next I tried exiftool and got some success.
This script takes an input file and shifts the time by a given amount of seconds.
time_changer.sh
#!/bin/bash
#INPUT_FILE=TEST.JPG
#DIFF_SEC=295483639
INPUT_FILE=$1
DIFF_SEC=$2
current_date=$(exiftool -CreateDate -d "%Y-%m-%d %H:%M:%S" -s3 "$INPUT_FILE")
new_date=$(date -d "$current_date GMT + $DIFF_SEC seconds" +"%Y:%m:%d %H:%M:%S%z")
# exiftool -ExtractEmbedded -DateTimeOriginal="$new_date" -CreateDate="$new_date" -ModifyDate="$new_date" "-Track*Date=$new_date" "-Media*Date=$new_date" "$INPUT_FILE"
exiftool -ExtractEmbedded -DateTimeOriginal="$new_date" -CreateDate="$new_date" -ModifyDate="$new_date" "$INPUT_FILE"
#echo $new_date
exiftool is used both to get the original date and to set the modified date. To get the current date, I used the CreateDate field. I had originally tried the DateTimeOriginal field, but found that GoPro videos did not set DateTimeOriginal correctly, but did set CreateDate correctly. Regardless, in the last step I set several fields as the new modified date.
I used the date
command to shift the wrong date by the correct amount of time. I had to make sure that the $current_date
variable was in the form YY-MM-DD HH:MM:SS TTT with TTT being the time zone code, otherwise the date
command would get mad at me. That is
why I added GMT
in the command. For the output format string, I added %z
at the end to make sure exiftool writes the correct time zone as
well when modifying the files.
When running this script, the original file will be renamed with an _original
suffix, so there is no worry of permanently messing up your originals
unless you specifically use that parameter.
To run this over multiple files, I used a helper script that just loops over every file in a specified directory with a hardcoded number of seconds to shift by.
run_time_changer.sh
#!/bin/bash
workdir=$1
for ASSET in $(ls $workdir); do
echo $ASSET
bash time_changer.sh "$workdir/$ASSET" 295483639
done