# [メタ情報] # 識別子: 動画をGIFに変換_exe # システム名: 未分類 # 技術種別: Misc # 機能名: Misc # 使用言語: [] # 状態: 実行用 # [/メタ情報] 要約:動画ファイルを軽量GIFに変換するAutomator用Zshスクリプト。ffmpegを利用し、FPS=8・最大幅1280px・色数128・bayerディザで容量を抑制。2パス方式でパレット生成と適用を行い、既存GIFは上書き保存する。競合防止のため一時ロックを使用し、詳細ログを~/Library/Logs/QuickActions/gifify_debug.logに記録。エラーやスキップ処理にも対応している。 #!/bin/zsh set -o pipefail # ===== ログ(通知・アラートは使いません) ===== LOGDIR="$HOME/Library/Logs/QuickActions" mkdir -p "$LOGDIR" LOG="$LOGDIR/gifify_debug.log" { echo "================ $(date '+%F %T') ================" echo "Args count: $#" echo "Args list: $@" } >> "$LOG" # ===== ffmpeg の場所(固定) ===== FFMPEG="/usr/local/bin/ffmpeg" if [[ ! -x "$FFMPEG" ]]; then echo "ffmpeg not found at $FFMPEG" >> "$LOG" exit 1 fi # =====(任意)競合回避ロック ===== LOCK="/tmp/xxxxxxxx_gifify.lock" /bin/rm -f "$LOCK" 2>/dev/null /usr/bin/touch "$LOCK" trap '/bin/rm -f "$LOCK"' EXIT INT TERM # ===== 画質・容量パラメータ(軽量版) ===== FPS=8 # 動きは十分滑らかで容量抑制 MAX_W=1280 # 横幅を2/3に(肉眼での文字判読はほぼ維持) MAX_COLORS=128 # 色数削減 DITHER="bayer" # 軽量ディザ # CUT="-t 8" # テスト短縮用 # scale:min() のカンマ問題を避けるため if(gte()) を使用 SCALE_EXPR="scale=w=if(gte(iw\\,${MAX_W})\\,${MAX_W}\\,iw):h=-2:flags=lanczos" # ===== 入力チェック ===== if [[ $# -eq 0 ]]; then echo "No input from Automator" >> "$LOG" exit 0 fi # ===== 本処理(2パス:palettegen → paletteuse) ===== for f in "$@"; do echo "Processing: $f" >> "$LOG" [[ -f "$f" ]] || { echo "Skip (not a file): $f" >> "$LOG"; continue; } dir="$(/usr/bin/dirname "$f")" base="$(/usr/bin/basename "$f")" name="${base%.*}" out="${dir}/${name}.gif" pal="$(/usr/bin/mktemp -t pal_XXXXXX).png" # 上書き対応 /bin/rm -f "$out" 2>/dev/null # 1) パレット生成:fps/scale→色数160でパレット作成 "$FFMPEG" -hide_banner -loglevel error -stats -y -nostdin \ -i "$f" ${CUT:-} \ -vf "fps=${FPS},${SCALE_EXPR},palettegen=max_colors=${MAX_COLORS}:stats_mode=diff" \ "$pal" 2>>"$LOG" || { echo "palettegen failed: $f" >> "$LOG" /bin/rm -f "$pal" continue } # 2) パレット適用:同じフィルタ列 + 軽量ディザ "$FFMPEG" -hide_banner -loglevel error -stats -y -nostdin \ -i "$f" -i "$pal" ${CUT:-} \ -lavfi "fps=${FPS},${SCALE_EXPR},paletteuse=dither=${DITHER}:diff_mode=rectangle" \ -loop 0 \ "$out" 2>>"$LOG" || { echo "gif encode failed: $f" >> "$LOG" /bin/rm -f "$pal" continue } /bin/rm -f "$pal" if [[ -f "$out" ]]; then echo "Done: $out (overwritten if existed)" >> "$LOG" else echo "Error: output not created for $f" >> "$LOG" fi done echo "================ end =================" >> "$LOG"