Storyboard (revisi 1): "Gue Bikin Bot Telegram Buat Invoice"
Sumber: raw/take_invoice.MP4 (2:51, 1080Γ1920 HEVC, selfie close-up, satu take dengan banyak ulangan). Aset: raw/diskusi_claude.MOV (5,2 dtk, rekaman layar monitor berisi diskusi dengan Claude, tanpa suara berarti) dan raw/telegram_invoice.PNG (screenshot bot Telegram: klien tersimpan, "Invoice DJ/2026/002 dibuat", PDF, tombol Tandai DP / Tandai Lunas / Kirim PDF lagi / Duplikat). Target: Reels 1080Γ1920, 30 fps, -14 LUFS, tanpa musik, durasi perkiraan Β±1:30 (opsi pangkas ke Β±1:10 ada di bawah). Pipeline: edit/EDITING_GUIDE.md (potong dari energi audio, caption dari transkrip hasil potongan, Remotion, safe zone).
Referensi gaya (@andreakyton, "AI editor guide", 1:04)
Yang bisa kuamati dari 2 frame yang berhasil kuputar (seek di pemutar TikTok tidak mau pindah, jadi sisanya tidak kulihat):
Talking head full-frame, dengan kartu putih besar di bagian atas yang berisi layar/grafik dan judul bertuliskan "STEP N + nama langkah".
Caption putih tebal, 1 kata per kemunculan, di bawah kartu, di atas dada.
Kartu berganti per langkah, sementara pembicara tetap di frame. Yang belum kuketahui (transisi, SFX, zoom, kecepatan potong). Kalau ada momen lain di video itu yang kamu suka, sebutkan detiknya.
Keputusan layout (perlu persetujuanmu)
Di footage-mu wajah memenuhi bagian atas frame (kepala yβ290β1100), jadi kartu gaya referensi akan menutupi wajah kalau ditaruh begitu saja. Solusi: saat kartu tampil, footage diperkecil Β±55% dan digeser turun, area kosong di atasnya diisi footage yang di-blur (gelap), lalu kartu ditaruh di atas. Preview geometri (zona merah = area UI TikTok/IG, kotak putih = posisi caption): edit/invoice/export/layout_preview.png.
Kartu di yβ285β560, lebar Β±700 (di dalam safe zone), wajah utuh di yβ720β1170, caption tepat di bawah dagu (yβ1210β1380).
Saat tidak ada kartu: footage full-frame, caption di bawah dagu (yβ1100β1300 mengikuti guide), tanpa pergeseran.
Perpindahan full β split memakai animasi zoom 0,25 dtk supaya terasa disengaja, bukan lompat.
Aturan visual
Elemen
Spek
Jump cut
Jeda > 0,32 dtk dibuang, batas potong dari energi audio. Zoom bergantian 1.00 β 1.06 per klip saat layout full.
Caption
Montserrat 900 putih, stroke hitam, 1β3 kata, kata aktif kuning #FFD43B. Posisi lihat layout di atas.
Kartu langkah
Glass card gelap dengan badge biru "#N" + judul langkah (gaya "STEP N" referensi). Muncul slide dari atas.
Kartu Telegram
Screenshot yang di-crop (lihat privasi), border putih, muncul di slot kartu.
Whoosh tiap kartu masuk, ding saat "it works". Tanpa musik.
Safe zone
Atas 280, bawah 1440, kanan 150, kiri 60. Dicek dengan still berkotak merah sebelum render.
Scene list
Waktu "sumber" dari transkrip. Waktu "out" perkiraan, final setelah EDL.
#
Sumber
Ucapan (ringkas)
Visual / teks layar
Catatan edit
1 Hook
0.6β5.9
"Jadi selain jadi programmer, gue punya dua kerjaan lain, yaitu jadi DJ dan jadi content creator."
Judul besar "GUE BIKIN BOT TELEGRAM BUAT INVOICE" di atas kepala (3 baris, font 76, kuning di "BOT TELEGRAM"), full layout
Dibuka langsung di suara.
2 Masalah
11.4β17.0
"Kesamaan di antara ketiganya adalah gue butuh invoice untuk nagih pembayaran ke klien."
Kartu langkah #1 MASALAH: ikon π§Ύ. Bubble "butuh invoice π§Ύ"
Take 7.3β10.3 dibuang (kata terputus).
38.9β46.5
"Cuman masalahnya, gue masih harus ngutak-atik manual untuk data-datanya."
Bubble "data manual π©"
56.5β61.8
"Gue selalu memisahkan persona programmer, content creator, dan DJ."
Kartu 3 chip: π» Programmer Β· π¬ Content creator Β· π§ DJ
Kalimat "Misalkan untuk persona programmer" (48.1β50.2) menggantung, dibuang.
65.0β73.98
"Atas nama gue selalu berubah-ubah. Ditambah rekeningnya beda, kliennya beda, jatuh temponya beda, segala itemnya beda semua."
Bubble "semua beda π€―" (di "beda semua").
Take pertama "atas nama" (62.6β64.3) dibuang, pakai take kedua.
74.9β80.4
"Setiap gue bikin invoice baru, gue harus masukin datanya manual. Gue males hal ini."
3 Solusi
84.8β89.1
"Karena gue resah dengan hal ini, gue memutuskan diskusi dengan Claude."
Kartu #2 SOLUSI: "ngobrol sama Claude" π€. Mulai di kata "Claude", b-roll diskusi_claude.MOV full-screen (lihat bagian B-roll).
"Cloud" di transkrip = Claude (dikonfirmasi). Awal yang tersendat (81.5β84.8) dibuang.
90.7β96.2
"Gue curhat gimana pain point-nya dan minta solusi."
B-roll Claude lanjut sampai Β±"minta solusi", lalu kembali ke wajah.
Dengan adanya b-roll bagian ini jadi dipertahankan (dibuang hanya di opsi pendek).
98.3β108.1
"Karena gue kesel, gue mikir, apa gue bikin bot Telegram aja ya buat mengakomodasi keresahan gue."
Muncul kartu Telegram (crop "Invoice DJ/2026/002 dibuat" + PDF) tepat di kata "Telegram". Layout beralih ke split.
Anchor Telegram.
4 Alasan
108.8β113.4
"Kadang waktu klien minta invoice, gue lagi di luar, kejutan."
Opsi pangkas.
114.4β121.7
"Contohnya semalam, gue diminta bikin invoice jam 11 atau 12 malam, sedangkan gue lagi perform di club."
Bubble "jam 11 malam, lagi di club π§"
5 Demo
122.7β126.1
"Akhirnya udah jadi dan udah bisa dipakai."
Kartu #3 CARA PAKAI
127.2β137.98
"Gue tinggal ngechat aja mau gue apa: invoice untuk persona yang mana, DJ kek, content creator kek, dan untuk klien siapa."
Kartu Telegram: potongan percakapan (klien baru tersimpan, invoice dibuat).
138.8β145.3
"Peruntukannya untuk klien siapa, deskripsinya gimana, rekening yang mana, itu udah ke-set semua."
Kartu Telegram: tombol Tandai DP / Tandai Lunas / Kirim PDF lagi / Duplikat (crop kedua).
6 Hasil
148.5β159.6
"Baru semalam gue pake dan it works. Ketika gue lagi di luar, gak pegang laptop, gue bisa bikin invoice sendiri. Mempermudah banget."
Bubble "it works β " + ding. Kembali full layout.
7 CTA
164.8β171.1
"Gimana, kalian ada yang penasaran gak cara bikinnya dan tech stack apa aja yang gue pake untuk teknologi ini?"
Bubble "Mau tau cara & tech stack-nya? Komen π" (CTA dari ucapanmu sendiri).
Take pertama (160.7β164) dibuang, pakai take kedua yang lebih utuh.
Perkiraan: dengan semua baris di atas Β±1:35, setelah jeda dibuang Β±1:25β1:30. Opsi lebih pendek (Β±1:10): buang "curhat ke Claude" (90.7β96.2, b-roll Claude dipersingkat jadi Β±2 dtk), "kadang waktu klien minta invoice" (108.8β113.4), dan kalimat "gue males hal ini" (79.2β80.4). Contoh yang dibuang dari rencana: pengulangan satu per satu "di programmerβ¦ di DJβ¦ di content creatorβ¦" (17.9β38.1) karena poinnya sudah tercakup di kalimat "kesamaan ketiganya". Kalau menurutmu justru bagian itu lucu, bilang.
B-roll diskusi_claude.MOV
Isi: rekaman ponsel ke layar monitor (Xiaomi) yang menampilkan percakapan Claude Code (Opus 5.5) dengan teks panjang bergerak cepat. Ada bayangan ganda (ghosting) dari refresh monitor, tepi atas 18% kosong (dinding putih), dan teksnya kecil sehingga tidak terbaca. Karena itu dipakai sebagai tekstur "lagi ngobrol panjang sama Claude", bukan untuk dibaca.
Dipakai Β±3,5 dtk dari 5,2 dtk, tanpa suaranya (hanya Β±-45 dB ambient), suaramu tetap jalan.
Crop hanya area layar (buang dinding putih di atas dan bezel Xiaomi di bawah), diisi penuh ke layar dengan sedikit gelap + zoom pelan 1.00β1.06. Full-screen, bukan kartu, supaya teks tidak jadi terlalu kecil. Wajahmu hilang selama b-roll, dan caption tetap tampil di zona caption.
Label kecil "Claude π€" di kartu langkah supaya penonton langsung paham itu layar apa.
Sebagian nama klien dan nama proyek terlihat samar di layar (mis. nama pusat PAUD). Karena blur dan ghosting nyaris tidak terbaca, tapi kalau mau aman aku tambahkan blur lebih kuat.
Penanganan data di screenshot (butuh konfirmasi)
Screenshot memuat nama klien Zeeto Coffee, nomor invoice DJ/2026/002, dan alamat lengkap klien (Jl. Suryowijayan, Gedongkiwo, Yogyakarta 55142) di bagian atas. Rencanaku:
Crop hanya bagian "Klien β¦ tersimpan", "Invoice β¦ dibuat", PDF, dan tombol. Alamat dan jam status bar tidak ditampilkan.
Nama klien dan nomor invoice tetap terlihat. Mau disamarkan (blur/ganti "Klien A")? Pilihan ada di bawah.
Audio
Loudnorm dua pass β -14 LUFS, fade 10 ms di tiap sambungan, whoosh dan ding sintetis (bebas hak cipta). Tanpa musik.
Caption IG (draft, belum dihumanize)
Gue bikin bot Telegram buat invoice π§Ύ biar bisa bikin invoice dari mana aja, bahkan pas lagi perform di club π§ Mau tau cara bikin dan tech stack-nya? Komen di bawah π #programmer #freelancer #contentcreator #dj #invoice #telegrambot #ai
Perlu dicek kreator
Dikonfirmasi: "cloud" = Claude, "text-text" = tech stack. Masih belum jelas: kata sebelum "segala matemnya" (item-itemnya? rate-nya?).
Judul: "Gue Bikin Bot Telegram Buat Invoice" (dari kamu). Hook 0β3 dtk memakai judul ini; usulan teks "3 PEKERJAAN, 1 MASALAH" kubuang.
Hasil v1 (export/gue_bikin_bot_telegram_buat_invoice_v1.mp4)
Durasi 1:38, 1080Γ1920, 30 fps, -13,7 LUFS, peak -1,2 dB. Tidak ada jeda kosong > 0,35 dtk, tidak ada frame hitam atau beku.
Semua bagian storyboard masuk (tanpa opsi pangkas). Layout split dipakai di hook, kartu langkah, chip persona, dan kartu Telegram.
Perubahan dari storyboard: b-roll Claude diblur lebih kuat (sigma 2,6) dan sepanjang 4,6 dtk; bubble CTA dipersingkat jadi "Mau tau tech stack-nya? π" supaya satu baris dan tidak melewati batas bawah safe zone.
Pipeline: invoice/build/ (make_edl.py, build_base.py, loudnorm.sh, captions.py, render.sh) dan invoice/remotion/.
B-roll "lagi perform di club": sedang_di_eskala.MOV full-screen (suaranya dibuang) + chat klien cient_minta_invoice.jpg ("hallo kak, maaf aku lupa minta invoice nya") sebagai kartu di atas. Mulai di kata "sedangkan", selesai di akhir bagian itu.
Caption "buatnya" diperbaiki jadi "bot-nya".
Kalimat "dan untuk klien yang siapa" dibuang dari potongan (sumber 135.80β138.75).
Durasi 1:36, -13,7 LUFS, tanpa jeda kosong, frame hitam, atau frame beku.
Panduan ini untuk agent (Claude Code dll.) yang mengedit video talking head vertikal jadi Reels/TikTok dengan gaya: jump cut rapat, caption kata-per-kata, kartu glass di atas, bubble biru, b-roll screenshot, tanpa musik. Referensi gaya: video @brandnat ("Comment EDIT") + guide aicreatorlibrary.com/blog/ai-video-editing-prompts. Contoh hasil: export/sidehustle_reels_v2.mp4. Kode contoh: folder build/ dan remotion/src/.
Bahasa kerja dengan kreator: Indonesia santai (gue/lu). Kreator: @damsatriaa (Satria), Android dev + IT content creator.
Storyboard dulu (storyboard.md), baru edit. Kreator meminta ini secara eksplisit.
Potong dulu, dekorasi kemudian. Setiap cut menggeser timestamp, jadi caption/overlay baru dibuat setelah potongan final.
Transkrip ulang hasil potongan untuk timing caption (jangan pakai timestamp transkrip raw).
Jangan menimpa file lama. Keluaran diberi versi: *_v2.mp4, *_v3.mp4.
Raw footage tidak pernah diubah.
Verifikasi dengan still + contact sheet + cek silence/loudness sebelum bilang "selesai". Agent tidak bisa menilai sinkron bibir; minta kreator menonton sekali penuh.
- Setup tool (gotcha yang sudah kejadian)
Masalah
Solusi
faster_whisper tidak ada di python Homebrew
Buat venv di scratchpad: python3 -m venv $S/venv && $S/venv/bin/pip install faster-whisper
Jangan kirim path. Ekstrak wav 16 kHz mono dengan ffmpeg, baca pakai wave+numpy, kirim array float32 ke model.transcribe(array)
Model sudah ter-cache
~/.cache/huggingface/hub punya faster-whisper-small dan base. Pakai small (CPU int8 di M1 cukup)
npx remotion ... gagal lewat hook RTK (output error npm)
Pakai binary langsung dengan proxy: rtk proxy ./node_modules/.bin/remotion render ...
ffmpeg loudnorm error Invalid chars 'inear=true'
Pisahkan param: ...:offset=1.71:linear=true (jangan ditempel ke angka offset)
Remotion font emoji tidak tampil
fontFamily harus "Montserrat", "Apple Color Emoji", "Noto Color Emoji", sans-serif
tsc komplain properti baru
Tambahkan ke type ITEMS (contoh: short?: string)
Render panjang
Jalankan di background, jangan polling; tunggu notifikasi selesai
Versi yang dipakai: remotion@4.0.400, @remotion/cli, @remotion/google-fonts, react 18.3.1, typescript 5.6.3. Scratchpad dipakai untuk venv, wav sementara, dan still preview. Hasil akhir ke edit/export/.
- Struktur folder
raw/ footage + aset screenshot (jangan diubah)
reference/ video referensi gaya
edit/
storyboard.md storyboard + catatan revisi
EDITING_GUIDE.md file ini
build/
make_edl.py daftar segmen terpilih -> batas potongan (EDL) -> edl.json
build_base.py ffmpeg trim+concat -> base.mov
captions.py transkrip hasil potongan -> kata caption di edl.json
fix.json koreksi kata (words + phrases)
words_raw.json transkrip raw (per kata)
words_base.json transkrip hasil potongan (cache)
remotion/
public/ base.mp4, ding.wav, whoosh.wav, aset b-roll (jpg)
src/Main.tsx semua overlay (caption, kartu, bubble, b-roll, ringkasan)
src/edl.json salinan edl.json dari build/ (WAJIB disalin ulang tiap ada perubahan)
export/ hasil render + storyboard
- Pipeline langkah demi langkah
3.1 Transkrip raw
ffmpeg -i raw.MP4 -vn -ac 1 -ar 16000 a.wav
faster-whisper small, language="id", word_timestamps=True. Simpan per kata ke words_raw.json + teks per segmen (untuk dibaca manusia).
Hasil raw biasanya salah dengar nama/istilah dan memuat banyak take ulang. Baca seluruh transkrip dan pilih take terbaik per kalimat.
3.2 Pilih segmen (SEGS)
Di make_edl.py, tulis list (id_bagian, src_mulai, src_selesai[, True]) untuk take terbaik. Aturan editorial:
Buang blooper, kalimat tidak selesai, take pertama kalau ada take kedua yang lebih bersih.
Buang kalimat redundan ("effortnya gak sebandingβ¦") bila poin sudah jelas.
Boleh menukar urutan kalimat bila punchline lebih kuat di akhir (contoh: undervalue β "skill nego gue yang kurang").
Satu ide = satu id bagian (hook, n1β¦n8, cta). Id ini dipakai untuk kartu, b-roll, dan skor.
Flag True di elemen ke-4 = paksa ekor kata pelan tidak terpotong (lihat 3.3).
3.3 Hitung batas potongan dari energi audio (PENTING)
Timestamp kata dari Whisper meleset hingga Β±0,5 dtk. Jangan potong berdasarkan itu. Yang benar:
Hitung RMS dB per 10 ms dari wav 16 kHz.
Region bersuara = frame dengan dB > -36 (noise ruangan Β±-45 s/d -55). Gabungkan region yang jaraknya β€ 0,32 dtk (GAP). Abaikan region < 0,08 dtk.
Perpanjang akhir region selama 120 ms ke depan masih > -45 dB (menangkap ekor kata: "sepuluh", "developer"), dibatasi sampai awal region berikutnya dikurangi 0,05 dtk, atau 0,7 dtk lewat batas segmen untuk region terakhir.
Padding: awal -0,04, akhir +0,10 dtk.
Klip pertama video: geser awal +0,03 agar langsung terbuka di suara (tanpa udara kosong).
Untuk kata dengan ekor sangat pelan (di sini: "hustle", "kayaknya", "aja") pakai flag True agar akhir klip minimal b - 0,1.
Fade audio 10 ms di tiap sambungan (afade in/out) supaya tidak "klik".
Hasil ke edl.json: clips (src_s, src_e, out_s, dur, sec), words, total.
3.4 Render potongan dasar
build_base.py: satu filter_complex (trim+setpts, atrim+asetpts, fps=30, concat) -> base.mov (libx264 crf 16 + pcm). Pakai -filter_complex_script karena puluhan klip.
Transkrip ulang base.mov (initial_prompt berisi istilah: side hustle, Play Store, GMV, SaaS, dst.). Cache ke words_base.json.
Koreksi lewat fix.json: words (ganti per kata) dan phrases (ganti urutan kata; lebih aman daripada ganti kata tunggal yang ambigu, mis. "kedua"/"it"/"Content").
Skor 4x10/4 % -> 4/10 (regex menangani variasi). Token -gila digabung ke kata sebelumnya.
Awal kata di-snap ke suara (geser sampai dB > -40).
Bagian (sec) ditentukan dari titik tengah kata, bukan awal (kata di batas klip sering salah masuk bagian).
Tulis ke edl.json -> words, lalu cp build/edl.json remotion/src/edl.json.
Selalu baca hasil teks caption penuh dan cek ke kreator kata yang kurang yakin.
3.7 Overlay di Remotion (Main.tsx)
Semua di atas OffthreadVideo(base.mp4). Komponen:
Komponen
Spek
Footage
Zoom bergantian per klip 1.00 β 1.09 (gaya jump cut), origin 50% 34%. Punch-in 1.20 (0,2 dtk, ease out cubic) saat kata skor "x/10".
Captions
Montserrat 900, 70px, putih, stroke hitam 10px (paintOrder: stroke fill), 1β3 kata (maks Β±18 karakter), pecah di jeda > 0,3 dtk atau tanda baca. Kata yang sedang diucapkan kuning #FFD43B; skor berwarna sesuai nilai. Pop-in scale 0.86β1 dalam 80 ms.
HookTitle
0β2,9 dtk, judul besar kuning/putih 84px miring -2Β°, subjudul di kartu glass.
ItemCard
Kartu glass (rgba(28,28,30,.72), blur 24, radius 34): badge biru #N, emoji + judul, 10 kotak skor yang terisi animasi saat skor diucapkan, angka besar berwarna, titik progres 1β8. Slide masuk dari atas, keluar di akhir bagian.
Bubble
Bubble biru iMessage #0A84FF, 42px, miring -2Β°, spring pop. Untuk kalimat kunci (β€ 6 kata + emoji). Tampil 2,2 dtk dan dipotong di akhir bagian.
BRoll
Mode kartu: screenshot dengan border putih, bayangan, footage diredupkan 38%. Mode full: layar penuh + zoom pelan 1.0β1.08.
Summary
Kartu ranking akhir (semua item + bar skor) pada CTA, diikuti bubble CTA.
SFX
whoosh.wav tiap kartu/b-roll masuk, ding.wav tiap skor. Dibuat dengan ffmpeg (sine, anoisesrc), bebas hak cipta.
Palet skor: #ff4d4d (β€4) β #ff7a3d β #ffb02e β #ffd43b β #b8e04a β #7ed957 β #3ddc84 β #22e07a (10). Posisi bubble/b-roll ditentukan dari kata jangkar (wordAt(sec, "kata")), jadi ikut bergeser otomatis bila caption berubah.
3.8 B-roll dari aset kreator
Aset ada di raw/ (screenshot PNG). Lihat dulu semuanya (hstack kecil), tentukan sorotan, lalu crop ke bagian penting dengan ffmpeg (hapus status bar/nav bar, area pribadi) ke remotion/public/*.jpg.
Satu aset = satu kalimat jangkar. Aset layar penuh (foto aktivitas) boleh full; screenshot UI pakai mode kartu.
Jangan tampilkan data sensitif (saldo, email, nomor) tanpa konfirmasi kreator.
- Safe zone Reels/TikTok (WAJIB)
Kreator menegur: elemen tertimpa UI platform. Layout 1080Γ1920, semua overlay harus berada di area ini:
Sisi
Batas
Alasan
Atas
tidak ada konten di y < 280
status bar, search bar TikTok ("Find related content"), tombol back/+
Bawah
tidak ada konten di y > 1440
username, deskripsi, tombol insight/boost
Kanan
tidak ada konten di x > 930 (margin 150)
tombol like/komentar/share/save
Kiri
margin 60
aman dari tepi
Konstanta di kode:
const SAFE = { left: 60, right: 150, top: 280, capTop: 1100, bubbleTop: 1325 };
const safeX = { left: SAFE.left, right: SAFE.right, width: "auto" }; // pakai untuk AbsoluteFill overlay
Tata letak vertikal (dari atas): kartu/judul/ringkasan mulai y=280 β wajah (Β±600β1000) β caption y=1100β1300 β bubble y=1325 (maks bawah Β±1430). B-roll kartu di y=540β1100 (tinggi maks 560, lebar maks 840) supaya tidak menimpa kartu atas maupun caption.
Cara cek: render beberapa still (remotion still ... --frame=N --scale=0.5), tempel kotak merah semi-transparan di zona terlarang dengan ffmpeg drawbox (di skala 0.5: atas h=140, bawah y=720,h=240, kanan x=465,w=75), pastikan semua teks di luar merah. Lakukan sebelum render penuh.
- Template storyboard (storyboard.md)
Judul, sumber (durasi/resolusi/codec), target durasi, referensi gaya + guide.
Tabel scene list: # | waktu out | ucapan ringkas | visual/teks layar | catatan edit (catat take yang dibuang dan alasannya).
Audio: loudness target, fade sambungan, SFX, musik (default: tanpa musik; kreator tambah dari library IG saat upload).
Caption IG + hashtag (draft).
Perlu dicek kreator: kata hasil tebakan transkrip.
Bagian Revisi vN: tiap feedback kreator -> perbaikan yang dilakukan.
- QA sebelum menyerahkan (dari guide, "Change nothing")
ffprobe: 1080Γ1920, 30 fps, durasi.
ebur128: Β±-14 LUFS, peak β€ -1 dB.
silencedetect=noise=-40dB:d=0.35 pada hasil akhir: tidak boleh ada jeda panjang.
blackdetect dan freezedetect.
Contact sheet (fps=1/3,scale=200:-1,tile=9x4): caption tidak menutup mulut/mata, tidak ada elemen terpotong, ejaan benar, bubble tidak menumpuk.
Safe zone (bagian 4).
Akui keterbatasan: agent hanya melihat still, jadi sinkron bibir dan timing SFX harus ditonton kreator.
- Pelajaran dari feedback kreator (jangan ulangi)
Feedback
Akar masalah
Pencegahan
Intro kelamaan, tidak langsung audio
Awal klip dari timestamp Whisper, ada udara kosong
Batas dari energi audio; klip pertama mulai di suara
Ada audio kosong sebelum detik 6 / 26
Jeda antar take tidak terbuang
GAP 0,32 dtk, cek silencedetect di hasil akhir
"sepuluh" pada 4/10 belum selesai
Akhir klip ikut Whisper (terlalu awal)
Perpanjang ekor kata selama masih bersuara; cek ucapan angka skor secara khusus
"freelance developer" terpotong
Sama (ekor kata pelan)
Flag True / perpanjangan ekor
Aset baru belum masuk
β
Selalu cek raw/ untuk aset baru, lihat semuanya, tempatkan ke kalimat jangkar
Safe box kurang ketat
Layout tidak memperhitungkan UI platform
Bagian 4, cek dengan overlay merah
- Prompt siap pakai untuk agent
Edit video raw/<file> jadi Reels 9:16 mengikuti edit/EDITING_GUIDE.md. Buat storyboard dulu (edit/storyboard.md) dan tunggu saya setuju bila ada keputusan editorial besar. Pakai gaya yang sama dengan export/sidehustle_reels_v2.mp4: jump cut, caption kata-per-kata, kartu glass, bubble biru, b-roll dari aset di raw/, -14 LUFS, tanpa musik. Patuhi safe zone (bagian 4). Jangan render versi final sebelum still dicek dengan overlay safe zone. Simpan hasil sebagai export/<nama>_vN.mp4, jangan timpa versi lama.
Revisi: . Perbaiki lewat batas potongan berbasis energi audio (bagian 3.3), jangan menebak dari timestamp Whisper. Tambahkan catatan ke bagian "Revisi vN" di storyboard.
- Menggunakan ulang untuk video baru
Salin build/ dan remotion/ ke folder proyek baru (atau gunakan ulang yang ada).
Ganti RAW di build_base.py, daftar SEGS di make_edl.py, fix.json, dan initial_prompt di captions.py.
Ganti ITEMS, BUBBLES, BROLL, judul HookTitle, dan teks CTA di Main.tsx. Kartu bernomor/skor hanya cocok untuk format ranking; untuk format lain pakai kartu tanpa skor (hapus scoreTime/bar).
Jalankan: make_edl.py β build_base.py β loudnorm 2-pass β captions.py β salin edl.json ke remotion/src β still + cek safe zone β render.
Panduan Editing Reels: Talking Head + Jump Cut + Overlay (Remotion + ffmpeg) Panduan ini untuk agent (Claude Code dll.) yang mengedit video talking head vertikal jadi Reels/TikTok dengan gaya: jump cut rapat, caption kata-per-kata, kartu glass di atas, bubble biru, b-roll screenshot, tanpa musik. Referensi gaya: video @brandnat ("Comment EDIT") + guide aicreatorlibrary.com/blog/ai-video-editing-prompts. Contoh hasil: export/sidehustle_reels_v2.mp4. Kode contoh: folder build/ dan remotion/src/.
Bahasa kerja dengan kreator: Indonesia santai (gue/lu). Kreator: @damsatriaa (Satria), Android dev + IT content creator.
Aturan emas (urutan kerja) Inspect raw: ffprobe (durasi, resolusi, fps), lihat contact sheet frame, transkrip. Storyboard dulu (storyboard.md), baru edit. Kreator meminta ini secara eksplisit. Potong dulu, dekorasi kemudian. Setiap cut menggeser timestamp, jadi caption/overlay baru dibuat setelah potongan final. Transkrip ulang hasil potongan untuk timing caption (jangan pakai timestamp transkrip raw). Jangan menimpa file lama. Keluaran diberi versi: *_v2.mp4, *_v3.mp4. Raw footage tidak pernah diubah. Verifikasi dengan still + contact sheet + cek silence/loudness sebelum bilang "selesai". Agent tidak bisa menilai sinkron bibir; minta kreator menonton sekali penuh.
Setup tool (gotcha yang sudah kejadian) Masalah Solusi faster_whisper tidak ada di python Homebrew Buat venv di scratchpad: python3 -m venv $S/venv && $S/venv/bin/pip install faster-whisper faster-whisper error open() got an unexpected keyword argument 'metadata_errors' (PyAV baru) Jangan kirim path. Ekstrak wav 16 kHz mono dengan ffmpeg, baca pakai wave+numpy, kirim array float32 ke model.transcribe(array) Model sudah ter-cache ~/.cache/huggingface/hub punya faster-whisper-small dan base. Pakai small (CPU int8 di M1 cukup) npx remotion ... gagal lewat hook RTK (output error npm) Pakai binary langsung dengan proxy: rtk proxy ./node_modules/.bin/remotion render ... ffmpeg loudnorm error Invalid chars 'inear=true' Pisahkan param: ...:offset=1.71:linear=true (jangan ditempel ke angka offset) Remotion font emoji tidak tampil fontFamily harus "Montserrat", "Apple Color Emoji", "Noto Color Emoji", sans-serif tsc komplain properti baru Tambahkan ke type ITEMS (contoh: short?: string) Render panjang Jalankan di background, jangan polling; tunggu notifikasi selesai Versi yang dipakai: remotion@4.0.400, @remotion/cli, @remotion/google-fonts, react 18.3.1, typescript 5.6.3. Scratchpad dipakai untuk venv, wav sementara, dan still preview. Hasil akhir ke edit/export/.
Struktur folder raw/ footage + aset screenshot (jangan diubah) reference/ video referensi gaya edit/ storyboard.md storyboard + catatan revisi EDITING_GUIDE.md file ini build/ make_edl.py daftar segmen terpilih -> batas potongan (EDL) -> edl.json build_base.py ffmpeg trim+concat -> base.mov captions.py transkrip hasil potongan -> kata caption di edl.json fix.json koreksi kata (words + phrases) words_raw.json transkrip raw (per kata) words_base.json transkrip hasil potongan (cache) remotion/ public/ base.mp4, ding.wav, whoosh.wav, aset b-roll (jpg) src/Main.tsx semua overlay (caption, kartu, bubble, b-roll, ringkasan) src/edl.json salinan edl.json dari build/ (WAJIB disalin ulang tiap ada perubahan) export/ hasil render + storyboard
Pipeline langkah demi langkah 3.1 Transkrip raw ffmpeg -i raw.MP4 -vn -ac 1 -ar 16000 a.wav faster-whisper small, language="id", word_timestamps=True. Simpan per kata ke words_raw.json + teks per segmen (untuk dibaca manusia). Hasil raw biasanya salah dengar nama/istilah dan memuat banyak take ulang. Baca seluruh transkrip dan pilih take terbaik per kalimat. 3.2 Pilih segmen (SEGS) Di make_edl.py, tulis list (id_bagian, src_mulai, src_selesai[, True]) untuk take terbaik. Aturan editorial:
Buang blooper, kalimat tidak selesai, take pertama kalau ada take kedua yang lebih bersih. Buang kalimat redundan ("effortnya gak sebandingβ¦") bila poin sudah jelas. Boleh menukar urutan kalimat bila punchline lebih kuat di akhir (contoh: undervalue β "skill nego gue yang kurang"). Satu ide = satu id bagian (hook, n1β¦n8, cta). Id ini dipakai untuk kartu, b-roll, dan skor. Flag True di elemen ke-4 = paksa ekor kata pelan tidak terpotong (lihat 3.3). 3.3 Hitung batas potongan dari energi audio (PENTING) Timestamp kata dari Whisper meleset hingga Β±0,5 dtk. Jangan potong berdasarkan itu. Yang benar:
Hitung RMS dB per 10 ms dari wav 16 kHz. Region bersuara = frame dengan dB > -36 (noise ruangan Β±-45 s/d -55). Gabungkan region yang jaraknya β€ 0,32 dtk (GAP). Abaikan region < 0,08 dtk. Perpanjang akhir region selama 120 ms ke depan masih > -45 dB (menangkap ekor kata: "sepuluh", "developer"), dibatasi sampai awal region berikutnya dikurangi 0,05 dtk, atau 0,7 dtk lewat batas segmen untuk region terakhir. Padding: awal -0,04, akhir +0,10 dtk. Klip pertama video: geser awal +0,03 agar langsung terbuka di suara (tanpa udara kosong). Untuk kata dengan ekor sangat pelan (di sini: "hustle", "kayaknya", "aja") pakai flag True agar akhir klip minimal b - 0,1. Fade audio 10 ms di tiap sambungan (afade in/out) supaya tidak "klik". Hasil ke edl.json: clips (src_s, src_e, out_s, dur, sec), words, total.
3.4 Render potongan dasar build_base.py: satu filter_complex (trim+setpts, atrim+asetpts, fps=30, concat) -> base.mov (libx264 crf 16 + pcm). Pakai -filter_complex_script karena puluhan klip.
Transkrip ulang base.mov (initial_prompt berisi istilah: side hustle, Play Store, GMV, SaaS, dst.). Cache ke words_base.json. Koreksi lewat fix.json: words (ganti per kata) dan phrases (ganti urutan kata; lebih aman daripada ganti kata tunggal yang ambigu, mis. "kedua"/"it"/"Content"). Skor 4x10/4 % -> 4/10 (regex menangani variasi). Token -gila digabung ke kata sebelumnya. Awal kata di-snap ke suara (geser sampai dB > -40). Bagian (sec) ditentukan dari titik tengah kata, bukan awal (kata di batas klip sering salah masuk bagian). Tulis ke edl.json -> words, lalu cp build/edl.json remotion/src/edl.json. Selalu baca hasil teks caption penuh dan cek ke kreator kata yang kurang yakin.
3.7 Overlay di Remotion (Main.tsx) Semua di atas OffthreadVideo(base.mp4). Komponen:
Komponen Spek Footage Zoom bergantian per klip 1.00 β 1.09 (gaya jump cut), origin 50% 34%. Punch-in 1.20 (0,2 dtk, ease out cubic) saat kata skor "x/10". Captions Montserrat 900, 70px, putih, stroke hitam 10px (paintOrder: stroke fill), 1β3 kata (maks Β±18 karakter), pecah di jeda > 0,3 dtk atau tanda baca. Kata yang sedang diucapkan kuning #FFD43B; skor berwarna sesuai nilai. Pop-in scale 0.86β1 dalam 80 ms. HookTitle 0β2,9 dtk, judul besar kuning/putih 84px miring -2Β°, subjudul di kartu glass. ItemCard Kartu glass (rgba(28,28,30,.72), blur 24, radius 34): badge biru #N, emoji + judul, 10 kotak skor yang terisi animasi saat skor diucapkan, angka besar berwarna, titik progres 1β8. Slide masuk dari atas, keluar di akhir bagian. Bubble Bubble biru iMessage #0A84FF, 42px, miring -2Β°, spring pop. Untuk kalimat kunci (β€ 6 kata + emoji). Tampil 2,2 dtk dan dipotong di akhir bagian. BRoll Mode kartu: screenshot dengan border putih, bayangan, footage diredupkan 38%. Mode full: layar penuh + zoom pelan 1.0β1.08. Summary Kartu ranking akhir (semua item + bar skor) pada CTA, diikuti bubble CTA. SFX whoosh.wav tiap kartu/b-roll masuk, ding.wav tiap skor. Dibuat dengan ffmpeg (sine, anoisesrc), bebas hak cipta. Palet skor: #ff4d4d (β€4) β #ff7a3d β #ffb02e β #ffd43b β #b8e04a β #7ed957 β #3ddc84 β #22e07a (10). Posisi bubble/b-roll ditentukan dari kata jangkar (wordAt(sec, "kata")), jadi ikut bergeser otomatis bila caption berubah.
3.8 B-roll dari aset kreator Aset ada di raw/ (screenshot PNG). Lihat dulu semuanya (hstack kecil), tentukan sorotan, lalu crop ke bagian penting dengan ffmpeg (hapus status bar/nav bar, area pribadi) ke remotion/public/*.jpg. Satu aset = satu kalimat jangkar. Aset layar penuh (foto aktivitas) boleh full; screenshot UI pakai mode kartu. Jangan tampilkan data sensitif (saldo, email, nomor) tanpa konfirmasi kreator. 4. Safe zone Reels/TikTok (WAJIB) Kreator menegur: elemen tertimpa UI platform. Layout 1080Γ1920, semua overlay harus berada di area ini:
Sisi Batas Alasan Atas tidak ada konten di y < 280 status bar, search bar TikTok ("Find related content"), tombol back/+ Bawah tidak ada konten di y > 1440 username, deskripsi, tombol insight/boost Kanan tidak ada konten di x > 930 (margin 150) tombol like/komentar/share/save Kiri margin 60 aman dari tepi Konstanta di kode:
const SAFE = { left: 60, right: 150, top: 280, capTop: 1100, bubbleTop: 1325 }; const safeX = { left: SAFE.left, right: SAFE.right, width: "auto" }; // pakai untuk AbsoluteFill overlay Tata letak vertikal (dari atas): kartu/judul/ringkasan mulai y=280 β wajah (Β±600β1000) β caption y=1100β1300 β bubble y=1325 (maks bawah Β±1430). B-roll kartu di y=540β1100 (tinggi maks 560, lebar maks 840) supaya tidak menimpa kartu atas maupun caption.
Cara cek: render beberapa still (remotion still ... --frame=N --scale=0.5), tempel kotak merah semi-transparan di zona terlarang dengan ffmpeg drawbox (di skala 0.5: atas h=140, bawah y=720,h=240, kanan x=465,w=75), pastikan semua teks di luar merah. Lakukan sebelum render penuh.
Template storyboard (storyboard.md) Judul, sumber (durasi/resolusi/codec), target durasi, referensi gaya + guide. Tabel aturan visual (jump cut, zoom, caption, kartu, skor, progres). Tabel scene list: # | waktu out | ucapan ringkas | visual/teks layar | catatan edit (catat take yang dibuang dan alasannya). Audio: loudness target, fade sambungan, SFX, musik (default: tanpa musik; kreator tambah dari library IG saat upload). Caption IG + hashtag (draft). Perlu dicek kreator: kata hasil tebakan transkrip. Bagian Revisi vN: tiap feedback kreator -> perbaikan yang dilakukan.
QA sebelum menyerahkan (dari guide, "Change nothing") ffprobe: 1080Γ1920, 30 fps, durasi. ebur128: Β±-14 LUFS, peak β€ -1 dB. silencedetect=noise=-40dB:d=0.35 pada hasil akhir: tidak boleh ada jeda panjang. blackdetect dan freezedetect. Contact sheet (fps=1/3,scale=200:-1,tile=9x4): caption tidak menutup mulut/mata, tidak ada elemen terpotong, ejaan benar, bubble tidak menumpuk. Safe zone (bagian 4). Akui keterbatasan: agent hanya melihat still, jadi sinkron bibir dan timing SFX harus ditonton kreator.
Pelajaran dari feedback kreator (jangan ulangi) Feedback Akar masalah Pencegahan Intro kelamaan, tidak langsung audio Awal klip dari timestamp Whisper, ada udara kosong Batas dari energi audio; klip pertama mulai di suara Ada audio kosong sebelum detik 6 / 26 Jeda antar take tidak terbuang GAP 0,32 dtk, cek silencedetect di hasil akhir "sepuluh" pada 4/10 belum selesai Akhir klip ikut Whisper (terlalu awal) Perpanjang ekor kata selama masih bersuara; cek ucapan angka skor secara khusus "freelance developer" terpotong Sama (ekor kata pelan) Flag True / perpanjangan ekor Aset baru belum masuk β Selalu cek raw/ untuk aset baru, lihat semuanya, tempatkan ke kalimat jangkar Safe box kurang ketat Layout tidak memperhitungkan UI platform Bagian 4, cek dengan overlay merah
Prompt siap pakai untuk agent Edit video raw/ jadi Reels 9:16 mengikuti edit/EDITING_GUIDE.md. Buat storyboard dulu (edit/storyboard.md) dan tunggu saya setuju bila ada keputusan editorial besar. Pakai gaya yang sama dengan export/sidehustle_reels_v2.mp4: jump cut, caption kata-per-kata, kartu glass, bubble biru, b-roll dari aset di raw/, -14 LUFS, tanpa musik. Patuhi safe zone (bagian 4). Jangan render versi final sebelum still dicek dengan overlay safe zone. Simpan hasil sebagai export/_vN.mp4, jangan timpa versi lama.
Revisi: . Perbaiki lewat batas potongan berbasis energi audio (bagian 3.3), jangan menebak dari timestamp Whisper. Tambahkan catatan ke bagian "Revisi vN" di storyboard.
Menggunakan ulang untuk video baru Salin build/ dan remotion/ ke folder proyek baru (atau gunakan ulang yang ada). Ganti RAW di build_base.py, daftar SEGS di make_edl.py, fix.json, dan initial_prompt di captions.py. Ganti ITEMS, BUBBLES, BROLL, judul HookTitle, dan teks CTA di Main.tsx. Kartu bernomor/skor hanya cocok untuk format ranking; untuk format lain pakai kartu tanpa skor (hapus scoreTime/bar). Jalankan: make_edl.py β build_base.py β loudnorm 2-pass β captions.py β salin edl.json ke remotion/src β still + cek safe zone β render. Continued from β9. Menggunakan ulang untuk video baruβ Continued from β9. Menggunakan ulang untuk video baruβ