#!/bin/bash # Kịch bản chuyển đổi tất cả các file .mkv sang .mp4 một cách đệ quy. # Phiên bản cải tiến: dễ cấu hình, ghi log cho từng file và dùng tùy chọn ffmpeg hiện đại. # --- Phần cấu hình --- # Bạn có thể thay đổi các giá trị này để phù hợp với nhu cầu. # CRF (Constant Rate Factor) cho video: 0-51. Càng thấp chất lượng càng cao. 18-28 là khoảng hợp lý. CRF="23" # Preset cho tốc độ encode: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. # Càng chậm thì nén càng tốt (file nhỏ hơn) nhưng tốn thời gian hơn. 'medium' là mặc định cân bằng. PRESET="medium" # Bitrate cho audio. '128k' hoặc '192k' là phổ biến cho codec AAC. AUDIO_BITRATE="128k" # --- Bắt đầu kịch bản --- # 1. Kiểm tra xem ffmpeg đã được cài đặt chưa if ! command -v ffmpeg >/dev/null 2>&1; then echo "❌ Lỗi: Lệnh 'ffmpeg' không tồn tại. Vui lòng cài đặt ffmpeg." exit 1 fi # 2. Xác định thư mục mục tiêu (lấy tham số đầu vào, mặc định là thư mục hiện tại) DIR="${1:-.}" echo "🔍 Bắt đầu quét thư mục '$DIR'..." echo "---" # 3. Tìm và lặp qua từng file .mkv # -print0 và -d '' là cách an toàn nhất để xử lý tên file có chứa ký tự đặc biệt hoặc dấu cách. find "$DIR" -type f -iname '*.mkv' -print0 | while IFS= read -r -d '' file; do # Tạo tên file output bằng cách thay thế đuôi .mkv thành .mp4 một cách hiệu quả out_file="${file%.mkv}.mp4" log_file="${out_file}.log" # Kiểm tra nếu file .mp4 đã tồn tại thì bỏ qua if [ -f "$out_file" ]; then echo "⚠️ Bỏ qua (đã tồn tại): '$out_file'" continue fi echo "▶️ Đang chuyển đổi: '$file'" # 4. Thực thi lệnh ffmpeg # -hide_banner: Ẩn thông tin banner của ffmpeg cho log gọn hơn. # -c:v libx264 -crf $CRF -preset $PRESET: Tùy chọn encode video H.264 chất lượng cao. # -c:a aac -b:a $AUDIO_BITRATE: Tùy chọn encode audio AAC. # Ghi log (cả stdout và stderr) vào một file riêng cho mỗi video để tránh ghi đè. ffmpeg -nostdin -hide_banner -i "$file" \ -c:v libx264 -crf "$CRF" -preset "$PRESET" \ -c:a aac -b:a "$AUDIO_BITRATE" \ "$out_file" > "$log_file" 2>&1 # 5. Kiểm tra kết quả chuyển đổi và thông báo if [ $? -eq 0 ]; then echo "✅ Hoàn thành: '$out_file'" # Nếu muốn tự động xóa log khi thành công, bỏ comment dòng dưới # rm "$log_file" else echo "❌ Lỗi khi chuyển đổi file trên. Xem chi tiết trong log: '$log_file'" fi echo "---" done echo "🎉 Tất cả đã xong!"