most of program1 is done, shape of program2, actual app to be started

This commit is contained in:
Gabriel Radureau
2025-10-12 00:19:52 +02:00
parent 4f80b8b70d
commit 14a3392d41
8 changed files with 270 additions and 3 deletions

98
program1/metadata.sh Normal file
View File

@@ -0,0 +1,98 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# === CONFIGURATION ===
# === Utilitaires ===
esc() { printf '%s' "$1" | sed 's/"/""/g'; }
export -f esc
safe_weekday() {
local iso="$1"
python3 - <<PY
import sys
from datetime import datetime
s = "$iso"
try:
dt = datetime.fromisoformat(s)
print(dt.strftime('%A'))
except Exception:
print("Unknown")
PY
}
export -f safe_weekday
get_creation_time() {
local f="$1"
local ct=""
for tag in CreateDate MediaCreateDate TrackCreateDate; do
ct=$(exiftool -"$tag" -d "%Y-%m-%dT%H:%M:%S" -s3 "$f" 2>/dev/null || true)
[ -n "$ct" ] && break
done
if [ -z "$ct" ]; then
ct="$(date -r "$f" +"%Y-%m-%dT%H:%M:%S")"
fi
echo "$ct"
}
export -f get_creation_time
get_duration() {
local f="$1"
ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 "$f" 2>/dev/null || echo ""
}
export -f get_duration
get_gps() {
local f="$1"
local lat lon
lat="$(exiftool -GPSLatitude -n -s3 "$f" 2>/dev/null || true)"
lon="$(exiftool -GPSLongitude -n -s3 "$f" 2>/dev/null || true)"
echo "$lat|$lon"
}
export -f get_gps
reverse_geocode() {
local lat="$1" lon="$2"
local json="" postal city district
if [ -n "$lat" ] && [ -n "$lon" ]; then
json="$(curl -s "https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&zoom=16&addressdetails=1")"
# Extraction sécurisée avec jq
postal=$(echo "$json" | jq -r '.address.postcode // ""')
city=$(echo "$json" | jq -r '.address.city // .address.town // .address.village // ""')
district=$(echo "$json" | jq -r '.address.neighbourhood // .address.suburb // .address.residential // .address.village // .address.municipality // ""')
# Concaténation formatée, ignorer champs vides
formatted=""
[ -n "$postal" ] && formatted="$formatted$postal"
[ -n "$city" ] && formatted="${formatted:+$formatted, }
$city"
[ -n "$district" ] && formatted="${formatted:+$formatted, }
$district"
echo "$formatted" | tr '\n' ' ' | tr -s ' ' ' ' | sed 's/ *$//'
else
echo ""
fi
}
export -f reverse_geocode
process_video() {
local f="$1"
local ct weekday duration lat lon address
ct="$(get_creation_time "$f")"
weekday="$(safe_weekday "$ct")"
duration="$(get_duration "$f")"
IFS="|" read -r lat lon <<<"$(get_gps "$f")"
address="$(reverse_geocode "$lat" "$lon")"
echo "$ct|$weekday|$duration|$lat|$lon|$address"
# --- CSV row ---
# echo "\"$(basename "$f")\",\"$(esc "$f")\",\"$(esc "$ct")\",\"$(esc "$weekday")\",\"$(esc "$duration")\",\"$(esc "$lat")\",\"$(esc "$lon")\",\"$(esc "$formatted")\""
}
export -f process_video

View File

