Saluran FAST menghasilkan uang dari jeda iklan. Seluruh model bisnis didasarkan pada satu asumsi: ketika saluran mengatakan "potong ke iklan," setiap sistem hilir yang mendengarkan — ad server, SSAI splicer, smart-TV player — mendengarnya pada saat yang sama persis, dengan durasi yang sama persis. SCTE-35 adalah protokol standar yang membawa pesan tersebut. Jika salah secara diam-diam — dan diam adalah mode kegagalan bawaan — iklan tidak akan dirender, muncul pada frame yang salah, atau berdurasi yang salah. Penonton melihat layar hitam. Pendapatan tidak ada.
Ini adalah kisah rekayasa tentang bagaimana saluran FAST mStudio mengeluarkan isyarat SCTE-35 yang sesuai standar dari input yang ramah operator, dan mengapa kami membangunnya sebagai tiga isyarat per jeda, bukan satu.
Gambaran singkat
| Aspek | Detail |
|---|---|
| Domain | Pensinyalan jeda iklan SCTE-35 untuk saluran FAST AWS MediaLive |
| Alur kerja operator | Editor jeda iklan per-program — posisi dalam detik, durasi dalam detik |
| Isyarat yang dipancarkan per jeda | Tiga — TimeSignal awal iklan, SpliceInsert, TimeSignal akhir iklan |
| Batasan durasi | 10–120 detik, divalidasi pada lapisan data |
| Konsumen hilir | Player, ad server, dan AWS MediaTailor (dirancang tetapi belum terhubung) adalah contohnya. |
| Status | Pancaran isyarat SCTE-35 dalam produksi; integrasi SSAI dalam tahap desain |
Masalah Bisnis
Setiap jeda iklan pada saluran FAST adalah peristiwa pendapatan. Saluran memancarkan penanda yang mengatakan "iklan akan tayang di sini, akan berlangsung 30 detik, harap bersiap." Sistem hilir — Google Ad Manager, AWS MediaTailor, ad server regional, SDK smart-TV player — membaca penanda tersebut dan memutuskan apa yang akan disisipkan.
Ketika penanda benar, jeda iklan berjalan lancar, jumlah tayangan dihitung, dan operator dibayar. Ketika penanda salah — durasi salah, bentuk salah, format salah — sistem iklan akan menolaknya (tidak ada iklan yang ditayangkan) atau menerimanya secara tidak benar (iklan dengan durasi yang salah, atau iklan yang melampaui program berikutnya). Kedua hasil tersebut merugikan uang sungguhan, dan keduanya gagal secara diam-diam. Saluran terus melakukan streaming. Penonton melihat layar hitam atau potongan yang canggung. Saluran monetisasi hanya menghasilkan angka yang lebih rendah dan tidak ada pesan kesalahan untuk ditindaklanjuti.
Tujuan rekayasa bukan "mendukung iklan." Melainkan: setiap jeda iklan yang ditentukan operator harus sampai ke setiap konsumen hilir sebagai sinyal SCTE-35 yang sesuai standar, pada frame yang tepat yang dipilih operator, setiap saat.
Apa Sebenarnya SCTE-35 Itu (Versi 90 Detik)
SCTE-35 adalah standar untuk menyisipkan pesan isyarat ke dalam aliran video. Isyarat tidak membawa konten iklan; isyarat membawa sinyal — "jeda iklan dimulai di sini," "jeda iklan berakhir di sini," "segmen ini berdurasi N detik." Sistem hilir membaca sinyal-sinyal tersebut dan bertindak berdasarkan sinyal tersebut: lapisan SSAI menyisipkan materi iklan yang sesungguhnya ke dalam HLS manifest, smart-TV player memicu overlay, ad server mencatat peluang slot.
Dua bentuk isyarat penting untuk kasus penggunaan kami:
- SpliceInsert — isyarat SCTE-35 asli. Membawa SpliceEventId, durasi dalam detik, dan tanda "out of network". Kebanyakan ad server klasik membaca ini.
- TimeSignal — isyarat yang lebih baru dan ekspresif. Membawa SegmentationDescriptor dengan SegmentationTypeId (52 = Provider Ad Start, 53 = Provider Ad End) dan SegmentationDuration dalam satuan 90.000-tick. Sistem SSAI dan player modern lebih menyukai bentuk ini karena berpasangan dengan rapi antara awal dan akhir.
Kedua bentuk ini adalah SCTE-35 yang benar. Konsumen hilir yang berbeda lebih menyukai yang berbeda. Memancarkan hanya satu bentuk berarti kehilangan potensi pendapatan.
Mengapa ini penting. Implementasi naif memancarkan satu SpliceInsert per jeda iklan dan menganggapnya selesai. Jeda iklan berfungsi pada player lama dan gagal secara diam-diam pada SSAI. Setengah dari inventaris iklan Anda menghasilkan uang; setengahnya tidak. Anda tidak akan tahu yang mana sampai angka pendapatan Anda rendah.
Mengapa Pendekatan Naif Gagal
Jalan pintas itu menggiurkan karena semuanya hampir berfungsi.
- "Pada saat encode, sisipkan iklan ke dalam video asli." Tidak ada ruang untuk fleksibilitas. Operator tidak dapat melakukan A/B-test penempatan, tidak dapat mengubah iklan setelah deploy, tidak dapat menjalankan iklan regional atau yang ditargetkan audiens. Seluruh alasan saluran FAST ada adalah untuk memonetisasi konten yang sama dengan berbagai cara — membakar iklan pada saat encode menutup peluang tersebut.
- "Memanfaatkan penyisipan iklan sisi klien." Pemblokiran iklan itu sederhana. Jalur kode yang berbeda per perangkat. Tanpa personalisasi sisi server. Dan ini sepenuhnya melewati SSAI, yang berarti CPM lebih rendah.
- "Hanya memancarkan satu SpliceInsert per jeda." Kesalahan produksi yang paling umum. Berfungsi pada beberapa player, diabaikan secara diam-diam oleh sistem SSAI yang menginginkan TimeSignal isyarat untuk memasangkan awal/akhir. Monetisasi parsial, tanpa ada kesalahan untuk diselidiki.
- "Ekspresikan semuanya dalam 90 kHz tick karena spesifikasi menyebutkannya." Spesifikasi lebih menjengkelkan dari itu. SpliceInsert.Duration dalam detik. SegmentationDuration dalam satuan 90 kHz tick. Mencampurkannya menghasilkan isyarat yang lolos validasi skema dan dikirim, kemudian gagal pada player sebagai durasi yang salah format. Encoder tidak akan menangkapnya. Player hanya melewati jeda tersebut.
- "Izinkan MediaLive untuk mengkonfirmasi." Tidak akan. MediaLive menerima jeda yang tumpang tindih, jeda durasi nol, dan durasi segmentasi yang tidak mungkin tanpa keluhan. Konfirmasi harus ada sebelum MediaLive melihat tindakan tersebut.
Pengungkit yang kami miliki adalah batas antara UI operator — di mana jeda iklan hanyalah pasangan {position, duration} — dan jadwal MediaLive, di mana setiap isyarat harus sempurna.
Solusi Kami
Perlakukan jeda iklan sebagai objek data kelas satu dari awal hingga akhir. Operator mendefinisikannya dalam istilah yang paling sederhana. Backend memvalidasinya sekali pada lapisan skema. Lambda menerjemahkannya menjadi tumpukan tiga isyarat pada waktu deploy, dengan setiap isyarat diekspresikan dalam basis waktu yang diminta oleh spesifikasinya sendiri. Tidak ada hal lain dalam tumpukan yang perlu tahu tentang SCTE-35 — terjemahan berada dalam satu fungsi, di Lambda yang sama yang memiliki setiap tindakan jadwal lainnya.
Diagram 1 · Pipeline Penanda Iklan End-to-End

