Files
Documentation/Moodle/Tools/mkv2mp4.sh
2025-08-20 09:47:42 +07:00

65 lines
2.7 KiB
Bash

#!/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!"