Merge pull request #5 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
This commit is contained in:
+2
-3
@@ -43,8 +43,7 @@ target_per_clip=$(echo "scale=6; $music_duration / $DAYS_IN_MVT" | bc)
|
|||||||
echo "Target clip duration: $target_per_clip s ($DAYS_IN_MVT days in movement)"
|
echo "Target clip duration: $target_per_clip s ($DAYS_IN_MVT days in movement)"
|
||||||
|
|
||||||
# ── Locate yesterday's images ─────────────────────────────────────────────────
|
# ── Locate yesterday's images ─────────────────────────────────────────────────
|
||||||
script_name=$(basename "$SCRIPT_DIR" | cut -d'-' -f1)
|
image_dir="$base_dir/$CAM_NAME/$yesterday"
|
||||||
image_dir="$base_dir/$script_name/$yesterday"
|
|
||||||
|
|
||||||
if [ ! -d "$image_dir" ]; then
|
if [ ! -d "$image_dir" ]; then
|
||||||
echo "WARNING: Image directory $image_dir not found — skipping $yesterday."
|
echo "WARNING: Image directory $image_dir not found — skipping $yesterday."
|
||||||
@@ -59,7 +58,7 @@ fi
|
|||||||
echo "Images found: $total_images"
|
echo "Images found: $total_images"
|
||||||
|
|
||||||
# ── Prepare output directory ──────────────────────────────────────────────────
|
# ── Prepare output directory ──────────────────────────────────────────────────
|
||||||
output_dir="$base_dir/movies/$script_name/$ASTRO_YEAR/$SEASON/Mvt$MVT_NUM"
|
output_dir="$base_dir/movies/$CAM_NAME/$ASTRO_YEAR/$SEASON/Mvt$MVT_NUM"
|
||||||
mkdir -p "$output_dir"
|
mkdir -p "$output_dir"
|
||||||
|
|
||||||
# ── Build sorted image list ───────────────────────────────────────────────────
|
# ── Build sorted image list ───────────────────────────────────────────────────
|
||||||
|
|||||||
+2
-3
@@ -17,9 +17,8 @@ RETENTION_DAYS=10 # full-day videos older than this are deleted
|
|||||||
|
|
||||||
# ── Date / paths ──────────────────────────────────────────────────────────────
|
# ── Date / paths ──────────────────────────────────────────────────────────────
|
||||||
yesterday=$(date --date="yesterday" +%Y-%m-%d)
|
yesterday=$(date --date="yesterday" +%Y-%m-%d)
|
||||||
script_name=$(basename "$SCRIPT_DIR" | cut -d'-' -f1)
|
image_dir="$base_dir/$CAM_NAME/$yesterday"
|
||||||
image_dir="$base_dir/$script_name/$yesterday"
|
output_dir="$base_dir/movies/$CAM_NAME/fullday"
|
||||||
output_dir="$base_dir/movies/$script_name/fullday"
|
|
||||||
mkdir -p "$output_dir"
|
mkdir -p "$output_dir"
|
||||||
|
|
||||||
# ── Purge old full-day videos ─────────────────────────────────────────────────
|
# ── Purge old full-day videos ─────────────────────────────────────────────────
|
||||||
|
|||||||
Executable
+115
@@ -0,0 +1,115 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# install.sh — generate and install sky-cam systemd units from sky-cam.conf.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./install.sh # installs to ~/.config/systemd/user (no root needed)
|
||||||
|
# ./install.sh --system # installs to /etc/systemd/system (needs sudo)
|
||||||
|
#
|
||||||
|
# Run this once after editing sky-cam.conf, and again whenever sky-cam.conf
|
||||||
|
# changes (e.g. SCRIPT_DIR moves). No other file needs editing.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HERE="$(dirname "$(realpath "$0")")"
|
||||||
|
source "$HERE/sky-cam.conf"
|
||||||
|
|
||||||
|
# ── Install target ────────────────────────────────────────────────────────────
|
||||||
|
SYSTEM_MODE=false
|
||||||
|
[ "${1:-}" = "--system" ] && SYSTEM_MODE=true
|
||||||
|
|
||||||
|
if $SYSTEM_MODE; then
|
||||||
|
UNIT_DIR="/etc/systemd/system"
|
||||||
|
SC="sudo systemctl"
|
||||||
|
else
|
||||||
|
UNIT_DIR="$HOME/.config/systemd/user"
|
||||||
|
SC="systemctl --user"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$UNIT_DIR"
|
||||||
|
echo "Installing systemd units to $UNIT_DIR ..."
|
||||||
|
|
||||||
|
# ── Helper: write a oneshot service unit ─────────────────────────────────────
|
||||||
|
write_service() {
|
||||||
|
local unit="$1" description="$2" script="$3" extra="${4:-}"
|
||||||
|
cat > "$UNIT_DIR/${unit}.service" <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Sky-Cam ($CAM_NAME) — $description
|
||||||
|
${extra}OnFailure=sky-cam-notify-failure@%n.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=$SCRIPT_DIR/$script
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
EOF
|
||||||
|
echo " wrote ${unit}.service"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Helper: write a timer unit ───────────────────────────────────────────────
|
||||||
|
write_timer() {
|
||||||
|
local unit="$1" description="$2" calendar="$3"
|
||||||
|
cat > "$UNIT_DIR/${unit}.timer" <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Sky-Cam ($CAM_NAME) — $description
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=$calendar
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
EOF
|
||||||
|
echo " wrote ${unit}.timer"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Failure notification template ────────────────────────────────────────────
|
||||||
|
cat > "$UNIT_DIR/sky-cam-notify-failure@.service" <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Sky-Cam notify on failure for %i
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=$SCRIPT_DIR/notify.sh "sky-cam job failed: %i" "systemd unit %i failed — check: journalctl -u %i"
|
||||||
|
EOF
|
||||||
|
echo " wrote sky-cam-notify-failure@.service"
|
||||||
|
|
||||||
|
# ── Three daily jobs ──────────────────────────────────────────────────────────
|
||||||
|
# Sunrise video → Mattermost (run after sunrise window ends)
|
||||||
|
write_service "sky-cam-sunrise" \
|
||||||
|
"daily sunrise video → Mattermost" \
|
||||||
|
"sunrise_video.10s.sh" \
|
||||||
|
"After=network-online.target\nWants=network-online.target\n"
|
||||||
|
write_timer "sky-cam-sunrise" "daily sunrise video" "*-*-* 09:00:00"
|
||||||
|
|
||||||
|
# Four Seasons daily clip (auto-triggers montage + year-end on last days)
|
||||||
|
write_service "sky-cam-4seasons" \
|
||||||
|
"Four Seasons daily clip" \
|
||||||
|
"4-seasons.sh" \
|
||||||
|
"After=network-online.target\nWants=network-online.target\n"
|
||||||
|
write_timer "sky-cam-4seasons" "Four Seasons daily clip" "*-*-* 01:00:00"
|
||||||
|
|
||||||
|
# Full-day timelapse with 10-day retention
|
||||||
|
write_service "sky-cam-fullday" \
|
||||||
|
"full-day timelapse" \
|
||||||
|
"fullday-video.sh"
|
||||||
|
write_timer "sky-cam-fullday" "full-day timelapse" "*-*-* 02:00:00"
|
||||||
|
|
||||||
|
# ── Reload and enable ─────────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
$SC daemon-reload
|
||||||
|
|
||||||
|
for timer in sky-cam-sunrise sky-cam-4seasons sky-cam-fullday; do
|
||||||
|
$SC enable --now "${timer}.timer" \
|
||||||
|
&& echo " enabled + started ${timer}.timer" \
|
||||||
|
|| echo " WARNING: could not enable ${timer}.timer"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done. Check status with:"
|
||||||
|
if $SYSTEM_MODE; then
|
||||||
|
echo " sudo systemctl list-timers 'sky-cam-*'"
|
||||||
|
echo " sudo journalctl -u sky-cam-4seasons.service -f"
|
||||||
|
else
|
||||||
|
echo " systemctl --user list-timers 'sky-cam-*'"
|
||||||
|
echo " journalctl --user -u sky-cam-4seasons.service -f"
|
||||||
|
fi
|
||||||
+1
-2
@@ -38,8 +38,7 @@ eval "$(python3 "$SCRIPT_DIR/season_info.py" ${DATE_ARG:+"$DATE_ARG"})"
|
|||||||
echo "Season=$SEASON Mvt=$MVT_NUM Year=$ASTRO_YEAR (ref: ${DATE_ARG:-today})"
|
echo "Season=$SEASON Mvt=$MVT_NUM Year=$ASTRO_YEAR (ref: ${DATE_ARG:-today})"
|
||||||
|
|
||||||
# ── Locate files ──────────────────────────────────────────────────────────────
|
# ── Locate files ──────────────────────────────────────────────────────────────
|
||||||
script_name=$(basename "$SCRIPT_DIR" | cut -d'-' -f1)
|
video_dir="$base_dir/movies/$CAM_NAME/$ASTRO_YEAR/$SEASON/Mvt$MVT_NUM"
|
||||||
video_dir="$base_dir/movies/$script_name/$ASTRO_YEAR/$SEASON/Mvt$MVT_NUM"
|
|
||||||
output_dir="$video_dir/montage"
|
output_dir="$video_dir/montage"
|
||||||
mkdir -p "$output_dir"
|
mkdir -p "$output_dir"
|
||||||
|
|
||||||
|
|||||||
+103
-12
@@ -1,33 +1,124 @@
|
|||||||
# sky-cam.conf — single config for all sky-cam scripts and Python helpers.
|
# =============================================================================
|
||||||
|
# sky-cam.conf — master configuration for all sky-cam scripts
|
||||||
|
# =============================================================================
|
||||||
#
|
#
|
||||||
# Bash scripts source this file:
|
# This is the ONLY file you need to edit. After editing, run:
|
||||||
# source "$(dirname "$(realpath "$0")")/sky-cam.conf"
|
|
||||||
#
|
#
|
||||||
# Python reads it with key=value parsing (same format, quotes stripped).
|
# ./install.sh # installs systemd timers (no root needed)
|
||||||
|
# ./install.sh --system # system-wide install (requires sudo)
|
||||||
#
|
#
|
||||||
# Copy this file to your scripts directory and fill in every value.
|
# Re-run install.sh any time this file changes.
|
||||||
# Lines starting with # are comments and are ignored.
|
#
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# MANUAL SYSTEMD SETUP (if you prefer not to use install.sh)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# After editing this file, generate the unit files:
|
||||||
|
#
|
||||||
|
# mkdir -p ~/.config/systemd/user
|
||||||
|
# cp systemd/*.service systemd/*.timer ~/.config/systemd/user/
|
||||||
|
#
|
||||||
|
# Then edit ExecStart= in each .service file to match your SCRIPT_DIR, then:
|
||||||
|
#
|
||||||
|
# systemctl --user daemon-reload
|
||||||
|
# systemctl --user enable --now sky-cam-sunrise.timer # 09:00 daily
|
||||||
|
# systemctl --user enable --now sky-cam-4seasons.timer # 01:00 daily
|
||||||
|
# systemctl --user enable --now sky-cam-fullday.timer # 02:00 daily
|
||||||
|
#
|
||||||
|
# Check status:
|
||||||
|
# systemctl --user list-timers 'sky-cam-*'
|
||||||
|
# journalctl --user -u sky-cam-4seasons.service -f
|
||||||
|
#
|
||||||
|
# System-wide (replace --user with no flag, prepend sudo):
|
||||||
|
# sudo cp systemd/*.service systemd/*.timer /etc/systemd/system/
|
||||||
|
# sudo systemctl daemon-reload && sudo systemctl enable --now sky-cam-*.timer
|
||||||
|
#
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SCRIPT MAP — what each file does and when it runs
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# You run / schedule:
|
||||||
|
# sunrise_video.10s.sh — daily at 09:00 (via systemd)
|
||||||
|
# grabs today's sunrise images, makes a 10-second
|
||||||
|
# video, uploads it to Mattermost
|
||||||
|
#
|
||||||
|
# 4-seasons.sh — daily at 01:00 (via systemd)
|
||||||
|
# makes yesterday's daily clip sized to its share
|
||||||
|
# of the matching Vivaldi movement's music duration;
|
||||||
|
# on the last day of a movement, auto-triggers
|
||||||
|
# montage-mvt.sh
|
||||||
|
#
|
||||||
|
# fullday-video.sh — daily at 02:00 (via systemd)
|
||||||
|
# full-day timelapse at fixed fps; deletes files
|
||||||
|
# older than 10 days automatically
|
||||||
|
#
|
||||||
|
# install.sh — run once at setup, and again if this file changes
|
||||||
|
# generates and installs systemd units from conf
|
||||||
|
#
|
||||||
|
# stitch-cameras.py — run manually when needed
|
||||||
|
# stitches north + sunrise into a panorama
|
||||||
|
# usage: python3 stitch-cameras.py north.jpg sunrise.jpg prefix [focal]
|
||||||
|
#
|
||||||
|
# Auto-triggered (do not run directly):
|
||||||
|
# montage-mvt.sh — called by 4-seasons.sh on last day of each movement
|
||||||
|
# concatenates all daily clips for the movement,
|
||||||
|
# speed-adjusts to match music, overlays attribution,
|
||||||
|
# sends completion notification; on last Autumn
|
||||||
|
# movement also triggers year-end-join.sh
|
||||||
|
#
|
||||||
|
# year-end-join.sh — called by montage-mvt.sh at end of Autumn Mvt 3
|
||||||
|
# concatenates all 12 movement montages into one
|
||||||
|
# Four Seasons year video, sends notification
|
||||||
|
#
|
||||||
|
# Helpers (called by the scripts above, not run directly):
|
||||||
|
# notify.sh — sends notifications via ntfy / email / Mattermost
|
||||||
|
# season_info.py — outputs astronomical season/movement/year for a date
|
||||||
|
# sunrise.py — outputs today's sunrise time (used by sunrise_video)
|
||||||
|
# sunrise2mm.py — uploads the sunrise video to Mattermost
|
||||||
|
#
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
# ── Paths ─────────────────────────────────────────────────────────────────────
|
# ── Install location ──────────────────────────────────────────────────────────
|
||||||
|
# Full path to the directory containing this file and all the scripts.
|
||||||
|
SCRIPT_DIR=/home/motion/drives/local-2tb/sunrise-scripts
|
||||||
|
|
||||||
|
# Camera name — subfolder under BASE_DIR (images) and BASE_DIR/movies (videos).
|
||||||
|
# E.g. "sunrise" → images: $BASE_DIR/sunrise/YYYY-MM-DD/ videos: $BASE_DIR/movies/sunrise/
|
||||||
|
CAM_NAME=sunrise
|
||||||
|
|
||||||
|
# ── Storage ───────────────────────────────────────────────────────────────────
|
||||||
BASE_DIR=/home/motion/drives/local-2tb
|
BASE_DIR=/home/motion/drives/local-2tb
|
||||||
MUSIC_DIR=/home/motion/drives/local-2tb/music/4 Seasons
|
MUSIC_DIR=/home/motion/drives/local-2tb/music/4 Seasons
|
||||||
|
|
||||||
|
# ── Location & timezone ───────────────────────────────────────────────────────
|
||||||
|
# Used by sunrise.py to calculate sunrise time each day.
|
||||||
|
# TIMEZONE must be a valid IANA name: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
|
LATITUDE=38.123456
|
||||||
|
LONGITUDE=-97.654321
|
||||||
TIMEZONE=America/New_York
|
TIMEZONE=America/New_York
|
||||||
|
|
||||||
# ── Mattermost — daily sunrise upload ────────────────────────────────────────
|
# ── Mattermost — daily sunrise upload ─────────────────────────────────────────
|
||||||
mattermost_url=https://your-mattermost-server.example.com
|
mattermost_url=https://your-mattermost-server.example.com
|
||||||
access_token=your-access-token-here
|
access_token=your-access-token-here
|
||||||
channel_id=your-daily-upload-channel-id-here
|
channel_id=your-daily-upload-channel-id-here
|
||||||
|
|
||||||
# ── Notifications — movement montage + year-end video complete / job failure ──
|
# ── Notifications — montage / year-end complete + any job failure ─────────────
|
||||||
# ntfy: https://ntfy.sh (cloud) or self-hosted. Set topic URL below.
|
# Notifications fire when a movement montage or the year video finishes.
|
||||||
|
# They also fire automatically via systemd OnFailure= if any daily job fails.
|
||||||
|
# Enable one or more methods below.
|
||||||
|
|
||||||
|
# ntfy — push notifications, zero signup required for self-hosted:
|
||||||
|
# https://docs.ntfy.sh/install/
|
||||||
|
# or use the free cloud tier at ntfy.sh (pick any topic name)
|
||||||
NTFY_ENABLED=false
|
NTFY_ENABLED=false
|
||||||
NTFY_URL=https://ntfy.sh/your-topic-here
|
NTFY_URL=https://ntfy.sh/your-topic-here
|
||||||
|
|
||||||
# Email: requires the 'mail' command (mailutils / s-nail).
|
# Email — requires the 'mail' command on the system (package: mailutils or s-nail).
|
||||||
|
# For outbound SMTP configure /etc/ssmtp/ssmtp.conf or msmtp.
|
||||||
EMAIL_ENABLED=false
|
EMAIL_ENABLED=false
|
||||||
EMAIL_TO=you@example.com
|
EMAIL_TO=you@example.com
|
||||||
EMAIL_FROM=skycam@localhost
|
EMAIL_FROM=skycam@localhost
|
||||||
|
|
||||||
# Mattermost text post (can be same channel as daily upload or a private one).
|
# Mattermost text post — reuses the URL and token above, but posts to this
|
||||||
|
# channel (can be the same daily channel or a separate private/admin channel).
|
||||||
MM_NOTIFY_ENABLED=false
|
MM_NOTIFY_ENABLED=false
|
||||||
MM_NOTIFY_CHANNEL_ID=your-notify-channel-id-here
|
MM_NOTIFY_CHANNEL_ID=your-notify-channel-id-here
|
||||||
|
|||||||
+18
-35
@@ -1,47 +1,30 @@
|
|||||||
#from suntime import Sun
|
from datetime import datetime
|
||||||
#from datetime import datetime, timedelta
|
import pathlib
|
||||||
#import pytz
|
|
||||||
|
|
||||||
#latitude = YOUR_LATITUDE
|
|
||||||
#longitude = YOUR_LONGITUDE
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#sun = Sun(latitude, longitude)
|
|
||||||
#tz = pytz.timezone(timezone)
|
|
||||||
|
|
||||||
# Get yesterday's date and time
|
|
||||||
#yesterday = datetime.now(tz) - timedelta(days=1)
|
|
||||||
#sunrise_time = sun.get_sunrise_time(yesterday).astimezone(tz)
|
|
||||||
|
|
||||||
# Print the sunrise time
|
|
||||||
#print(sunrise_time.strftime('%Y-%m-%d %H:%M:%S'))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import pytz
|
import pytz
|
||||||
from suntime import Sun
|
from suntime import Sun
|
||||||
|
|
||||||
# Example coordinates (e.g., New York City)
|
# Locate sky-cam.conf next to this script (works regardless of cwd).
|
||||||
latitude = re.dacted
|
_here = pathlib.Path(__file__).resolve().parent
|
||||||
longitude = re.dacted
|
|
||||||
|
|
||||||
|
def _read_conf(path):
|
||||||
|
conf = {}
|
||||||
|
with open(path) as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith('#') and '=' in line:
|
||||||
|
k, v = line.split('=', 1)
|
||||||
|
conf[k.strip()] = v.strip()
|
||||||
|
return conf
|
||||||
|
|
||||||
# Define the timezone
|
conf = _read_conf(_here / 'sky-cam.conf')
|
||||||
tz = pytz.timezone('America/New_York')
|
|
||||||
|
latitude = float(conf['LATITUDE'])
|
||||||
|
longitude = float(conf['LONGITUDE'])
|
||||||
|
tz = pytz.timezone(conf['TIMEZONE'])
|
||||||
|
|
||||||
# Create a Sun object with the given latitude and longitude
|
|
||||||
sun = Sun(latitude, longitude)
|
sun = Sun(latitude, longitude)
|
||||||
|
|
||||||
# Get today's date and time in the desired timezone
|
|
||||||
now = datetime.now(tz)
|
now = datetime.now(tz)
|
||||||
|
|
||||||
# Get today's sunrise time in UTC and convert it to the desired timezone
|
|
||||||
sunrise_utc = sun.get_sunrise_time(now)
|
sunrise_utc = sun.get_sunrise_time(now)
|
||||||
sunrise_time = sunrise_utc.astimezone(tz)
|
sunrise_time = sunrise_utc.astimezone(tz)
|
||||||
|
|
||||||
# Print the sunrise time in the desired format
|
|
||||||
print(sunrise_time.strftime('%Y-%m-%d %H:%M:%S'))
|
print(sunrise_time.strftime('%Y-%m-%d %H:%M:%S'))
|
||||||
|
|||||||
+2
-2
@@ -45,8 +45,8 @@ today_date_str = today.strftime("%Y-%m-%d") # e.g., "2024-11-05"
|
|||||||
today_month_str = today.strftime("%Y-%m") # e.g., "2024-11"
|
today_month_str = today.strftime("%Y-%m") # e.g., "2024-11"
|
||||||
|
|
||||||
# Set the full folder path for today's video
|
# Set the full folder path for today's video
|
||||||
base_video_folder = "/home/motion/drives/local-2tb/movies/sunrise" # Correct base folder for videos
|
base_video_folder = os.path.join(config.get('BASE_DIR', ''), 'movies', config.get('CAM_NAME', 'sunrise'))
|
||||||
output_dir = os.path.join(base_video_folder, today_month_str, "sunrise-only") # Subfolder for final videos
|
output_dir = os.path.join(base_video_folder, today_month_str, "sunrise-only")
|
||||||
|
|
||||||
# Check if the directory exists
|
# Check if the directory exists
|
||||||
if not os.path.isdir(output_dir):
|
if not os.path.isdir(output_dir):
|
||||||
|
|||||||
+9
-11
@@ -1,25 +1,23 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||||
|
source "$SCRIPT_DIR/sky-cam.conf"
|
||||||
|
|
||||||
# Get today's date in the format YYYY-MM-DD
|
# Get today's date in the format YYYY-MM-DD
|
||||||
current_date=$(date +%Y-%m-%d)
|
current_date=$(date +%Y-%m-%d)
|
||||||
output_date=$(date +%Y-%m)
|
output_date=$(date +%Y-%m)
|
||||||
|
|
||||||
# Extract the base directory and the first word of the script's folder name
|
|
||||||
base_dir="/home/motion/drives/local-2tb"
|
|
||||||
script_dir=$(dirname "$(realpath "$0")") # Get the directory where the script is located
|
|
||||||
first_word_of_script_folder=$(basename "$script_dir" | cut -d'-' -f1)
|
|
||||||
|
|
||||||
# Define the directory where images are stored (using today's date)
|
# Define the directory where images are stored (using today's date)
|
||||||
image_dir="$base_dir/$first_word_of_script_folder/$current_date"
|
image_dir="$BASE_DIR/$CAM_NAME/$current_date"
|
||||||
|
|
||||||
# Set output directory (new structure with 'sunrise-only' subfolder)
|
# Set output directory
|
||||||
output_dir="/home/motion/drives/local-2tb/movies/sunrise/$output_date/sunrise-only"
|
output_dir="$BASE_DIR/movies/$CAM_NAME/$output_date/sunrise-only"
|
||||||
|
|
||||||
# Make sure the output directory exists
|
# Make sure the output directory exists
|
||||||
mkdir -p "$output_dir"
|
mkdir -p "$output_dir"
|
||||||
|
|
||||||
# Get the sunrise time for today using the sunrise.py script
|
# Get the sunrise time for today using the sunrise.py script
|
||||||
sunrise_time=$(python3 /home/motion/drives/local-2tb/sunrise-scripts/sunrise.py)
|
sunrise_time=$(python3 "$SCRIPT_DIR/sunrise.py")
|
||||||
|
|
||||||
# Check if the sunrise time was fetched successfully
|
# Check if the sunrise time was fetched successfully
|
||||||
if [[ -z "$sunrise_time" ]]; then
|
if [[ -z "$sunrise_time" ]]; then
|
||||||
@@ -143,10 +141,10 @@ echo "Video created at $final_video"
|
|||||||
rm "$temp_file"
|
rm "$temp_file"
|
||||||
|
|
||||||
# Run the sunrise_overlay.py script to add the sunrise overlay
|
# Run the sunrise_overlay.py script to add the sunrise overlay
|
||||||
python3 /home/motion/drives/local-2tb/sunrise-scripts/sunrise_overlay.py "$final_video"
|
python3 "$SCRIPT_DIR/sunrise_overlay.py" "$final_video"
|
||||||
|
|
||||||
# Run the sunrise2mm.py script to upload the video
|
# Run the sunrise2mm.py script to upload the video
|
||||||
python3 /home/motion/drives/local-2tb/sunrise-scripts/sunrise2mm.py
|
python3 "$SCRIPT_DIR/sunrise2mm.py"
|
||||||
|
|
||||||
# Check if the Python script was successful
|
# Check if the Python script was successful
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
|
|||||||
+4
-6
@@ -8,7 +8,7 @@
|
|||||||
# The 12 individual movement videos already carry their own attribution overlay
|
# The 12 individual movement videos already carry their own attribution overlay
|
||||||
# (first 6 seconds of each), so no extra card is appended here.
|
# (first 6 seconds of each), so no extra card is appended here.
|
||||||
#
|
#
|
||||||
# Output: $base_dir/movies/$script_name/$ASTRO_YEAR/$script_name-$ASTRO_YEAR.mp4
|
# Output: $BASE_DIR/movies/$CAM_NAME/$ASTRO_YEAR/$CAM_NAME-$ASTRO_YEAR.mp4
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -21,9 +21,7 @@ if [ -z "$ASTRO_YEAR" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
base_dir="$BASE_DIR"
|
year_dir="$BASE_DIR/movies/$CAM_NAME/$ASTRO_YEAR"
|
||||||
script_name=$(basename "$SCRIPT_DIR" | cut -d'-' -f1)
|
|
||||||
year_dir="$base_dir/movies/$script_name/$ASTRO_YEAR"
|
|
||||||
|
|
||||||
echo "Assembling Four Seasons $ASTRO_YEAR from $year_dir ..."
|
echo "Assembling Four Seasons $ASTRO_YEAR from $year_dir ..."
|
||||||
|
|
||||||
@@ -60,7 +58,7 @@ if [ "$missing" -gt 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Join ──────────────────────────────────────────────────────────────────────
|
# ── Join ──────────────────────────────────────────────────────────────────────
|
||||||
output_file="$year_dir/${script_name}-${ASTRO_YEAR}.mp4"
|
output_file="$year_dir/${CAM_NAME}-${ASTRO_YEAR}.mp4"
|
||||||
echo "Output: $output_file"
|
echo "Output: $output_file"
|
||||||
|
|
||||||
ffmpeg -loglevel warning \
|
ffmpeg -loglevel warning \
|
||||||
@@ -74,5 +72,5 @@ echo "Done: $output_file (${total_min} min)"
|
|||||||
# ── Notify ────────────────────────────────────────────────────────────────────
|
# ── Notify ────────────────────────────────────────────────────────────────────
|
||||||
"$SCRIPT_DIR/notify.sh" \
|
"$SCRIPT_DIR/notify.sh" \
|
||||||
"Four Seasons $ASTRO_YEAR complete" \
|
"Four Seasons $ASTRO_YEAR complete" \
|
||||||
"${script_name}-${ASTRO_YEAR}.mp4 — ${total_min} minutes ($found movements)" \
|
"${CAM_NAME}-${ASTRO_YEAR}.mp4 — ${total_min} minutes ($found movements)" \
|
||||||
|| true
|
|| true
|
||||||
|
|||||||
Reference in New Issue
Block a user