Arsitektur
- Editor jeda iklan Frontend — operator menambahkan jeda iklan per program dengan menentukan offset posisi (detik dari awal program) dan durasi (detik). Slot bumper adalah bagian dari model data dan siap untuk lapisan playout.
- Koleksi AdMarker (MongoDB) — satu dokumen per program dengan jeda iklan, mereferensikan video. Array adBreaks[] menyimpan {position, duration} dengan Mongoose memberlakukan 10 ≤ duration ≤ 120 pada saat penyimpanan. Bumper membawa referensi adBreakId untuk pasangan hilir.
- Backend NestJS (schedule.service.ts) — pada saat deploy, menggabungkan setiap jadwal ke AdMarker-nya dan mengganti nama field menjadi kontrak Lambda (position → offsetSeconds, duration → durationSeconds). Satu pengambilan massal, tanpa N+1.
- Orkestrator Lambda (fastChannel-lambda-fun/index.js) — memiliki terjemahan SCTE-35. Untuk setiap jeda iklan, memancarkan tumpukan tiga isyarat ke dalam BatchUpdateScheduleCommand yang sama yang membawa input switch dan watermark. Nama tindakan diatur versinya per program sehingga pembersihan yatim piatu dapat memasangkannya setelah deploy parsial.
- AWS MediaLive — menerima tindakan, memancarkan penanda #EXT-SCTE35 dalam HLS manifest pada detik yang dipilih operator.
Keputusan Rekayasa Utama
1. Tiga isyarat per jeda iklan, bukan satu
Setiap jeda iklan memancarkan tiga tindakan diskrit terhadap momen logis yang sama dalam program.
Diagram 2 · Siklus Hidup Jeda Iklan Tunggal

