In the first part of this article, I went over the details of a process for renaming photos to include the geographic location in the filename. Some people asked if the same can be done for videos, and the answer is “probably.”

Earlier this year, I went on a month-long overlanding trip across the US. I mounted a bunch of GoPro cameras all over my truck and took thousands of videos. Upon returning home – exhausted and sunburned – I quickly realized that my recollection of the entire trip consisted primarily of driving, refueling, and looking for campgrounds or hotels.

I couldn’t remember which parks or even which states I visited. So when I looked at my collection of several terabytes of video recordings with informative filenames like “GH010182.MP4,” I realized that getting through this pile will take some effort.

I needed a quick way of glancing at the filename and immediately knowing when and where the video was made. GoPro encodes GPS coordinates, among other useful data, within the MP4 file, and this information can be extracted with exiftool.

However, seeing something like “38.626,-109.508” doesn’t tell me much. The latitude and longitude need to be converted to a recognizable address, requiring a geolocation service. I used Geocodio, which met my needs and budget.

The script is below, and you can also download it from my GitHub repo. You must get your own API key from Geocodio and insert it in the script. Before you run the script, you must make a backup of your videos in case the renaming process goes awry.

Simply go to the directory containing your video files and run the script. It will only process the files in the current folder without going into any subfolders. You can change this behavior by adjusting the -maxdepth argument for the find command. You may also change the filename mask to match your needs.

These were the original names of the files I used for testing this script:

GH010135.MP4  GH010162.MP4  GH010182.MP4  GH010288.MP4

And these are the new names created by the script:

20220706-1128-000-190_s_park_st_lake_city_co_81235-31s-GH010135.MP4.mp4
20220706-1318-000-497_county_rd_30_lake_city_co_81235-13s-GH010162.MP4.mp4
20220707-1321-000-1098_county_rd_33_lake_city_co_81235-120s-GH010182.MP4.mp4
20220712-1825-000-1119_state_hwy_191_moab_ut_84532-411s-GH010288.MP4.mp4
The script
#!/bin/bash
# Rename GoPro videos in the current folder to include:
# Date the video was taken
# Full address
# Duration in seconds
# Original filename
#
# Example:
# 20220706-1128-000-190_s_park_st_lake_city_co_81235-31s-GH010135.MP4.mp4

v='v1.7'
apibase="https://api.geocod.io/${v}"
api_key="Get your API key from https://www.geocod.io"

convert_function() {
  echo "Renaming "
  orig_name="$(basename "")"

  coordinates="$(exiftool -q -m -n -p '$GPSLatitude,$GPSLongitude' "")"

  location="$(curl -s0 -q -k "${apibase}/reverse?q=${coordinates}&api_key=${api_key}&limit=1" | \
    jq -r '.results[]|"\(.formatted_address)"' 2>/dev/null | \
    sed -e 's/\(.*\)/\L/' -e 's/[^A-Za-z0-9._-]/_/g' -e 's/__/_/g')"

  if [ -z "${location}" ]
  then
    lat="$(echo "${coordinates}" | awk -F, '{print $1}' | sed 's/[0-9]$//')"
    lon="$(echo "${coordinates}" | awk -F, '{print $2}' | sed 's/[0-9]$//')"
    coordinates="${lat},${lon}"
    location="$(curl -s0 -q -k "${apibase}/reverse?q=${coordinates}&api_key=${api_key}&limit=1" | \
    jq -r '.results[]|"\(.formatted_address)"' 2>/dev/null | \
    sed -e 's/\(.*\)/\L/' -e 's/[^A-Za-z0-9._-]/_/g' -e 's/__/_/g')"
  fi

  if [ -z "${location}" ]
  then
    location="mystery_town"
  fi

  dt="$(exiftool -duration "" | grep -oE "([0-9]{1,}:){1,}?([0-9]{1,}){1,}([0-9]{1,}\.[0-9]{1,})?")"
  if [ $(echo ${dt} | grep -c :) -eq 0 ]; then dt="00:00:${dt}"; fi

  duration="$(date -d "1970-01-01 ${dt}Z" +%s)s"
  if [ -z "${duration}" ]; then duration=0s; fi

  exiftool '-filename<${CreateDate}.%le' -d "%Y%m%d-%H%M%%-03.c-${location}-${duration}-${orig_name}" "" 2>/dev/null
}
export -f convert_function

find . -mindepth 1 -maxdepth 1 -type f -name "*\.MP4" | while read i; do convert_function "${i}"; done