@@ -2,6 +2,8 @@
set -euo pipefail
IFS=$'\n\t'
SCRIPTS_DIR=$(dirname `realpath ${BASH_SOURCE[0]}`)
# === CONFIGURATION ===
export DOSSIER_SOURCE="${HOME}/Downloads"
export DOSSIER_DESTINATION_RAW="${HOME}/Documents/.DanceVideos/raw"
@@ -42,19 +44,84 @@ import_downloaded_file
export DOSSIER_DESTINATION_MP4="$(dirname $DOSSIER_DESTINATION_RAW)/videos"
## DB utilities
export DANCE_VIDEOS_DB="$(dirname $DOSSIER_DESTINATION_RAW)/db.sqlite"
export MODEL_DIR=$(realpath $SCRIPTS_DIR/../model)
cat $MODEL_DIR/videos.sql | sqlite3 $DANCE_VIDEOS_DB
source $MODEL_DIR/register_video.sh
# register_video \
# file_name raw_file duration mp4_file \
# rotated_file thumbnail_file record_datetime day_of_week \
# lat long address
source $SCRIPTS_DIR/metadata.sh
source $SCRIPTS_DIR/rotation.sh
mp4_dir() {
local raw="$1" weekday="$2" address="${3:-wherever}"
address=$(sed 's/[^a-zA-Z0-9]/_/g' <<< $(sanitize_name "$address") | tr -s '_' '_')
local dir=$DOSSIER_DESTINATION_MP4
dir=$dir/$(date -jf "%Y-%m-%dT%H:%M:%S" "$(get_creation_time $raw)" +%Y%m%d_%H%M%S)
dir=${dir}_${weekday}_${address}
mkdir -p $dir
echo $dir
}
export -f mp4_dir
write_thumbnail() {
set -x
local raw="$1"
local thumbnail="$2"
ffmpeg -ss 00:00:03 -i $raw -vframes 1 $thumbnail 2>/dev/null
set +x
}
export -f write_thumbnail
write_mp4() {
local src="$1"
local dst="$2"
[ -e "$dst" ] || reencode_with_rotation $src $dst
}
export -f write_mp4
process_raw_file() {
local raw="$1"
local ct weekday duration lat lon address
IFS="|" read -r ct weekday duration lat lon address <<<"$(process_video "$raw")"
local dir=$(mp4_dir $raw $weekday "$address")
local thumbnail=${dir}/thumbnail.jpg
$(write_thumbnail $raw $thumbnail)
local mp4=${dir}/video.mp4
$(write_mp4 $raw $mp4)
register_video $(basename $raw) "$raw" "$duration" "$mp4" \
"$mp4" "$thumbnail" "'$ct'" "$weekday" \
"$lat" "$lon" "$address"
}
export -f process_raw_file
iphone_video() {
local raw="$1"
echo iphone $raw
process_raw_file $raw
}
export -f iphone_video
screen_video() {
local raw="$1"
echo screen $raw
process_raw_file $raw
}
export -f screen_video
whatsapp_video() {
local raw="$1"
echo whatsapp $raw
process_raw_file $raw
}
export -f whatsapp_video

46
program1/rotation.sh Normal file
View File

@@ -0,0 +1,46 @@
get_rotation_filter() {
local f="$1"
local rotation
rotation=$(exiftool -Rotation -n "$f" | awk '{print $3}')
# echo $rotation $f >> "rotations.txt"
case "$rotation" in
# 90) echo "transpose=1" ;;
# 270) echo "transpose=2" ;;
# 180) echo "hflip,vflip" ;;
# *) echo "" ;;
*) echo "transpose=1" ;;
esac
}
export -f get_rotation_filter
reencode_with_rotation() {
local src="$1"
local dst="$2"
local filter
filter="$(get_rotation_filter "$src")"
if [ -n "$filter" ]; then
echo " Correction dorientation (rotation=${filter})"
if ffmpeg -encoders 2>/dev/null | grep -q 'h264_videotoolbox'; then
ffmpeg -nostdin -i "$src" -vf "$filter" \
-c:v h264_videotoolbox -b:v 5M -c:a aac -map_metadata -1 -y "$dst"
else
ffmpeg -nostdin -i "$src" -vf "$filter" \
-c:v libx264 -preset fast -crf 18 -c:a aac -map_metadata -1 -y "$dst"
fi
else
# Pas de rotation → simple copie (ou réencodage minimal)
if ffmpeg -y -i "$src" -c copy -map 0 -movflags +faststart "$dst" < /dev/null 2>/dev/null; then
:
else
if ffmpeg -encoders 2>/dev/null | grep -q 'h264_videotoolbox'; then
ffmpeg -nostdin -i "$src" \
-c:v h264_videotoolbox -b:v 5M -c:a aac -map_metadata -1 -y "$dst"
else
ffmpeg -nostdin -i "$src" \
-c:v libx264 -preset fast -crf 18 -c:a aac -map_metadata -1 -y "$dst"
fi
fi
fi
}
export -f reencode_with_rotation