Isyarat TimeSignal awal dan akhir berbagi SegmentationUpid agar sistem hilir dapat memasangkannya secara deterministik. SpliceInsert membawa SpliceEventId unik untuk deduplikasi tingkat player. Konsumen yang berbeda membaca isyarat yang berbeda. Memancarkan ketiganya mencakup setiap kontrak yang kami pedulikan hari ini dan setiap kontrak yang mungkin di masa mendatang.
Kesalahan produksi umum. Memancarkan satu SpliceInsert dan berasumsi sisa ekosistem akan menanganinya. Sistem SSAI secara diam-diam membatalkan jeda yang tidak memiliki isyarat TimeSignal yang cocok; ad server klasik mengabaikan sinyal TimeSignal-saja. Tanpa ketiganya, setiap jeda iklan dimonetisasi oleh sebagian dari tumpukan hilir Anda dan dilewatkan oleh yang lain — dan Anda mengetahuinya dari laporan pendapatan, bukan log.
2. Dua basis waktu, direkonsiliasi dalam satu fungsi
SpliceInsert.Duration dalam detik. SegmentationDuration di dalam deskriptor TimeSignal dalam satuan 90.000-tick. Durasi logis yang sama, dua encoding — dan bug SCTE-35 paling umum di lapangan adalah mencampurkannya.
Diagram 3 · Logika Konversi Waktu

Konversi tersebut berada di buildProgramActions dan hanya di sana. Ada satu tempat kanonis untuk mencari jika durasi isyarat pernah salah, dan satu tempat untuk diubah jika spesifikasi pernah berkembang.
Tradeoff yang sengaja kami lakukan. Kami bisa saja menyimpan kedua basis waktu pada dokumen AdMarker dan membiarkan Lambda menyalinnya. Kami sengaja tidak melakukannya: menyimpan hanya nilai detik berarti hanya ada satu angka yang dapat diatur operator, hanya satu angka untuk divalidasi, dan hanya satu angka yang dapat salah. Nilai 90 kHz diturunkan, tidak pernah disimpan. Data turunan tidak dapat melenceng.
3. Posisi relatif, waktu pemicu mutlak
Operator mengatakan "jeda iklan pada 720 detik ke dalam program." Lambda menghitung waktu pemicu UTC sebenarnya sebagai programStartTime + offsetSeconds × 1000 dan membubuhkannya pada tindakan. Setiap tindakan jadwal lainnya — input switch, watermark on, program end — menggunakan pipeline offset-ke-timestamp yang sama. Isyarat iklan mendarat pada batas frame yang sama dengan yang lainnya, tanpa ambiguitas tentang jam mana yang memiliki timeline.
4. Validasi pada lapisan data, bukan pada wire
Skema AdMarker memberlakukan duration ∈ [10, 120] detik pada waktu penyimpanan Mongoose. Jeda di luar jangkauan tidak pernah mencapai Lambda. Jeda iklan yang akan melampaui akhir program dipotong pada waktu build daripada ditolak — operator tidak kehilangan pekerjaan mereka karena satu jeda yang buruk. Jenis bug yang tidak dapat terjadi lebih menarik daripada yang dapat terjadi.
5. Pancaran isyarat dilepaskan dari SSAI
Apa yang kami kirim hari ini adalah lapisan pensinyalan. Penyisipan iklan sisi server melalui AWS MediaTailor — yang akan mengkonsumsi isyarat ini untuk menyisipkan materi iklan yang sesungguhnya ke dalam HLS manifest — telah sepenuhnya dirancang dan belum terhubung. Urutan yang disengaja: dapatkan lapisan isyarat benar terlebih dahulu, dalam produksi, digunakan oleh saluran yang sesungguhnya, sebelum mengaktifkan SSAI. Ketika integrasi aktif, isyarat sudah ada di sana. Sistem hilir mendapatkan kontrak yang bersih untuk dikonsumsi sejak hari pertama.
Mengapa urutan ini penting. Debugging SSAI sangat sulit ketika isyarat Anda salah, karena setiap kegagalan terlihat seperti kegagalan SSAI bahkan ketika isyarat yang salah. Dengan mengirimkan lapisan isyarat secara terpisah terlebih dahulu dan memvalidasinya terhadap player dan ad server sungguhan, kami menghilangkan seluruh kategori kebingungan integrasi sebelum itu bisa terjadi.
Hasil
- Setiap jeda iklan yang ditentukan operator memancarkan tumpukan SCTE-35 tiga isyarat yang sesuai standar dalam HLS manifest saluran — pada detik yang tepat, berdasarkan basis waktu yang tepat.
- Lapisan terjemahan berada dalam satu fungsi. Perubahan spesifikasi atau konsumen hilir baru adalah perubahan satu file, bukan pencarian di seluruh codebase.
- Validasi durasi berjalan pada lapisan data, sebelum isyarat apa pun mencapai encoder. Kesalahan operator muncul di UI, bukan secara diam-diam saat tayang — isyarat yang salah format tidak dapat mencapai MediaLive.
- Pembuatan isyarat bersifat deterministik: input operator yang identik menghasilkan tindakan SCTE-35 yang identik, sehingga jeda yang sama berperilaku dengan cara yang sama di setiap deploy dan setiap saluran.
- Lapisan pensinyalan telah dikirim dan aktif. Konsumen SSAI (MediaTailor) dirancang dan siap untuk dihubungkan — dan ketika sudah, isyarat setiap saluran yang ada akan sudah ada di sana menunggunya.
Tumpukan Teknologi: AWS MediaLive · AWS Lambda · NestJS · MongoDB · TypeScript · Node 18 · SCTE-35 (Scte35TimeSignalSettings, Scte35SpliceInsertSettings) · AWS SDK v3

