#!/bin/bash # Скрипт для сжатия видео ScreenRecordings без потери качества # Использует H.265 (HEVC) кодек с CRF 18 (визуально без потерь) SCREENRECORDINGS_DIR="$HOME/Library/ScreenRecordings" BACKUP_DIR="$SCREENRECORDINGS_DIR/originals" TEMP_DIR="$SCREENRECORDINGS_DIR/compressed" # Цвета для вывода GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color echo "==========================================" echo " Сжатие ScreenRecordings без потери качества" echo "==========================================" echo "" # Проверка наличия ffmpeg if ! command -v ffmpeg &> /dev/null; then echo -e "${RED}Ошибка: ffmpeg не установлен${NC}" echo "Установите ffmpeg: brew install ffmpeg" exit 1 fi # Проверка существования директории if [ ! -d "$SCREENRECORDINGS_DIR" ]; then echo -e "${RED}Ошибка: директория $SCREENRECORDINGS_DIR не найдена${NC}" exit 1 fi # Создание директорий для бэкапа и временных файлов mkdir -p "$BACKUP_DIR" mkdir -p "$TEMP_DIR" # Подсчет видео файлов VIDEO_FILES=$(find "$SCREENRECORDINGS_DIR" -maxdepth 1 -type f \( -iname "*.mov" -o -iname "*.mp4" -o -iname "*.m4v" \) ! -name ".*" | wc -l | tr -d ' ') if [ "$VIDEO_FILES" -eq 0 ]; then echo -e "${YELLOW}Видео файлы не найдены в $SCREENRECORDINGS_DIR${NC}" exit 0 fi echo -e "${GREEN}Найдено видео файлов: $VIDEO_FILES${NC}" echo "" # Подсчет общего размера TOTAL_SIZE=$(du -sh "$SCREENRECORDINGS_DIR" 2>/dev/null | cut -f1) echo -e "Текущий размер: ${YELLOW}$TOTAL_SIZE${NC}" echo "" # Подтверждение read -p "Продолжить сжатие? (y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Отменено" exit 0 fi echo "" echo "Начало сжатия..." echo "" # Счетчики PROCESSED=0 SKIPPED=0 ERRORS=0 # Создание массива видео файлов mapfile -t video_files < <(find "$SCREENRECORDINGS_DIR" -maxdepth 1 -type f \( -iname "*.mov" -o -iname "*.mp4" -o -iname "*.m4v" \) ! -name ".*" | sort) # Обработка каждого видео файла for video_file in "${video_files[@]}"; do filename=$(basename "$video_file") name_without_ext="${filename%.*}" ext="${filename##*.}" # Пропускаем уже обработанные файлы if [[ "$filename" == *"_compressed"* ]] || [ -f "$BACKUP_DIR/$filename" ]; then echo -e "${YELLOW}Пропуск: $filename (уже обработан)${NC}" ((SKIPPED++)) continue fi echo "----------------------------------------" echo -e "${GREEN}Обработка: $filename${NC}" # Размер оригинального файла original_size=$(stat -f%z "$video_file" 2>/dev/null || stat -c%s "$video_file" 2>/dev/null) original_size_mb=$(echo "scale=2; $original_size / 1024 / 1024" | bc) echo " Размер оригинала: ${original_size_mb} MB" # Временный файл для сжатого видео compressed_file="$TEMP_DIR/${name_without_ext}_compressed.${ext}" # Сжатие с H.265 (HEVC) кодеком # CRF 18 = визуально без потерь качества (чем меньше, тем лучше качество, но больше размер) # preset slow = лучшее сжатие, но медленнее # pix_fmt yuv420p = совместимость с большинством плееров echo " Сжатие с H.265 (HEVC) кодеком (CRF 18, визуально без потерь)..." # Запуск ffmpeg с подавлением вывода (кроме ошибок) if ! ffmpeg -i "$video_file" \ -c:v libx265 \ -crf 18 \ -preset slow \ -c:a copy \ -pix_fmt yuv420p \ -movflags +faststart \ -y \ "$compressed_file" > /dev/null 2>&1; then echo -e " ${RED}Ошибка при сжатии: $filename${NC}" rm -f "$compressed_file" ((ERRORS++)) continue fi # Проверка, что сжатый файл создан if [ ! -f "$compressed_file" ]; then echo -e " ${RED}Ошибка: сжатый файл не создан${NC}" ((ERRORS++)) continue fi # Размер сжатого файла compressed_size=$(stat -f%z "$compressed_file" 2>/dev/null || stat -c%s "$compressed_file" 2>/dev/null) compressed_size_mb=$(echo "scale=2; $compressed_size / 1024 / 1024" | bc) # Процент сжатия if [ "$original_size" -gt 0 ]; then compression_ratio=$(echo "scale=1; (1 - $compressed_size / $original_size) * 100" | bc) echo " Размер сжатого: ${compressed_size_mb} MB" echo -e " ${GREEN}Сжатие: ${compression_ratio}%${NC}" fi # Проверка, что сжатый файл меньше оригинала if [ "$compressed_size" -lt "$original_size" ]; then # Бэкап оригинала echo " Создание бэкапа оригинала..." cp "$video_file" "$BACKUP_DIR/$filename" # Замена оригинала сжатой версией echo " Замена оригинала сжатой версией..." mv "$compressed_file" "$video_file" echo -e " ${GREEN}✓ Готово: $filename${NC}" ((PROCESSED++)) else echo -e " ${YELLOW}Сжатый файл больше оригинала, оставляем оригинал${NC}" rm -f "$compressed_file" ((SKIPPED++)) fi echo "" done # Очистка временной директории rm -rf "$TEMP_DIR" echo "==========================================" echo " Результаты" echo "==========================================" echo -e "${GREEN}Обработано: $PROCESSED${NC}" echo -e "${YELLOW}Пропущено: $SKIPPED${NC}" if [ "$ERRORS" -gt 0 ]; then echo -e "${RED}Ошибок: $ERRORS${NC}" fi echo "" # Финальный размер FINAL_SIZE=$(du -sh "$SCREENRECORDINGS_DIR" 2>/dev/null | cut -f1) echo -e "Финальный размер: ${GREEN}$FINAL_SIZE${NC}" echo "" # Информация о бэкапах if [ -d "$BACKUP_DIR" ] && [ "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then BACKUP_SIZE=$(du -sh "$BACKUP_DIR" 2>/dev/null | cut -f1) echo -e "Бэкапы оригиналов сохранены в: ${YELLOW}$BACKUP_DIR${NC} (${BACKUP_SIZE})" echo "" echo "⚠️ После проверки сжатых видео, вы можете удалить бэкапы:" echo " rm -rf $BACKUP_DIR" fi echo "" echo -e "${GREEN}Готово!${NC}"