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