😑

Raspberry Pi 5:画像・動画の自動圧縮スクリプト構築記録

に公開

🎯 目的
Raspberry Pi 5 上に蓄積された画像・動画ファイルの容量を抑えるため、圧縮処理を定期的に自動実行する仕組みを構築。元ファイルは圧縮後に削除し、結果はログとして記録する。

📁 構成概要
圧縮対象フォルダ:
/home/[USER]/sharePhoto

圧縮後保存フォルダ(除外対象):
/home/[USER]/sharePhoto/Shred_Photos

Pythonスクリプト配置先:
/home/[USER]/projects/photo_backup

仮想環境:
/home/[USER]/photoenv

設定ファイル:
/home/[USER]/projects/photo_backup/config.json

ログファイル:
/home/[USER]/projects/photo_backup/compression.log

📜 Python スクリプト:photo_compression.py
python
コピーする
編集する
import os
import json
import logging
import subprocess
from PIL import Image

設定読み込み

with open(os.path.join(os.path.dirname(file), 'config.json'), 'r') as f:
config = json.load(f)

input_dir = config['input_dir']
output_dir = config['output_dir']
exclude_dirs = config.get('exclude_dirs', [])

ログ設定

log_path = os.path.join(os.path.dirname(file), 'compression.log')
logging.basicConfig(
filename=log_path,
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)

def is_image(file_name):
return file_name.lower().endswith(('.jpg', '.jpeg', '.png'))

def is_video(file_name):
return file_name.lower().endswith(('.mp4', '.mov', '.avi', '.mkv'))

def compress_image(file_path, output_path):
try:
with Image.open(file_path) as img:
img.save(output_path, optimize=True, quality=85)
return True
except Exception as e:
logging.error(f"画像圧縮失敗: {file_path} - {e}")
return False

def compress_video(file_path, output_path):
try:
result = subprocess.run([
'ffmpeg', '-y', '-i', file_path,
'-vcodec', 'libx264', '-crf', '28', '-preset', 'fast',
output_path
], capture_output=True, text=True)
if result.returncode != 0:
raise Exception(result.stderr)
return True
except Exception as e:
logging.error(f"動画圧縮失敗: {file_path} - {e}")
return False

def should_exclude(path):
for exclude in exclude_dirs:
if os.path.commonpath([exclude, path]) == exclude:
return True
return False

def main():
logging.info("=== 圧縮処理開始 ===")
for root, dirs, files in os.walk(input_dir):
if should_exclude(root):
continue

    rel_path = os.path.relpath(root, input_dir)
    output_subdir = os.path.join(output_dir, rel_path)

    try:
        os.makedirs(output_subdir, exist_ok=True)
    except Exception as e:
        logging.error(f"出力フォルダ作成失敗: {output_subdir} - {e}")
        continue

    for file_name in files:
        file_path = os.path.join(root, file_name)

        if is_image(file_name):
            output_file = os.path.join(output_subdir, file_name)
            if compress_image(file_path, output_file):
                os.remove(file_path)
        elif is_video(file_name):
            name, _ = os.path.splitext(file_name)
            output_file = os.path.join(output_subdir, f"{name}_compressed.mp4")
            if compress_video(file_path, output_file):
                os.remove(file_path)

logging.info("=== 圧縮処理終了 ===")

if name == 'main':
main()
⚙️ 設定ファイル:config.json
json
コピーする
編集する
{
"input_dir": "/home/[USER]/sharePhoto",
"output_dir": "/home/[USER]/sharePhoto/Shred_Photos",
"exclude_dirs": [
"/home/[USER]/sharePhoto/Shred_Photos"
]
}
📌 セットアップ手順まとめ

  1. 仮想環境の作成と依存インストール
    bash
    コピーする
    編集する
    python3 -m venv ~/photoenv
    source ~/photoenv/bin/activate
    pip install pillow
    sudo apt install ffmpeg
  2. 所有権の修正(必要に応じて)
    bash
    コピーする
    編集する
    sudo chown -R [USER]:[USER] /home/[USER]/sharePhoto
    sudo chown -R [USER]:[USER] /home/[USER]/projects/photo_backup
    🔄 cron による定期実行(例:毎日3時)
    bash
    コピーする
    編集する
    crontab -e
    cron
    コピーする
    編集する
    0 3 * * * /home/[USER]/photoenv/bin/python /home/[USER]/projects/photo_backup/photo_compression.py
    📊 圧縮確認方法
    bash
    コピーする
    編集する
    ls -lh # 各ファイルの容量をMBやKB単位で確認
    du -sh /path/to/folder # フォルダ全体の容量確認
    🧩 トラブル対処メモ
    エラー 対応
    PermissionError: compression.log スクリプトフォルダの権限を変更 (chown)
    pip install できない venv を使う。pip install は仮想環境で実施
    ffmpeg がない sudo apt install ffmpeg
    PermissionError on output_dir フォルダ所有権が root → [USER] に変更

✅ 今後の改善候補
圧縮前後サイズをログに出す機能

dry-run モードの実装(削除せず確認のみ)

圧縮失敗時のバックアップ保存対応

外部ストレージやNASへの転送機能の追加

ネットワーク越しの圧縮(高負荷対策)

Discussion