Tutorial Indexing Video Lokal dengan Gemma 4 dan Vector Search
Taufiq M
Taufiq M

Dipublikasikan 22 Mei 2026

Tutorial Indexing Video Lokal dengan Gemma 4 dan Vector Search

Baru-baru ini, developer independen berhasil indexing setahun penuh video lokal hanya dengan MacBook 2021 dan model Gemma 4-31B. Artikel ini adalah breakdown praktis cara kerjanya dan bagaimana kamu bisa replikasi setup serupa untuk project pribadi atau internal tim.

Sumber inspirasi: Indexing a year of video locally on a 2021 MacBook oleh Simba Stack.

Persiapan Environment dan Hardware

Kamu tidak butuh server mahal. Minimum viable setup:

  • MacBook Pro M1/M2 atau PC dengan 32GB RAM
  • Storage SSD NVMe minimal 500GB untuk video dan index
  • Ollama terinstall untuk menjalankan Gemma 4 locally
  • Python 3.12+ dengan virtual environment

Install dependency utama:

pip install opencv-python-headless chromadb sentence-transformers ollama

Ekstraksi Frame dari Video

Proses indexing dimulai dengan mengubah video menjadi frame representatif. Gunakan OpenCV untuk ekstraksi setiap 5 detik:

import cv2, os

def extract_frames(video_path, out_dir, interval=5):
    cap = cv2.VideoCapture(video_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    count = 0
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret: break
        if int(count) % (int(fps) * interval) == 0:
            cv2.imwrite(f"{out_dir}/frame_{count}.jpg", frame)
        count += 1
    cap.release()

Untuk 1 tahun video, biasanya menghasilkan 10.000 - 50.000 frame tergantung durasi total.

Generate Embedding dengan Gemma 4 via Ollama

Gemma 4-31B support vision dan text. Kita gunakan untuk generate embedding visual dari setiap frame:

import ollama

def embed_image(path):
    res = ollama.embed(
        model="gemma4:31b",
        input=[{"type": "image", "source": path}]
    )
    return res.embeddings[0]

Embedding ini akan disimpan ke vector database untuk semantic search nanti.

Setup Vector Database dengan ChromaDB

ChromaDB adalah pilihan terbaik untuk local vector search karena pure Python dan zero-config:

import chromadb
client = chromadb.PersistentClient(path="./video_index")
collection = client.get_or_create_collection("video_frames")

def index_frame(frame_path, embedding, metadata):
    collection.add(
        ids=[metadata["id"]],
        embeddings=[embedding],
        metadatas=[metadata]
    )

Metadata wajib menyertakan nama file video dan timestamp frame untuk traceability.

Implementasi Semantic Search

Setelah index terbangun, search menjadi trivial. User bisa query dalam bahasa natural:

def search_videos(query, n_results=5):
    q_embed = ollama.embed(model="gemma4:31b", input=query).embeddings[0]
    return collection.query(
        query_embeddings=[q_embed],
        n_results=n_results
    )

Hasil query akan mengembalikan frame paling relevan beserta metadata video dan timestamp-nya.

Optimasi untuk Scale Besar

Jika kamu indexing lebih dari 100.000 frame, pertimbangkan:

  • Batch processing: Proses embedding dalam batch 32-64 frame untuk memaksimalkan throughput GPU
  • Dimensionality reduction: Gunakan PCA untuk menurunkan dimensi embedding dari 8192 ke 1024 jika storage terbatas
  • Hierarchical index: Group frame per video untuk filtering awal sebelum semantic search

Dengan optimasi ini, MacBook 2021 pun mampu handle indexing 1 tahun video dalam waktu semalam.

Sumber referensi: Simba Stack - Indexed a Year of Video Locally.