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"
]
}
📌 セットアップ手順まとめ
- 仮想環境の作成と依存インストール
bash
コピーする
編集する
python3 -m venv ~/photoenv
source ~/photoenv/bin/activate
pip install pillow
sudo apt install ffmpeg - 所有権の修正(必要に応じて)
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