Membuat Subtitle Otomatis dengan AI

Membuat Subtitle Otomatis dengan AI

Tujuan: Menghasilkan file subtitle (.srt) secara otomatis dari video apa pun dengan memanfaatkan model AI transkripsi (ChatGPT Plus, Claude Pro, atau Gemini Advanced) dan skrip Python yang dapat dijalankan di mesin lokal atau server CI/CD.


Pendahuluan

Video tanpa subtitle mengurangi aksesibilitas dan SEO. Dengan AI modern, proses transkripsi dan penyesuaian waktu dapat diotomatisasi dalam hitungan menit. Arsitektur solusi ini terdiri dari:

  1. Ekstraksi audio dari video menggunakan ffmpeg.
  2. Transkripsi audio ke teks via API AI (ChatGPT Plus, Claude Pro, atau Gemini Advanced).
  3. Pemrosesan teks menjadi format subtitle (.srt) dengan penyesuaian timestamp.
  4. Integrasi kembali ke video (opsional).

Diagram alur singkat:

Video → ffmpeg → audio.wav → AI API → transcript.txt → Python → subtitles.srt → (optional) ffmpeg → video_with_subs.mp4

Prasyarat & Persiapan

Kebutuhan Detail Link
Sistem Operasi Linux (Ubuntu 22.04+) atau macOS
Python Versi 3.9+ (disarankan 3.11)
ffmpeg Untuk manipulasi media sudo apt-get install ffmpeg
Akun API AI ChatGPT Plus, Claude Pro, atau Gemini Advanced https://tools.jartekindo.com/tool/chatgpt-plus/
https://tools.jartekindo.com/tool/claude-pro/
https://tools.jartekindo.com/tool/gemini-advanced/
Token API Simpan di variabel lingkungan OPENAI_API_KEY, ANTHROPIC_API_KEY, atau GEMINI_API_KEY
(Opsional) Notion AI untuk catatan proyek https://tools.jartekindo.com/tool/notion-ai/

Instalasi Dependensi Sistem

# Update paket
sudo apt-get update && sudo apt-get upgrade -y

# Install ffmpeg
sudo apt-get install -y ffmpeg

# Install Python 3.11 (jika belum ada)
sudo apt-get install -y python3.11 python3.11-venv python3-pip

Langkah Demi Langkah

Step 1 – Siapkan Lingkungan Virtual Python

# Buat folder proyek
mkdir subtitle-ai && cd subtitle-ai

# Buat virtual environment
python3.11 -m venv .venv
source .venv/bin/activate

# Upgrade pip
pip install --upgrade pip

Step 2 – Instalasi Library Python

pip install openai anthropic google-generativeai tqdm python-dotenv

Catatan: openai untuk ChatGPT Plus, anthropic untuk Claude Pro, dan google-generativeai untuk Gemini Advanced.

Step 3 – Ekstrak Audio dari Video

# Ganti input.mp4 dengan nama file video Anda
ffmpeg -i input.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 audio.wav

Step 4 – Transkripsi Audio dengan AI

Buat file .env di root proyek:

OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=...
GEMINI_API_KEY=...

4.1 Pilihan 1: ChatGPT Plus (OpenAI Whisper)

# transcribe_openai.py
import os, json, time
import openai
from dotenv import load_dotenv
from tqdm import tqdm

load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

def transcribe(file_path: str) -> str:
    with open(file_path, "rb") as audio:
        # Menggunakan endpoint Whisper (audio transcription)
        resp = openai.audio.transcriptions.create(
            model="whisper-1",
            file=audio,
            response_format="json"
        )
    return resp["text"]

if __name__ == "__main__":
    transcript = transcribe("audio.wav")
    with open("transcript.txt", "w", encoding="utf-8") as f:
        f.write(transcript)
    print("Transkripsi selesai, hasil disimpan di transcript.txt")

Jalankan:

python transcribe_openai.py

4.2 Pilihan 2: Claude Pro (Anthropic)

# transcribe_claude.py
import os, json, base64
import anthropic
from dotenv import load_dotenv

load_dotenv()
client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))

def transcribe(file_path: str) -> str:
    with open(file_path, "rb") as f:
        audio_b64 = base64.b64encode(f.read()).decode()
    # Claude tidak memiliki endpoint Whisper; gunakan model Claude untuk *summarize* teks yang sudah di‑transcribe oleh layanan lain.
    # Untuk contoh, kita pakai OpenAI Whisper dulu, lalu Claude memperbaiki punctuation.
    # (Implementasi lengkap memerlukan dua‑step; disederhanakan di sini.)
    raise NotImplementedError("Claude tidak menyediakan speech‑to‑text secara native.")

# Anda dapat menggabungkan OpenAI Whisper + Claude polishing bila diperlukan.

Catatan: Claude Pro tidak menyediakan layanan speech‑to‑text langsung; biasanya dipasangkan dengan Whisper terlebih dahulu. Tutorial ini tetap menyertakan contoh placeholder.

4.3 Pilihan 3: Gemini Advanced (Google)

# transcribe_gemini.py
import os, json, base64
import google.generativeai as genai
from dotenv import load_dotenv

load_dotenv()
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
model = genai.GenerativeModel('gemini-1.5-pro')

