Last active
March 9, 2025 08:07
-
-
Save emreberge/d844a768e735266b3efa045962405d07 to your computer and use it in GitHub Desktop.
A script that takes the center point of all the latitude, longitude and altitude points in an srt file and adds to the exif meta data of the corresponding mp4 file. Typical use case is for DJI drone movies, which creates an SRT file with meta data for the videos taken. The GPS coordinates is embedded in a format that works with Apple Photos app.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Use exiftool -"gps*" -n to check coordinates | |
set -o errexit # Abort on nonzero exit status | |
set -o nounset # Abort on unbound variable | |
set -o pipefail # Don't hide errors within pipes | |
# Global Variables | |
readonly SCRIPT_DIR="$(dirname "$0")" | |
readonly SCRIPT_NAME="$(basename "$0")" | |
main() { | |
which exiftool >/dev/null || (echo "This script requires exiftool: brew install exiftool"; exit 1) | |
is_arguments_valid "$@" || (print_usage; exit 1) | |
for file in "$@"; do | |
srt_file="${file%.*}.SRT" | |
mov_file="${file%.*}.MP4" | |
avg_lat="$(get_avarage_latitude "${srt_file}")" | |
avg_lon="$(get_avarage_longitude "${srt_file}")" | |
avg_alt="$(get_avarage_altitude "${srt_file}")" | |
echo "Setting coordinates of "${mov_file}" to ("${avg_lat}", "${avg_lon}", "${avg_alt}")" | |
exiftool -Keys:GPSCoordinates="${avg_lat}, ${avg_lon}, ${avg_alt}" -overwrite_original -P "$file" | |
done | |
} | |
is_arguments_valid() { | |
local return_code=0 | |
if [[ "$#" -eq 0 ]]; then | |
echo "Error: no files provided" >&2 | |
return_code=1 | |
fi | |
for file in "$@"; do | |
fileExtention="${file##*.}" | |
# Extract file base name | |
fileName="${file%.*}" | |
case "$fileExtention" in | |
"mp4" | "MP4") | |
# If it's an mp4, check the .srt | |
if [ ! -f "${fileName}.srt" ]; then | |
echo "Error: Missing corresponding .srt file for \"$file\"." >&2 | |
return_code=1 | |
fi | |
;; | |
"srt" | "SRT") | |
# If it's an srt, check the .mp4 | |
if [ ! -f "${fileName}.mp4" ]; then | |
echo "Error: Missing corresponding .mp4 file for \"$file\"." >&2 | |
return_code=1 | |
fi | |
;; | |
*) | |
echo "Error: File must have a .mp4 or .srt extension." >&2 | |
return_code=1 | |
;; | |
esac | |
done | |
return $return_code | |
} | |
print_usage() { | |
echo "" >&2 | |
echo "Usage: $SCRIPT_NAME file.SRT | file.MP4 ..." >&2 | |
echo "Where one or more file are either an SRT file with an MP4 equvalant, or vice versa." >&2 | |
} | |
get_avarage_latitude() { | |
local lats="$( sed -nE 's/^.*\[latitude:[[:space:]]*(-?[0-9]+\.[0-9]+)\].*$/\1/p' "${1}" | grep -v '^0\.000000$')" | |
echo "$(get_avarage_from_values "${lats}")" | |
} | |
get_avarage_longitude() { | |
local longs="$( sed -nE 's/^.*\[longitude:[[:space:]]*(-?[0-9]+\.[0-9]+)\].*$/\1/p' "${1}" | grep -v '^0\.000000$')" | |
echo "$(get_avarage_from_values "${longs}")" | |
} | |
get_avarage_altitude() { | |
local alts="$( sed -nE 's/^.*abs_alt:[[:space:]]*(-?[0-9]+\.[0-9]+).*$/\1/p' "${1}" | grep -v '^0\.000000$')" | |
echo "$(get_avarage_from_values "${alts}")" | |
} | |
get_avarage_from_values() { | |
local values="${@}" | |
max_value="$(echo "${values}" | sort -n | tail -1)" | |
min_value="$(echo "${values}" | sort -nr | tail -1)" #head could be used, but once head reads 1 line, it exits, sort then returns SIGPIPE error, as one can not write to a closed pipe | |
avarage="$(echo "scale=7; ("${max_value}" + "${min_value}")/2" | bc)" | |
echo "${avarage}" | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example usage:
gps-coordinates-from-srt-to-mp4-sh 100MEDIA/*.mp4