Giới thiệu
FFmpeg là một bộ công cụ mã nguồn mở mạnh mẽ cho phép ghi, chuyển đổi và phát luồng nội dung âm thanh, video. Nó cung cấp giải pháp toàn diện cho việc xử lý đa phương tiện nhờ vào thư viện编解码 libavcodec tiên tiến, được xây dựng lại từ đầu nhằm đảm bảo tính di động cao và chất lượng mã hóa/giải mã vượt trội.
Hướng dẫn triển khai
Cấu hình hệ thống tối thiểu yêu cầu:
| Môi trường | Phiên bản |
|---|---|
| Ubuntu | 22.04.4 LTS |
| CUDA | 12.8 |
| Python | 3.12 |
| GPU NVIDIA | RTX 4090 |
1. Cập nhật hệ thống và cấu hình nguồn trong nước
# Kiểm tra phiên bản hệ điều hành
cat /etc/os-release
# Sao lưu sources.list gốc
cp /etc/apt/sources.list /etc/apt/sources.list.bak
# Cập nhật danh sách gói
apt update
# Cài đặt các công cụ cơ bản
apt install -y vim wget git unzip lsof net-tools gcc cmake build-essential
Sau khi sao lưu, chỉnh sửa /etc/apt/sources.list để thay bằng mirror của Alibaba Cloud:
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
2. Cài đặt Miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3
source ~/.bashrc
# Cấu hình pip sử dụng mirror Tsinghua
mkdir -p ~/.pip
echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple" > ~/.pip/pip.conf
3. Cài đặt FFmpeg
sudo apt update
sudo apt install -y ffmpeg
4. Thiết lập môi trường Python và phụ thuộc
# Tạo môi trường ảo
conda create -n media_proc python=3.12 -y
conda activate media_proc
# Cài đặt thư viện cần thiết
pip install gradio numpy
5. Triển khai ứng dụng xử lý đa phương tiện
Tạo file media_handler.py với nội dung sau:
import gradio as gr
import subprocess
import os
import uuid
from pathlib import Path
from datetime import timedelta
import time
import mimetypes
# Thư mục làm việc
WORK_DIR = Path("workspace")
(WORK_DIR / "uploads").mkdir(parents=True, exist_ok=True)
(WORK_DIR / "outputs").mkdir(parents=True, exist_ok=True)
# Phát hiện phần cứng tăng tốc
def detect_accel():
try:
nvidia_smi = subprocess.run(['nvidia-smi'], capture_output=True, timeout=3)
if nvidia_smi.returncode == 0:
hwaccels = subprocess.run(['ffmpeg', '-hwaccels'], capture_output=True, text=True)
if 'cuda' in hwaccels.stdout.lower():
encoders = subprocess.run(['ffmpeg', '-encoders'], capture_output=True, text=True)
if 'h264_nvenc' in encoders.stdout.lower():
return 'nvidia'
except: pass
return 'cpu'
ACCEL_TYPE = detect_accel()
def cleanup_old_files():
now = time.time()
threshold = timedelta(hours=1).total_seconds()
for f in (WORK_DIR / "outputs").iterdir():
if now - f.stat().st_mtime > threshold:
f.unlink(missing_ok=True)
def get_media_type(filepath):
mime, _ = mimetypes.guess_type(filepath)
if mime:
if mime.startswith('video'): return 'video'
if mime.startswith('audio'): return 'audio'
if mime.startswith('image'): return 'image'
return 'unknown'
def build_ffmpeg_cmd(input_path, output_ext, params, use_accel=False):
output_path = WORK_DIR / "outputs" / f"{uuid.uuid4()}.{output_ext}"
cmd_base = ['ffmpeg', '-y']
if use_accel and ACCEL_TYPE == 'nvidia':
cmd = cmd_base + ['-hwaccel', 'cuda', '-i', input_path] + params + [str(output_path)]
else:
cmd = cmd_base + ['-i', input_path] + params + [str(output_path)]
try:
subprocess.run(cmd, check=True, capture_output=True, timeout=21600)
return str(output_path)
except subprocess.CalledProcessError as e:
raise gr.Error(f"Lỗi xử lý: {e.stderr.decode()[:200]}")
def process_file(file_obj, task_type, **kwargs):
if not file_obj: raise gr.Error("Vui lòng chọn tệp tin")
file_path = file_obj.name
media_type = get_media_type(file_path)
orig_ext = Path(file_path).suffix[1:] or 'mp4'
use_gpu = kwargs.get('use_gpu', False) and ACCEL_TYPE != 'cpu'
if task_type == "Chuyển định dạng":
target_ext = kwargs['format'] or orig_ext
return build_ffmpeg_cmd(file_path, target_ext, [], use_gpu)
elif task_type == "Cắt đoạn":
start, end = float(kwargs['start']), float(kwargs['end'])
out_ext = kwargs['out_format'] or orig_ext
try:
# Thử cắt nhanh không re-encode
return build_ffmpeg_cmd(file_path, out_ext,
['-ss', str(start), '-to', str(end), '-c', 'copy'], False)
except:
# Dùng GPU nếu hỗ trợ
gpu_params = ['-c:v', 'h264_nvenc'] if use_gpu else []
return build_ffmpeg_cmd(file_path, out_ext,
['-ss', str(start), '-to', str(end)] + gpu_params, use_gpu)
# Các chức năng khác có thể mở rộng tương tự...
raise gr.Error("Tính năng chưa được hỗ trợ")
# Giao diện Gradio
with gr.Blocks(title="Media Processor") as app:
gr.Markdown(f"# 🎬 Công cụ xử lý đa phương tiện\n**Tăng tốc GPU: {'✅ CUDA' if ACCEL_TYPE == 'nvidia' else '❌ Không hỗ trợ'}**")
with gr.Tab("Tải lên"):
inp_file = gr.File(type="filepath")
task = gr.Dropdown(["Chuyển định dạng", "Cắt đoạn"], value="Chuyển định dạng")
with gr.Group(visible=True) as fmt_group:
fmt_dropdown = gr.Dropdown(["mp4", "avi", "mov", "mp3", "wav"], value="mp4")
with gr.Group(visible=False) as clip_group:
start_t = gr.Number(label="Bắt đầu (giây)", value=0)
end_t = gr.Number(label="Kết thúc (giây)", value=10)
clip_fmt = gr.Dropdown(["mp4", "avi", "mov"], value="mp4")
gpu_check = gr.Checkbox(label="Sử dụng GPU", value=False, interactive=(ACCEL_TYPE != 'cpu'))
out_file = gr.File()
run_btn = gr.Button("Xử lý")
def toggle_params(task_sel):
return (
gr.update(visible=task_sel=="Chuyển định dạng"),
gr.update(visible=task_sel=="Cắt đoạn")
)
task.change(toggle_params, task, [fmt_group, clip_group])
run_btn.click(
process_file,
[inp_file, task, fmt_dropdown, start_t, end_t, clip_fmt, gpu_check],
out_file
)
if __name__ == "__main__":
cleanup_old_files()
app.launch(server_name="0.0.0.0", server_port=8080)
Khởi chạy ứng dụng:
conda activate media_proc
python media_handler.py
Sau khi khởi động thành công, truy cập cổng 8080 để sử dụng giao diện web xử lý đa phương tiện với hỗ trợ tăng tốc GPU NVIDIA.