StreamFlow adalah platform live streaming berbasis web yang powerful dan mudah digunakan. Streaming ke YouTube, Facebook, dan platform RTMP lainnya secara bersamaan dengan satu aplikasi. Dilengkapi dengan video management, scheduled streaming, dan real-time monitoring untuk pengalaman streaming yang profesional.
π Installation β’ π Documentation β’ π³ Docker β’ πͺ Troubleshooting β’ π¬ Community
- Multi-Platform Streaming - Streaming ke berbagai platform populer secara bersamaan
- Video Gallery - Kelola koleksi video dengan antarmuka yang intuitif
- Upload Video - Upload dari local storage atau import langsung dari Google Drive
- Scheduled Streaming - Jadwalkan streaming dengan pengaturan waktu yang fleksibel
- Advanced Settings - Kontrol penuh untuk bitrate, resolusi, FPS, dan orientasi video
- Real-time Monitoring - Monitor status streaming dengan dashboard real-time
- Video Analytics - Pantau statistik dan performa video langsung dari aplikasi
- Responsive UI - Antarmuka modern yang responsif di semua perangkat
- Node.js v18 atau versi terbaru
- FFmpeg untuk video processing (6.1+ jika ingin streaming video H.265 β lihat bagian Loop Video H.265 di bawah)
- SQLite3 (sudah termasuk dalam package)
- VPS/Server dengan minimal 1 Core CPU & 1GB RAM
- Port 7575 (dapat disesuaikan di file .env)
Untuk instalasi otomatis, jalankan perintah berikut:
curl -o install.sh https://raw.githubusercontent.com/bangtutorial/streamflow/main/install.sh && chmod +x install.sh && ./install.shUpdate sistem operasi:
sudo apt update && sudo apt upgrade -yInstall Node.js:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejsVerifikasi instalasi Node.js:
node --version
npm --versionInstall FFmpeg:
sudo apt install ffmpeg -yVerifikasi instalasi FFmpeg:
ffmpeg -versionInstall Git:
sudo apt install git -yClone repository:
git clone https://github.com/bangtutorial/streamflowMasuk ke direktori project:
cd streamflowInstall Paket Node.JS:
npm installGenerate Secret Key:
node generate-secret.jsKonfigurasi port (opsional):
nano .envJalankan aplikasi:
npm run devPENTING: Buka port SSH terlebih dahulu untuk menghindari terputusnya koneksi!
Buka port SSH (biasanya port 22):
sudo ufw allow ssh
# atau jika menggunakan port custom SSH
# sudo ufw allow [PORT_SSH_ANDA]Buka port aplikasi (default: 7575):
sudo ufw allow 7575Verifikasi aturan firewall sebelum mengaktifkan:
sudo ufw status verboseAktifkan firewall:
sudo ufw enableVerifikasi status firewall setelah aktif:
sudo ufw statusInstall PM2 untuk mengelola aplikasi:
sudo npm install -g pm2Jalankan aplikasi dengan PM2:
pm2 start app.js --name streamflowSetup Auto-Restart saat Server Reboot:
# Simpan konfigurasi PM2 saat ini
pm2 save
# Setup PM2 untuk auto-start saat server restart
pm2 startup
# Ikuti instruksi yang muncul, biasanya berupa command yang harus dijalankan dengan sudo
# Contoh output: sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u username --hp /home/username
# Setelah menjalankan command startup, save kembali
pm2 savePerintah PM2 Berguna:
# Lihat status aplikasi
pm2 status
# Restart aplikasi
pm2 restart streamflow
# Stop aplikasi
pm2 stop streamflow
# Lihat logs aplikasi
pm2 logs streamflow
# Monitor resource usage
pm2 monitAkses aplikasi melalui browser:
http://IP_SERVER:PORT
Contoh: http://88.12.34.56:7575
Panel Monetization tersedia di form Create/Edit stream (mode YouTube), di form Rotation (berlaku untuk semua item), dan lewat tombol koin pada kartu stream/rotation yang sedang live (Live monetization). Kontrolnya sama dengan Live Control Room YouTube Studio:
| Kontrol | Keterangan |
|---|---|
| Ads on/off | Mengaktifkan iklan pada broadcast (adsMonetizationStatus) |
| Auto ad breaks | YouTube menyisipkan mid-roll otomatis |
| Frequency Low / Medium / High | Frekuensi yang dioptimalkan YouTube |
| Custom interval 6β30 menit | Jeda iklan tetap, serentak untuk semua penonton atau bergantian |
| Delay ads at start | Tunda iklan N menit setelah live mulai |
| Run ad break (30β180 detik) | Sisipkan mid-roll manual saat live berjalan |
Status kelayakan (eligible) dan status iklan yang sebenarnya dibaca langsung dari YouTube di panel Live monetization. Perubahan saat live langsung dikirim ke YouTube; untuk stream yang belum mulai, pengaturan disimpan dan diterapkan saat broadcast dibuat.
Catatan: fitur ini memakai
liveBroadcasts.monetizationDetailsdanliveBroadcasts.insertCuepointdari YouTube Data API v3. Channel harus sudah masuk YouTube Partner Program; kalau tidak, YouTube menolak permintaan dan stream tetap jalan tanpa iklan.
Pilih bahasa (satu per satu, preset, atau semua ~80 bahasa YouTube) di form stream / rotation, atau lewat panel Live monetization β Translate now. Judul dan deskripsi diterjemahkan lalu dikirim ke YouTube sebagai localizations, sehingga penonton melihat judul sesuai bahasa mereka.
Provider diatur di Settings β Integration β Translation Settings:
- Google Cloud Translation API (disarankan): enable Cloud Translation API di Google Cloud Console β buat API key β tempel di Settings β klik Test.
- OpenAI / Gemini (opsional): tetap didukung.
Halaman Translate dipakai untuk menerjemahkan video/live yang sudah ada di channel secara massal.
Di form Create/Edit stream (manual maupun YouTube), aktifkan Enable Schedule, isi Start & End, lalu pilih Repeat: Once, Every day, atau Every week. Setelah stream berakhir di End Time, jadwal digeser otomatis ke hari/minggu berikutnya (durasi sama) dan broadcast YouTube baru dibuat. Stream yang di-stop manual di tengah jendela tidak langsung restart β ia menunggu jadwal berikutnya. Untuk menghentikan permanen, ubah Repeat ke Once atau matikan schedule.
Di form Create/Edit stream YouTube ada field Stream Name (key stream): isi dengan nama yang sama untuk beberapa stream/jadwal ulang dan semuanya berbagi satu key stream YouTube (RTMP url/key) yang sama β persis seperti nama rotation yang otomatis dipakai sebagai nama key stream-nya. Nama baru (atau dikosongkan) = key stream baru dibuat.
Tombol Live Nonstop (ikon β) di form Create/Edit stream (manual maupun YouTube) membuat stream berjalan 24/7: tidak ada Start/End/Repeat, dan kalau FFmpeg crash ia terus di-restart otomatis tanpa batas retry (bukan berhenti setelah 15x percobaan seperti stream biasa). Stream nonstop juga otomatis di-resume kalau server/proses Node-nya di-restart (pm2 restart, deploy, reboot) β broadcast YouTube yang sudah ada dipakai lagi, bukan bikin baru β sehingga siaran 24/7 tidak terputus permanen hanya karena restart. Stream biasa (bukan nonstop) yang sedang live juga otomatis di-resume kalau saat restart ia masih berada di dalam jendela jadwalnya (waktu sekarang < End Time) β hanya stream yang jadwalnya sudah lewat, atau yang tidak punya End Time sama sekali, yang direset ke offline seperti biasa.
Untuk broadcast YouTube, "auto stop"-nya YouTube sendiri dimatikan selama stream nonstop berjalan, dan untuk stream terjadwal juga dimatikan sampai 30 menit sebelum End Time β supaya restart/reconnect sesaat tidak bikin YouTube ikut mengakhiri broadcast-nya secara sepihak. Begitu masuk 30 menit terakhir sebelum End Time, auto stop otomatis dinyalakan lagi sebagai jaring pengaman kalau logika stop kita sendiri gagal. Aplikasi juga mengecek status broadcast lama sebelum dipakai ulang (misal setelah resume) β kalau ternyata sudah di-end dari sisi YouTube (manual di YouTube Studio atau oleh auto stop), broadcast baru otomatis dibuat (key stream/RTMP tetap dipakai ulang bila namanya sama) alih-alih terus mendorong data ke broadcast yang sudah mati.
Di form Create/Edit Playlist, tab Audios, ada panel Audio Mixing. Secara default (toggle mati) audio dari background music yang dipilih akan mengganti total audio asli videonya (perilaku lama). Aktifkan toggle Mix with original audio supaya audio asli video dan background music sama-sama kedengaran β masing-masing punya slider gain sendiri (0%-200%) untuk atur keseimbangan volumenya.
Tombol Preview mix memutar video pertama + audio pertama yang dipilih langsung di browser (pakai Web Audio API, tanpa lewat server/FFmpeg sama sekali) sehingga volumenya langsung berubah real-time begitu slider digeser β jadi bisa diatur dulu by-ear sebelum disimpan. Catatan: kalau video sumbernya memang tidak punya audio track sama sekali, mode mix tidak akan menghasilkan apa-apa dari sisi video itu (tidak ada yang bisa di-mix); pakai mode default (replace) untuk video semacam itu.
Video H.265 butuh bitrate kira-kira setengah dari H.264 untuk kualitas yang sama, jadi bandwidth VPS muat lebih banyak stream sekaligus β dan karena mode default (tanpa Advanced Settings) hanya meng-copy codec, CPU tetap hampir tidak terpakai.
Syarat: FFmpeg 6.1 atau lebih baru. RTMP/FLV klasik tidak bisa membawa HEVC; dukungannya (Enhanced RTMP) baru ada sejak FFmpeg 6.1. Ubuntu 22.04 bawaannya FFmpeg 4.4, jadi pasang build statis terbaru:
sudo bash scripts/install-ffmpeg-static.sh
pm2 restart streamflowScript itu memasang FFmpeg ke /opt/ffmpeg-static dan membuat link di /usr/local/bin tanpa menghapus FFmpeg bawaan apt. Urutan binary yang dipakai aplikasi: FFMPEG_PATH di .env β /usr/local/bin/ffmpeg β /usr/bin/ffmpeg β binary bawaan npm. Versi yang terdeteksi dicetak di log saat aplikasi start (pm2 logs). Stream yang sedang live tetap memakai FFmpeg lama sampai stream itu di-restart.
Di Gallery, setiap video sekarang punya badge codec (H.264 / H.265), terdeteksi otomatis saat upload/import (video lama dianalisis di background saat Gallery dibuka). Badge kuning muncul kalau jarak keyframe lebih dari 4 detik β YouTube minta keyframe tiap 2 detik, dan jarak yang panjang bisa bikin glitch di titik sambungan loop.
Tombol Optimize for loop (ikon β» di tiap video) membuat salinan H.265 yang aman untuk di-loop di mode copy: keyframe tetap tiap 2 detik, closed GOP, tanpa B-frame, 8-bit, audio AAC. Video asli tidak diubah; hasilnya muncul sebagai video baru berjudul <judul> (H.265 loop) dengan badge hijau Loop. Pilihan kualitas: High (CRF 20), Balanced (CRF 23), Smallest file (CRF 26). Encode berjalan di background satu per satu dengan prioritas CPU rendah (nice) supaya stream yang sedang live tidak terganggu, dan bisa dibatalkan dari Gallery. Untuk video panjang prosesnya bisa lama β cukup dilakukan sekali per video.
Pengaman saat start stream (mode copy): kalau videonya H.265 tapi FFmpeg di server masih di bawah 6.1, atau playlist mencampur codec berbeda (misalnya H.264 + H.265), stream langsung ditolak dengan pesan yang jelas β bukan gagal diam-diam lalu retry berulang. Mode Advanced Settings tidak terpengaruh (tetap re-encode ke H.264).
Catatan: YouTube menerima HEVC lewat Enhanced RTMP, tapi tidak semua platform RTMP lain mendukungnya β untuk tujuan selain YouTube, cek dulu dokumentasi platformnya. Image Docker bawaan memakai FFmpeg dari Debian yang belum tentu 6.1+; cek versinya di log saat start.
Settings β Integration β Alert Notifications (khusus admin). Isi token bot Telegram (dari @BotFather) + chat ID, dan/atau URL webhook (n8n, Discord, gateway WhatsApp, dll.), pilih event, lalu klik Send test.
Event yang tersedia: stream berhenti setelah retry habis, FFmpeg crash & restart, stream stale (auto restart), stream gagal start (error YouTube API), stream mulai/berakhir, token channel YouTube expired, monetisasi ditolak YouTube, terjemahan gagal, item rotation gagal, disk hampir penuh (threshold bisa diatur), dan app restart. Alert yang sama tidak dikirim ulang dalam 10 menit.
Token OAuth channel yang di-refresh otomatis oleh Google kini selalu disimpan kembali ke database di semua jalur (rotation, translate, edit stream), sehingga channel tidak lagi "expired" diam-diam. Kalau token benar-benar dicabut, channel ditandai expired dan notifikasi dikirim.
Jika lupa password atau perlu reset akun:
cd streamflow && node reset-password.jsUntuk memastikan scheduled streaming berjalan dengan waktu yang akurat:
timedatectl statustimedatectl list-timezones | grep Asiasudo timedatectl set-timezone Asia/Jakartapm2 restart streamflowBuat file .env di root project:
PORT=7575
SESSION_SECRET=your_random_secret_here
NODE_ENV=developmentdocker-compose up --buildAkses aplikasi: http://localhost:7575
Data akan tersimpan secara otomatis di:
- Database:
db/ - Logs:
logs/ - Upload files:
public/uploads/
docker-compose exec app node reset-password.jschmod -R 755 public/uploads/# Cek proses yang menggunakan port
sudo lsof -i :7575
# Kill proses jika diperlukan
sudo kill -9 <PID># Reset database (PERINGATAN: akan menghapus semua data)
rm db/*.db
# Restart aplikasi untuk membuat database baru
pm2 restart streamflowTidak bisa login:
- Pastikan
NODE_ENV=developmentuntuk akses HTTP - Periksa permission folder:
sudo chmod -R 777 db/ logs/ public/uploads/
- Pastikan
SESSION_SECRETtidak berubah
Production (HTTPS):
- Set
NODE_ENV=production - Akses melalui HTTPS untuk cookie session
Β© 2026 - Bang Tutorial

