{"slug": "workflow-editing-pake-ai", "title": "Workflow editing pake AI", "summary": "A developer built a Telegram bot that generates client invoices on demand, complete with PDF output and buttons to mark deposits, mark paid, resend, or duplicate an invoice. The bot is aimed at managing three separate personas — programmer, content creator, and DJ — each with different billing names, bank accounts, clients, and due dates that previously had to be entered by hand. The developer also documented an AI-assisted editing workflow, including a Remotion-based pipeline and a split-screen layout that keeps step cards clear of the speaker's face.", "body_md": "Storyboard (revisi 1): \"Gue Bikin Bot Telegram Buat Invoice\"\n\nSumber: raw/take_invoice.MP4 (2:51, 1080×1920 HEVC, selfie close-up, satu take dengan banyak ulangan).\nAset: 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).\nTarget: Reels 1080×1920, 30 fps, -14 LUFS, tanpa musik, durasi perkiraan ±1:30 (opsi pangkas ke ±1:10 ada di bawah).\nPipeline: edit/EDITING_GUIDE.md (potong dari energi audio, caption dari transkrip hasil potongan, Remotion, safe zone).\n\nReferensi gaya (@andreakyton, \"AI editor guide\", 1:04)\n\nYang bisa kuamati dari 2 frame yang berhasil kuputar (seek di pemutar TikTok tidak mau pindah, jadi sisanya tidak kulihat):\n\nTalking head full-frame, dengan kartu putih besar di bagian atas yang berisi layar/grafik dan judul bertuliskan \"STEP N + nama langkah\".\n\nCaption putih tebal, 1 kata per kemunculan, di bawah kartu, di atas dada.\n\nKartu berganti per langkah, sementara pembicara tetap di frame.\nYang belum kuketahui (transisi, SFX, zoom, kecepatan potong). Kalau ada momen lain di video itu yang kamu suka, sebutkan detiknya.\n\nKeputusan layout (perlu persetujuanmu)\n\nDi 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.\nPreview geometri (zona merah = area UI TikTok/IG, kotak putih = posisi caption): edit/invoice/export/layout_preview.png.\n\nKartu di y≈285–560, lebar ±700 (di dalam safe zone), wajah utuh di y≈720–1170, caption tepat di bawah dagu (y≈1210–1380).\n\nSaat tidak ada kartu: footage full-frame, caption di bawah dagu (y≈1100–1300 mengikuti guide), tanpa pergeseran.\n\nPerpindahan full ↔ split memakai animasi zoom 0,25 dtk supaya terasa disengaja, bukan lompat.\n\nAturan visual\n\nElemen\n\nSpek\n\nJump cut\n\nJeda > 0,32 dtk dibuang, batas potong dari energi audio. Zoom bergantian 1.00 ↔ 1.06 per klip saat layout full.\n\nCaption\n\nMontserrat 900 putih, stroke hitam, 1–3 kata, kata aktif kuning #FFD43B. Posisi lihat layout di atas.\n\nKartu langkah\n\nGlass card gelap dengan badge biru \"#N\" + judul langkah (gaya \"STEP N\" referensi). Muncul slide dari atas.\n\nKartu Telegram\n\nScreenshot yang di-crop (lihat privasi), border putih, muncul di slot kartu.\n\nWhoosh tiap kartu masuk, ding saat \"it works\". Tanpa musik.\n\nSafe zone\n\nAtas 280, bawah 1440, kanan 150, kiri 60. Dicek dengan still berkotak merah sebelum render.\n\nScene list\n\nWaktu \"sumber\" dari transkrip. Waktu \"out\" perkiraan, final setelah EDL.\n\n#\n\nSumber\n\nUcapan (ringkas)\n\nVisual / teks layar\n\nCatatan edit\n\n1 Hook\n\n0.6–5.9\n\n\"Jadi selain jadi programmer, gue punya dua kerjaan lain, yaitu jadi DJ dan jadi content creator.\"\n\nJudul besar \"GUE BIKIN BOT TELEGRAM BUAT INVOICE\" di atas kepala (3 baris, font 76, kuning di \"BOT TELEGRAM\"), full layout\n\nDibuka langsung di suara.\n\n2 Masalah\n\n11.4–17.0\n\n\"Kesamaan di antara ketiganya adalah gue butuh invoice untuk nagih pembayaran ke klien.\"\n\nKartu langkah #1 MASALAH: ikon 🧾. Bubble \"butuh invoice 🧾\"\n\nTake 7.3–10.3 dibuang (kata terputus).\n\n38.9–46.5\n\n\"Cuman masalahnya, gue masih harus ngutak-atik manual untuk data-datanya.\"\n\nBubble \"data manual 😩\"\n\n56.5–61.8\n\n\"Gue selalu memisahkan persona programmer, content creator, dan DJ.\"\n\nKartu 3 chip: 💻 Programmer · 🎬 Content creator · 🎧 DJ\n\nKalimat \"Misalkan untuk persona programmer\" (48.1–50.2) menggantung, dibuang.\n\n65.0–73.98\n\n\"Atas nama gue selalu berubah-ubah. Ditambah rekeningnya beda, kliennya beda, jatuh temponya beda, segala itemnya beda semua.\"\n\nBubble \"semua beda 🤯\" (di \"beda semua\").\n\nTake pertama \"atas nama\" (62.6–64.3) dibuang, pakai take kedua.\n\n74.9–80.4\n\n\"Setiap gue bikin invoice baru, gue harus masukin datanya manual. Gue males hal ini.\"\n\n3 Solusi\n\n84.8–89.1\n\n\"Karena gue resah dengan hal ini, gue memutuskan diskusi dengan Claude.\"\n\nKartu #2 SOLUSI: \"ngobrol sama Claude\" 🤖. Mulai di kata \"Claude\", b-roll diskusi_claude.MOV full-screen (lihat bagian B-roll).\n\n\"Cloud\" di transkrip = Claude (dikonfirmasi). Awal yang tersendat (81.5–84.8) dibuang.\n\n90.7–96.2\n\n\"Gue curhat gimana pain point-nya dan minta solusi.\"\n\nB-roll Claude lanjut sampai ±\"minta solusi\", lalu kembali ke wajah.\n\nDengan adanya b-roll bagian ini jadi dipertahankan (dibuang hanya di opsi pendek).\n\n98.3–108.1\n\n\"Karena gue kesel, gue mikir, apa gue bikin bot Telegram aja ya buat mengakomodasi keresahan gue.\"\n\nMuncul kartu Telegram (crop \"Invoice DJ/2026/002 dibuat\" + PDF) tepat di kata \"Telegram\". Layout beralih ke split.\n\nAnchor Telegram.\n\n4 Alasan\n\n108.8–113.4\n\n\"Kadang waktu klien minta invoice, gue lagi di luar, kejutan.\"\n\nOpsi pangkas.\n\n114.4–121.7\n\n\"Contohnya semalam, gue diminta bikin invoice jam 11 atau 12 malam, sedangkan gue lagi perform di club.\"\n\nBubble \"jam 11 malam, lagi di club 🎧\"\n\n5 Demo\n\n122.7–126.1\n\n\"Akhirnya udah jadi dan udah bisa dipakai.\"\n\nKartu #3 CARA PAKAI\n\n127.2–137.98\n\n\"Gue tinggal ngechat aja mau gue apa: invoice untuk persona yang mana, DJ kek, content creator kek, dan untuk klien siapa.\"\n\nKartu Telegram: potongan percakapan (klien baru tersimpan, invoice dibuat).\n\n138.8–145.3\n\n\"Peruntukannya untuk klien siapa, deskripsinya gimana, rekening yang mana, itu udah ke-set semua.\"\n\nKartu Telegram: tombol Tandai DP / Tandai Lunas / Kirim PDF lagi / Duplikat (crop kedua).\n\n6 Hasil\n\n148.5–159.6\n\n\"Baru semalam gue pake dan it works. Ketika gue lagi di luar, gak pegang laptop, gue bisa bikin invoice sendiri. Mempermudah banget.\"\n\nBubble \"it works ✅\" + ding. Kembali full layout.\n\n7 CTA\n\n164.8–171.1\n\n\"Gimana, kalian ada yang penasaran gak cara bikinnya dan tech stack apa aja yang gue pake untuk teknologi ini?\"\n\nBubble \"Mau tau cara & tech stack-nya? Komen 👇\" (CTA dari ucapanmu sendiri).\n\nTake pertama (160.7–164) dibuang, pakai take kedua yang lebih utuh.\n\nPerkiraan: dengan semua baris di atas ±1:35, setelah jeda dibuang ±1:25–1:30.\nOpsi 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).\nContoh 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.\n\nB-roll diskusi_claude.MOV\n\nIsi: 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.\n\nDipakai ±3,5 dtk dari 5,2 dtk, tanpa suaranya (hanya ±-45 dB ambient), suaramu tetap jalan.\n\nCrop 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.\n\nLabel kecil \"Claude 🤖\" di kartu langkah supaya penonton langsung paham itu layar apa.\n\nSebagian 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.\n\nPenanganan data di screenshot (butuh konfirmasi)\n\nScreenshot memuat nama klien Zeeto Coffee, nomor invoice DJ/2026/002, dan alamat lengkap klien (Jl. Suryowijayan, Gedongkiwo, Yogyakarta 55142) di bagian atas. Rencanaku:\n\nCrop hanya bagian \"Klien … tersimpan\", \"Invoice … dibuat\", PDF, dan tombol. Alamat dan jam status bar tidak ditampilkan.\n\nNama klien dan nomor invoice tetap terlihat. Mau disamarkan (blur/ganti \"Klien A\")? Pilihan ada di bawah.\n\nAudio\n\nLoudnorm dua pass → -14 LUFS, fade 10 ms di tiap sambungan, whoosh dan ding sintetis (bebas hak cipta). Tanpa musik.\n\nCaption IG (draft, belum dihumanize)\n\nGue 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 👇\n#programmer #freelancer #contentcreator #dj #invoice #telegrambot #ai\n\nPerlu dicek kreator\n\nDikonfirmasi: \"cloud\" = Claude, \"text-text\" = tech stack. Masih belum jelas: kata sebelum \"segala matemnya\" (item-itemnya? rate-nya?).\n\nJudul: \"Gue Bikin Bot Telegram Buat Invoice\" (dari kamu). Hook 0–3 dtk memakai judul ini; usulan teks \"3 PEKERJAAN, 1 MASALAH\" kubuang.\n\nHasil v1 (export/gue_bikin_bot_telegram_buat_invoice_v1.mp4)\n\nDurasi 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.\n\nSemua bagian storyboard masuk (tanpa opsi pangkas). Layout split dipakai di hook, kartu langkah, chip persona, dan kartu Telegram.\n\nPerubahan 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.\n\nPipeline: invoice/build/ (make_edl.py, build_base.py, loudnorm.sh, captions.py, render.sh) dan invoice/remotion/.\n\nB-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.\n\nCaption \"buatnya\" diperbaiki jadi \"bot-nya\".\n\nKalimat \"dan untuk klien yang siapa\" dibuang dari potongan (sumber 135.80–138.75).\n\nDurasi 1:36, -13,7 LUFS, tanpa jeda kosong, frame hitam, atau frame beku.\n\nPanduan ini untuk agent (Claude Code dll.) yang mengedit video talking head vertikal jadi Reels/TikTok dengan gaya:\njump cut rapat, caption kata-per-kata, kartu glass di atas, bubble biru, b-roll screenshot, tanpa musik.\nReferensi gaya: video @brandnat (\"Comment EDIT\") + guide aicreatorlibrary.com/blog/ai-video-editing-prompts.\nContoh hasil: export/sidehustle_reels_v2.mp4. Kode contoh: folder build/ dan remotion/src/.\n\nBahasa kerja dengan kreator: Indonesia santai (gue/lu). Kreator: @damsatriaa (Satria), Android dev + IT content creator.\n\nStoryboard dulu (storyboard.md), baru edit. Kreator meminta ini secara eksplisit.\n\nPotong dulu, dekorasi kemudian. Setiap cut menggeser timestamp, jadi caption/overlay baru dibuat setelah potongan final.\n\nTranskrip ulang hasil potongan untuk timing caption (jangan pakai timestamp transkrip raw).\n\nJangan menimpa file lama. Keluaran diberi versi: *_v2.mp4, *_v3.mp4.\n\nRaw footage tidak pernah diubah.\n\nVerifikasi dengan still + contact sheet + cek silence/loudness sebelum bilang \"selesai\". Agent tidak bisa menilai sinkron bibir; minta kreator menonton sekali penuh.\n\n1. Setup tool (gotcha yang sudah kejadian)\n\nMasalah\n\nSolusi\n\nfaster_whisper tidak ada di python Homebrew\n\nBuat venv di scratchpad: python3 -m venv $S/venv && $S/venv/bin/pip install faster-whisper\n\nJangan kirim path. Ekstrak wav 16 kHz mono dengan ffmpeg, baca pakai wave+numpy, kirim array float32 ke model.transcribe(array)\n\nModel sudah ter-cache\n\n~/.cache/huggingface/hub punya faster-whisper-small dan base. Pakai small (CPU int8 di M1 cukup)\n\nnpx remotion ... gagal lewat hook RTK (output error npm)\n\nPakai binary langsung dengan proxy: rtk proxy ./node_modules/.bin/remotion render ...\n\nffmpeg loudnorm error Invalid chars 'inear=true'\n\nPisahkan param: ...:offset=1.71:linear=true (jangan ditempel ke angka offset)\n\nRemotion font emoji tidak tampil\n\nfontFamily harus \"Montserrat\", \"Apple Color Emoji\", \"Noto Color Emoji\", sans-serif\n\ntsc komplain properti baru\n\nTambahkan ke type ITEMS (contoh: short?: string)\n\nRender panjang\n\nJalankan di background, jangan polling; tunggu notifikasi selesai\n\nVersi yang dipakai: remotion@4.0.400, @remotion/cli, @remotion/google-fonts, react 18.3.1, typescript 5.6.3.\nScratchpad dipakai untuk venv, wav sementara, dan still preview. Hasil akhir ke edit/export/.\n\n2. Struktur folder\n\n```\nraw/                      footage + aset screenshot (jangan diubah)\nreference/                video referensi gaya\nedit/\n  storyboard.md           storyboard + catatan revisi\n  EDITING_GUIDE.md        file ini\n  build/\n    make_edl.py           daftar segmen terpilih -> batas potongan (EDL) -> edl.json\n    build_base.py         ffmpeg trim+concat -> base.mov\n    captions.py           transkrip hasil potongan -> kata caption di edl.json\n    fix.json              koreksi kata (words + phrases)\n    words_raw.json        transkrip raw (per kata)\n    words_base.json       transkrip hasil potongan (cache)\n  remotion/\n    public/               base.mp4, ding.wav, whoosh.wav, aset b-roll (jpg)\n    src/Main.tsx          semua overlay (caption, kartu, bubble, b-roll, ringkasan)\n    src/edl.json          salinan edl.json dari build/ (WAJIB disalin ulang tiap ada perubahan)\n  export/                 hasil render + storyboard\n```\n\n3. Pipeline langkah demi langkah\n\n3.1 Transkrip raw\n\nffmpeg -i raw.MP4 -vn -ac 1 -ar 16000 a.wav\n\nfaster-whisper small, language=\"id\", word_timestamps=True. Simpan per kata ke words_raw.json + teks per segmen (untuk dibaca manusia).\n\nHasil raw biasanya salah dengar nama/istilah dan memuat banyak take ulang. Baca seluruh transkrip dan pilih take terbaik per kalimat.\n\n3.2 Pilih segmen (SEGS)\n\nDi make_edl.py, tulis list (id_bagian, src_mulai, src_selesai[, True]) untuk take terbaik. Aturan editorial:\n\nBuang blooper, kalimat tidak selesai, take pertama kalau ada take kedua yang lebih bersih.\n\nBuang kalimat redundan (\"effortnya gak sebanding…\") bila poin sudah jelas.\n\nBoleh menukar urutan kalimat bila punchline lebih kuat di akhir (contoh: undervalue → \"skill nego gue yang kurang\").\n\nSatu ide = satu id bagian (hook, n1…n8, cta). Id ini dipakai untuk kartu, b-roll, dan skor.\n\nFlag True di elemen ke-4 = paksa ekor kata pelan tidak terpotong (lihat 3.3).\n\n3.3 Hitung batas potongan dari energi audio (PENTING)\n\nTimestamp kata dari Whisper meleset hingga ±0,5 dtk. Jangan potong berdasarkan itu. Yang benar:\n\nHitung RMS dB per 10 ms dari wav 16 kHz.\n\nRegion bersuara = frame dengan dB > -36 (noise ruangan ±-45 s/d -55). Gabungkan region yang jaraknya ≤ 0,32 dtk (GAP). Abaikan region < 0,08 dtk.\n\nPerpanjang 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.\n\nPadding: awal -0,04, akhir +0,10 dtk.\n\nKlip pertama video: geser awal +0,03 agar langsung terbuka di suara (tanpa udara kosong).\n\nUntuk kata dengan ekor sangat pelan (di sini: \"hustle\", \"kayaknya\", \"aja\") pakai flag True agar akhir klip minimal b - 0,1.\n\nFade audio 10 ms di tiap sambungan (afade in/out) supaya tidak \"klik\".\n\nHasil ke edl.json: clips (src_s, src_e, out_s, dur, sec), words, total.\n\n3.4 Render potongan dasar\n\nbuild_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.\n\nTranskrip ulang base.mov (initial_prompt berisi istilah: side hustle, Play Store, GMV, SaaS, dst.). Cache ke words_base.json.\n\nKoreksi lewat fix.json: words (ganti per kata) dan phrases (ganti urutan kata; lebih aman daripada ganti kata tunggal yang ambigu, mis. \"kedua\"/\"it\"/\"Content\").\n\nSkor 4x10/4 % -> 4/10 (regex menangani variasi). Token -gila digabung ke kata sebelumnya.\n\nAwal kata di-snap ke suara (geser sampai dB > -40).\n\nBagian (sec) ditentukan dari titik tengah kata, bukan awal (kata di batas klip sering salah masuk bagian).\n\nTulis ke edl.json -> words, lalu cp build/edl.json remotion/src/edl.json.\n\nSelalu baca hasil teks caption penuh dan cek ke kreator kata yang kurang yakin.\n\n3.7 Overlay di Remotion (Main.tsx)\n\nSemua di atas OffthreadVideo(base.mp4). Komponen:\n\nKomponen\n\nSpek\n\nFootage\n\nZoom 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\".\n\nCaptions\n\nMontserrat 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.\n\nHookTitle\n\n0–2,9 dtk, judul besar kuning/putih 84px miring -2°, subjudul di kartu glass.\n\nItemCard\n\nKartu 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.\n\nBubble\n\nBubble biru iMessage #0A84FF, 42px, miring -2°, spring pop. Untuk kalimat kunci (≤ 6 kata + emoji). Tampil 2,2 dtk dan dipotong di akhir bagian.\n\nBRoll\n\nMode kartu: screenshot dengan border putih, bayangan, footage diredupkan 38%. Mode full: layar penuh + zoom pelan 1.0→1.08.\n\nSummary\n\nKartu ranking akhir (semua item + bar skor) pada CTA, diikuti bubble CTA.\n\nSFX\n\nwhoosh.wav tiap kartu/b-roll masuk, ding.wav tiap skor. Dibuat dengan ffmpeg (sine, anoisesrc), bebas hak cipta.\n\nPalet skor: #ff4d4d (≤4) → #ff7a3d → #ffb02e → #ffd43b → #b8e04a → #7ed957 → #3ddc84 → #22e07a (10).\nPosisi bubble/b-roll ditentukan dari kata jangkar (wordAt(sec, \"kata\")), jadi ikut bergeser otomatis bila caption berubah.\n\n3.8 B-roll dari aset kreator\n\nAset 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.\n\nSatu aset = satu kalimat jangkar. Aset layar penuh (foto aktivitas) boleh full; screenshot UI pakai mode kartu.\n\nJangan tampilkan data sensitif (saldo, email, nomor) tanpa konfirmasi kreator.\n\n4. Safe zone Reels/TikTok (WAJIB)\n\nKreator menegur: elemen tertimpa UI platform. Layout 1080×1920, semua overlay harus berada di area ini:\n\nSisi\n\nBatas\n\nAlasan\n\nAtas\n\ntidak ada konten di y < 280\n\nstatus bar, search bar TikTok (\"Find related content\"), tombol back/+\n\nBawah\n\ntidak ada konten di y > 1440\n\nusername, deskripsi, tombol insight/boost\n\nKanan\n\ntidak ada konten di x > 930 (margin 150)\n\ntombol like/komentar/share/save\n\nKiri\n\nmargin 60\n\naman dari tepi\n\nKonstanta di kode:\n\n``` js\nconst SAFE = { left: 60, right: 150, top: 280, capTop: 1100, bubbleTop: 1325 };\nconst safeX = { left: SAFE.left, right: SAFE.right, width: \"auto\" };  // pakai untuk AbsoluteFill overlay\n```\n\nTata 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.\n\nCara 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.\n\n5. Template storyboard (storyboard.md)\n\nJudul, sumber (durasi/resolusi/codec), target durasi, referensi gaya + guide.\n\nTabel scene list: # | waktu out | ucapan ringkas | visual/teks layar | catatan edit (catat take yang dibuang dan alasannya).\n\nAudio: loudness target, fade sambungan, SFX, musik (default: tanpa musik; kreator tambah dari library IG saat upload).\n\nCaption IG + hashtag (draft).\n\nPerlu dicek kreator: kata hasil tebakan transkrip.\n\nBagian Revisi vN: tiap feedback kreator -> perbaikan yang dilakukan.\n\n6. QA sebelum menyerahkan (dari guide, \"Change nothing\")\n\nffprobe: 1080×1920, 30 fps, durasi.\n\nebur128: ±-14 LUFS, peak ≤ -1 dB.\n\nsilencedetect=noise=-40dB:d=0.35 pada hasil akhir: tidak boleh ada jeda panjang.\n\nblackdetect dan freezedetect.\n\nContact sheet (fps=1/3,scale=200:-1,tile=9x4): caption tidak menutup mulut/mata, tidak ada elemen terpotong, ejaan benar, bubble tidak menumpuk.\n\nSafe zone (bagian 4).\n\nAkui keterbatasan: agent hanya melihat still, jadi sinkron bibir dan timing SFX harus ditonton kreator.\n\n7. Pelajaran dari feedback kreator (jangan ulangi)\n\nFeedback\n\nAkar masalah\n\nPencegahan\n\nIntro kelamaan, tidak langsung audio\n\nAwal klip dari timestamp Whisper, ada udara kosong\n\nBatas dari energi audio; klip pertama mulai di suara\n\nAda audio kosong sebelum detik 6 / 26\n\nJeda antar take tidak terbuang\n\nGAP 0,32 dtk, cek silencedetect di hasil akhir\n\n\"sepuluh\" pada 4/10 belum selesai\n\nAkhir klip ikut Whisper (terlalu awal)\n\nPerpanjang ekor kata selama masih bersuara; cek ucapan angka skor secara khusus\n\n\"freelance developer\" terpotong\n\nSama (ekor kata pelan)\n\nFlag True / perpanjangan ekor\n\nAset baru belum masuk\n\n—\n\nSelalu cek raw/ untuk aset baru, lihat semuanya, tempatkan ke kalimat jangkar\n\nSafe box kurang ketat\n\nLayout tidak memperhitungkan UI platform\n\nBagian 4, cek dengan overlay merah\n\n8. Prompt siap pakai untuk agent\n\nEdit 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.\n\nRevisi: . Perbaiki lewat batas potongan berbasis energi audio (bagian 3.3), jangan menebak dari timestamp Whisper. Tambahkan catatan ke bagian \"Revisi vN\" di storyboard.\n\n9. Menggunakan ulang untuk video baru\n\nSalin build/ dan remotion/ ke folder proyek baru (atau gunakan ulang yang ada).\n\nGanti RAW di build_base.py, daftar SEGS di make_edl.py, fix.json, dan initial_prompt di captions.py.\n\nGanti 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).\n\nJalankan: make_edl.py → build_base.py → loudnorm 2-pass → captions.py → salin edl.json ke remotion/src → still + cek safe zone → render.\n\nPanduan Editing Reels: Talking Head + Jump Cut + Overlay (Remotion + ffmpeg)\nPanduan 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/.\n\nBahasa kerja dengan kreator: Indonesia santai (gue/lu). Kreator: @damsatriaa (Satria), Android dev + IT content creator.\n\nAturan emas (urutan kerja)\nInspect raw: ffprobe (durasi, resolusi, fps), lihat contact sheet frame, transkrip.\nStoryboard dulu (storyboard.md), baru edit. Kreator meminta ini secara eksplisit.\nPotong dulu, dekorasi kemudian. Setiap cut menggeser timestamp, jadi caption/overlay baru dibuat setelah potongan final.\nTranskrip ulang hasil potongan untuk timing caption (jangan pakai timestamp transkrip raw).\nJangan menimpa file lama. Keluaran diberi versi: *_v2.mp4, *_v3.mp4.\nRaw footage tidak pernah diubah.\nVerifikasi dengan still + contact sheet + cek silence/loudness sebelum bilang \"selesai\". Agent tidak bisa menilai sinkron bibir; minta kreator menonton sekali penuh.\n\nSetup tool (gotcha yang sudah kejadian)\nMasalah Solusi\nfaster_whisper tidak ada di python Homebrew Buat venv di scratchpad: python3 -m venv $S/venv && $S/venv/bin/pip install faster-whisper\nfaster-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)\nModel sudah ter-cache ~/.cache/huggingface/hub punya faster-whisper-small dan base. Pakai small (CPU int8 di M1 cukup)\nnpx remotion ... gagal lewat hook RTK (output error npm) Pakai binary langsung dengan proxy: rtk proxy ./node_modules/.bin/remotion render ...\nffmpeg loudnorm error Invalid chars 'inear=true' Pisahkan param: ...:offset=1.71:linear=true (jangan ditempel ke angka offset)\nRemotion font emoji tidak tampil fontFamily harus \"Montserrat\", \"Apple Color Emoji\", \"Noto Color Emoji\", sans-serif\ntsc komplain properti baru Tambahkan ke type ITEMS (contoh: short?: string)\nRender panjang Jalankan di background, jangan polling; tunggu notifikasi selesai\nVersi 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/.\n\nStruktur folder\nraw/ footage + aset screenshot (jangan diubah)\nreference/ video referensi gaya\nedit/\nstoryboard.md storyboard + catatan revisi\nEDITING_GUIDE.md file ini\nbuild/\nmake_edl.py daftar segmen terpilih -> batas potongan (EDL) -> edl.json\nbuild_base.py ffmpeg trim+concat -> base.mov\ncaptions.py transkrip hasil potongan -> kata caption di edl.json\nfix.json koreksi kata (words + phrases)\nwords_raw.json transkrip raw (per kata)\nwords_base.json transkrip hasil potongan (cache)\nremotion/\npublic/ base.mp4, ding.wav, whoosh.wav, aset b-roll (jpg)\nsrc/Main.tsx semua overlay (caption, kartu, bubble, b-roll, ringkasan)\nsrc/edl.json salinan edl.json dari build/ (WAJIB disalin ulang tiap ada perubahan)\nexport/ hasil render + storyboard\n\nPipeline langkah demi langkah\n3.1 Transkrip raw\nffmpeg -i raw.MP4 -vn -ac 1 -ar 16000 a.wav\nfaster-whisper small, language=\"id\", word_timestamps=True. Simpan per kata ke words_raw.json + teks per segmen (untuk dibaca manusia).\nHasil raw biasanya salah dengar nama/istilah dan memuat banyak take ulang. Baca seluruh transkrip dan pilih take terbaik per kalimat.\n3.2 Pilih segmen (SEGS)\nDi make_edl.py, tulis list (id_bagian, src_mulai, src_selesai[, True]) untuk take terbaik. Aturan editorial:\n\nBuang blooper, kalimat tidak selesai, take pertama kalau ada take kedua yang lebih bersih.\nBuang kalimat redundan (\"effortnya gak sebanding…\") bila poin sudah jelas.\nBoleh menukar urutan kalimat bila punchline lebih kuat di akhir (contoh: undervalue → \"skill nego gue yang kurang\").\nSatu ide = satu id bagian (hook, n1…n8, cta). Id ini dipakai untuk kartu, b-roll, dan skor.\nFlag True di elemen ke-4 = paksa ekor kata pelan tidak terpotong (lihat 3.3).\n3.3 Hitung batas potongan dari energi audio (PENTING)\nTimestamp kata dari Whisper meleset hingga ±0,5 dtk. Jangan potong berdasarkan itu. Yang benar:\n\nHitung RMS dB per 10 ms dari wav 16 kHz.\nRegion bersuara = frame dengan dB > -36 (noise ruangan ±-45 s/d -55). Gabungkan region yang jaraknya ≤ 0,32 dtk (GAP). Abaikan region < 0,08 dtk.\nPerpanjang 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.\nPadding: awal -0,04, akhir +0,10 dtk.\nKlip pertama video: geser awal +0,03 agar langsung terbuka di suara (tanpa udara kosong).\nUntuk kata dengan ekor sangat pelan (di sini: \"hustle\", \"kayaknya\", \"aja\") pakai flag True agar akhir klip minimal b - 0,1.\nFade audio 10 ms di tiap sambungan (afade in/out) supaya tidak \"klik\".\nHasil ke edl.json: clips (src_s, src_e, out_s, dur, sec), words, total.\n\n3.4 Render potongan dasar\nbuild_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.\n\nTranskrip ulang base.mov (initial_prompt berisi istilah: side hustle, Play Store, GMV, SaaS, dst.). Cache ke words_base.json.\nKoreksi lewat fix.json: words (ganti per kata) dan phrases (ganti urutan kata; lebih aman daripada ganti kata tunggal yang ambigu, mis. \"kedua\"/\"it\"/\"Content\").\nSkor 4x10/4 % -> 4/10 (regex menangani variasi). Token -gila digabung ke kata sebelumnya.\nAwal kata di-snap ke suara (geser sampai dB > -40).\nBagian (sec) ditentukan dari titik tengah kata, bukan awal (kata di batas klip sering salah masuk bagian).\nTulis ke edl.json -> words, lalu cp build/edl.json remotion/src/edl.json.\nSelalu baca hasil teks caption penuh dan cek ke kreator kata yang kurang yakin.\n\n3.7 Overlay di Remotion (Main.tsx)\nSemua di atas OffthreadVideo(base.mp4). Komponen:\n\nKomponen Spek\nFootage 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\".\nCaptions 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.\nHookTitle 0–2,9 dtk, judul besar kuning/putih 84px miring -2°, subjudul di kartu glass.\nItemCard 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.\nBubble Bubble biru iMessage #0A84FF, 42px, miring -2°, spring pop. Untuk kalimat kunci (≤ 6 kata + emoji). Tampil 2,2 dtk dan dipotong di akhir bagian.\nBRoll Mode kartu: screenshot dengan border putih, bayangan, footage diredupkan 38%. Mode full: layar penuh + zoom pelan 1.0→1.08.\nSummary Kartu ranking akhir (semua item + bar skor) pada CTA, diikuti bubble CTA.\nSFX whoosh.wav tiap kartu/b-roll masuk, ding.wav tiap skor. Dibuat dengan ffmpeg (sine, anoisesrc), bebas hak cipta.\nPalet 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.\n\n3.8 B-roll dari aset kreator\nAset 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.\nSatu aset = satu kalimat jangkar. Aset layar penuh (foto aktivitas) boleh full; screenshot UI pakai mode kartu.\nJangan tampilkan data sensitif (saldo, email, nomor) tanpa konfirmasi kreator.\n4. Safe zone Reels/TikTok (WAJIB)\nKreator menegur: elemen tertimpa UI platform. Layout 1080×1920, semua overlay harus berada di area ini:\n\nSisi Batas Alasan\nAtas tidak ada konten di y < 280 status bar, search bar TikTok (\"Find related content\"), tombol back/+\nBawah tidak ada konten di y > 1440 username, deskripsi, tombol insight/boost\nKanan tidak ada konten di x > 930 (margin 150) tombol like/komentar/share/save\nKiri margin 60 aman dari tepi\nKonstanta di kode:\n\nconst SAFE = { left: 60, right: 150, top: 280, capTop: 1100, bubbleTop: 1325 };\nconst safeX = { left: SAFE.left, right: SAFE.right, width: \"auto\" }; // pakai untuk AbsoluteFill overlay\nTata 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.\n\nCara 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.\n\nTemplate storyboard (storyboard.md)\nJudul, sumber (durasi/resolusi/codec), target durasi, referensi gaya + guide.\nTabel aturan visual (jump cut, zoom, caption, kartu, skor, progres).\nTabel scene list: # | waktu out | ucapan ringkas | visual/teks layar | catatan edit (catat take yang dibuang dan alasannya).\nAudio: loudness target, fade sambungan, SFX, musik (default: tanpa musik; kreator tambah dari library IG saat upload).\nCaption IG + hashtag (draft).\nPerlu dicek kreator: kata hasil tebakan transkrip.\nBagian Revisi vN: tiap feedback kreator -> perbaikan yang dilakukan.\n\nQA sebelum menyerahkan (dari guide, \"Change nothing\")\nffprobe: 1080×1920, 30 fps, durasi.\nebur128: ±-14 LUFS, peak ≤ -1 dB.\nsilencedetect=noise=-40dB:d=0.35 pada hasil akhir: tidak boleh ada jeda panjang.\nblackdetect dan freezedetect.\nContact sheet (fps=1/3,scale=200:-1,tile=9x4): caption tidak menutup mulut/mata, tidak ada elemen terpotong, ejaan benar, bubble tidak menumpuk.\nSafe zone (bagian 4).\nAkui keterbatasan: agent hanya melihat still, jadi sinkron bibir dan timing SFX harus ditonton kreator.\n\nPelajaran dari feedback kreator (jangan ulangi)\nFeedback Akar masalah Pencegahan\nIntro kelamaan, tidak langsung audio Awal klip dari timestamp Whisper, ada udara kosong Batas dari energi audio; klip pertama mulai di suara\nAda audio kosong sebelum detik 6 / 26 Jeda antar take tidak terbuang GAP 0,32 dtk, cek silencedetect di hasil akhir\n\"sepuluh\" pada 4/10 belum selesai Akhir klip ikut Whisper (terlalu awal) Perpanjang ekor kata selama masih bersuara; cek ucapan angka skor secara khusus\n\"freelance developer\" terpotong Sama (ekor kata pelan) Flag True / perpanjangan ekor\nAset baru belum masuk — Selalu cek raw/ untuk aset baru, lihat semuanya, tempatkan ke kalimat jangkar\nSafe box kurang ketat Layout tidak memperhitungkan UI platform Bagian 4, cek dengan overlay merah\n\nPrompt siap pakai untuk agent\nEdit 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.\n\nRevisi: . Perbaiki lewat batas potongan berbasis energi audio (bagian 3.3), jangan menebak dari timestamp Whisper. Tambahkan catatan ke bagian \"Revisi vN\" di storyboard.\n\nMenggunakan ulang untuk video baru\nSalin build/ dan remotion/ ke folder proyek baru (atau gunakan ulang yang ada).\nGanti RAW di build_base.py, daftar SEGS di make_edl.py, fix.json, dan initial_prompt di captions.py.\nGanti 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).\nJalankan: make_edl.py → build_base.py → loudnorm 2-pass → captions.py → salin edl.json ke remotion/src → still + cek safe zone → render.\nContinued from “9. Menggunakan ulang untuk video baru”\nContinued from “9. Menggunakan ulang untuk video baru”", "url": "https://wpnews.pro/news/workflow-editing-pake-ai", "canonical_source": "https://gist.github.com/notsatria/f4ad7836d0326126922a5c9a707f7b10", "published_at": "2026-11-09 06:59:26+00:00", "updated_at": "2026-11-09 07:21:12.241471+00:00", "lang": "en", "topics": ["ai-tools", "ai-agents", "generative-ai"], "entities": ["Telegram", "Claude", "Remotion", "TikTok", "Instagram"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/workflow-editing-pake-ai", "markdown": "https://wpnews.pro/news/workflow-editing-pake-ai.md", "text": "https://wpnews.pro/news/workflow-editing-pake-ai.txt", "jsonld": "https://wpnews.pro/news/workflow-editing-pake-ai.jsonld"}}