def transcribe(file_path: str) -> str:
    with open(file_path, "rb") as f:
        audio_bytes = f.read()
    # Gemini memiliki endpoint `generate_content` dengan mime_type "audio/wav"
    response = model.generate_content(
        [genai.upload_file(path=file_path, mime_type="audio/wav")],
        generation_config={"response_mime_type": "text/plain"}
    )
    return response.text

if __name__ == "__main__":
    transcript = transcribe("audio.wav")
    with open("transcript.txt", "w", encoding="utf-8") as f:
        f.write(transcript)
    print("Transkripsi selesai, hasil disimpan di transcript.txt")

Jalankan:

python transcribe_gemini.py

Step 5 – Mengubah Teks menjadi File SRT

# generate_srt.py
import re
from datetime import timedelta

def split_into_chunks(text: str, max_words: int = 12):
    words = text.split()
    for i in range(0, len(words), max_words):
        yield " ".join(words[i:i+max_words])

def format_timestamp(seconds: float) -> str:
    td = timedelta(seconds=seconds)
    hrs, remainder = divmod(td.seconds, 3600)
    mins, secs = divmod(remainder, 60)
    millis = int(td.microseconds / 1000)
    return f"{hrs:02}:{mins:02}:{secs:02},{millis:03}"

def generate_srt(transcript_path: str, srt_path: str, words_per_line=12, seconds_per_line=4):
    with open(transcript_path, "r", encoding="utf-8") as f:
        text = f.read().strip()

    chunks = list(split_into_chunks(text, max_words=words_per_line))
    with open(srt_path, "w", encoding="utf-8") as out:
        for idx, chunk in enumerate(chunks, start=1):
            start = idx * seconds_per_line - seconds_per_line
            end = idx * seconds_per_line
            out.write(f"{idx}\n")
            out.write(f"{format_timestamp(start)} --> {format_timestamp(end)}\n")
            out.write(f"{chunk}\n\n")

if __name__ == "__main__":
    generate_srt("transcript.txt", "subtitle.srt")
    print("File subtitle.srt berhasil dibuat.")

Jalankan:

python generate_srt.py

Catatan: Parameter words_per_line dan seconds_per_line dapat disesuaikan untuk meningkatkan akurasi timing.

Step 6 – (Opsional) Membungkus Subtitle ke Video

ffmpeg -i input.mp4 -vf "subtitles=subtitle.srt:force_style='FontName=Arial,FontSize=24,PrimaryColour=&HFFFFFF&'" -c:a copy output_with_subs.mp4

Tips Optimasi & Keamanan

Area Best Practice
API Key Simpan di variabel lingkungan, jangan hard‑code. Gunakan file .env dan tambahkan ke .gitignore.
Rate Limiting Implementasikan exponential backoff bila API mengembalikan 429.
Batch Processing Untuk video panjang, bagi audio menjadi segmen 5‑menit dan transkrip secara paralel (gunakan asyncio atau multiprocessing).
Caching Simpan hasil transkripsi (transcript.txt) untuk menghindari panggilan ulang selama debugging.
Kualitas Audio Pastikan audio mono 16 kHz; gunakan ffmpeg -ac 1 -ar 16000 untuk konversi.
Keamanan Data Jika video berisi data sensitif, gunakan endpoint AI yang berada di wilayah yang sesuai (mis. us-east-1).
CI/CD Integrasikan skrip ke pipeline GitHub Actions dengan secret OPENAI_API_KEY untuk otomatisasi subtitle pada repo video.

Troubleshooting Error Umum

Error Penyebab Solusi
openai.error.AuthenticationError API key tidak valid atau tidak terdeteksi Pastikan variabel OPENAI_API_KEY terisi, cek .env, jalankan source .venv/bin/activate kembali.
ffmpeg: Invalid argument Parameter ffmpeg salah (mis. nama file) Verifikasi nama file, jalankan ffmpeg -version untuk memastikan instalasi.
UnicodeDecodeError saat menulis transcript.txt Encoding tidak UTF‑8 Tambahkan encoding="utf-8" pada semua operasi file.
Rate limit exceeded Terlalu banyak request dalam waktu singkat Tambahkan time.sleep(2) antara panggilan atau gunakan tqdm untuk menampilkan progress dengan delay.
FileNotFoundError: audio.wav Ekstraksi audio gagal atau path salah Pastikan perintah ffmpeg selesai tanpa error dan file berada di direktori kerja.
AttributeError: 'NoneType' object has no attribute 'text' Respon API tidak mengandung field text (mis. error pada server) Tambahkan pengecekan if resp and "text" in resp: sebelum mengakses.

Kesimpulan

Dengan kombinasi ffmpeg, layanan AI (ChatGPT Plus, Claude Pro, atau Gemini Advanced), dan skrip Python singkat, Anda dapat menghasilkan subtitle otomatis yang akurat dalam hitungan menit. Proses ini dapat di‑scale ke ribuan video melalui pipeline CI/CD, sekaligus menjaga keamanan data melalui manajemen kunci API yang tepat.

Langkah selanjutnya:
- Integrasikan proses ke GitHub Actions untuk otomatisasi pada repositori konten video.
- Eksperimen dengan model AI lain (mis. Whisper‑large) untuk meningkatkan akurasi bahasa non‑Inggris.
- Tambahkan styling subtitle lanjutan via ffmpeg atau Subtitle Edit untuk produksi broadcast.

Selamat mencoba, dan semoga video Anda menjadi lebih inklusif serta SEO‑friendly!

🏷️ Topik Terkait: