#!/usr/bin/env bash set -euo pipefail IFS=$'\n\t' # === Gestion des arguments === PROCESS_ALL=false PRINT_ERR=false # Fonction pour afficher l'aide usage() { echo "Usage: $0 [--all|-a]" echo "Options:" echo " --all, -a Traiter tous les fichiers (ignore la liste de fichiers)" echo " --help, -h Afficher cette aide" exit 1 } # Traitement des arguments while [[ $# -gt 0 ]]; do case "$1" in --all|-a) PROCESS_ALL=true shift ;; --help|-h) usage ;; --print-err) PRINT_ERR=true shift ;; *) echo "Option inconnue : $1" >&2 usage ;; esac done SCRIPTS_DIR=$(dirname `realpath ${BASH_SOURCE[0]}`) # === CONFIGURATION === export DOSSIER_SOURCE="${HOME}/Downloads" export DOSSIER_DESTINATION_RAW="${HOME}/Documents/.DanceVideos/raw" export TEMP_FILE="/tmp/dancevideos_moved_files.txt" # Initialiser le fichier temporaire > "$TEMP_FILE" sanitize_name() { local name="$1" basename "$name" \ | tr '[:upper:]' '[:lower:]' \ | tr ' ' '_' \ | tr -cd '[:alnum:]._-\n' } export -f sanitize_name source $SCRIPTS_DIR/append_with_lock.sh # Fonction pour vérifier et déplacer un fichier check_and_move() { local fichier="$1" local taille1 taille2 taille1=$(stat -f "%z" "$fichier") sleep 5 taille2=$(stat -f "%z" "$fichier") if [ "$taille1" -eq "$taille2" ] && [ "$taille2" -gt 0 ]; then echo "Déplacement de $(basename "$fichier")" rsync -av --remove-source-files "$fichier" "$DOSSIER_DESTINATION_RAW/$(sanitize_name "$(basename "$fichier")")" if ! append_with_lock "$DOSSIER_DESTINATION_RAW/$(sanitize_name "$(basename "$fichier")")" "$TEMP_FILE"; then echo "Échec de l'écriture dans $TEMP_FILE (timeout)" >&2 fi else echo "Fichier $(basename "$fichier") encore en cours de réception." fi } export -f check_and_move import_downloaded_file() { find "$DOSSIER_SOURCE" -maxdepth 1 -type f \( -iname "*.mp4" -o -iname "*.mov" \) -print0 \ | parallel -0 -j 4 check_and_move } 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() { local raw="$1" local thumbnail="$2" ffmpeg -ss 00:00:03 -i $raw -vframes 1 $thumbnail 2>/dev/null } 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")" # récupérer les infos eventuelles dans la BDD # si fichier videos existent toujours ingorer, sinon écraser # TODO 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 convert_raws() { if $PROCESS_ALL; then find "$DOSSIER_DESTINATION_RAW" -type f \ -name "*.mov" \ -print0 | parallel -0 -j 4 iphone_video find "$DOSSIER_DESTINATION_RAW" -type f \ -name "screenrecording*.mp4" \ -print0 | parallel -0 -j 4 screen_video find "$DOSSIER_DESTINATION_RAW" -type f \ -name '*[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]*.mp4' \ -print0 | parallel -0 -j 4 whatsapp_video else if [ -f "$TEMP_FILE" ]; then while IFS= read -r file || [ -n "$file" ]; do file=$(echo "$file" | tr -d '\r' | xargs) # Ignorer les lignes vides if [ -z "$file" ]; then continue fi echo "Dealing with $file" local filename=$(basename "$file") if [[ "$filename" == *.mov ]]; then iphone_video "$file" elif [[ "$filename" == screenrecording*.mp4 ]]; then screen_video "$file" elif [[ "$filename" =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.mp4$ ]]; then whatsapp_video "$file" else echo "$file didn't match any pattern" fi done < "$TEMP_FILE" fi fi } $PRINT_ERR || exec 2> /tmp/DanceVideos.stderr convert_raws set -x if [ 0 -lt $(wc -l /tmp/dancevideos_moved_files.txt | awk '{print $1}') ]; then STREAMLIT_PID=$(ps aux | grep streamlit | grep -v 'grep' | awk '{print $2}'); [ ! -z "$STREAMLIT_PID" ] && kill $STREAMLIT_PID (cd $SCRIPTS_DIR/..; source .venv/bin/activate; streamlit run app/app.py -- --unlabeled) fi