Nodeflux Central
VoD (Video Upload)

VoD (Video Upload)

Mengunggah file video per chunk dengan resume, menyimpannya dengan waktu rekam nyata, memutarnya ulang sebagai stream, dan mengaksesnya lewat playback berbasis waktu.

Pengenalan

VoD (Video on Demand) membuat Liodra menerima file video yang sudah ada (ekspor CCTV, rekaman drone, bukti dari pihak ketiga) dan memperlakukannya seperti rekaman lain: bisa ditonton, dipotong berdasarkan waktu, dan dijadikan sumber analitik Visionaire. Fitur ini aktif dengan flag --with-vod (ENABLE_VOD=true).

Yang membedakannya dari sekadar file server:

  • Unggah per chunk dengan resume: file sampai MAX_UPLOAD_FILE_SIZE (50 GB) dikirim dalam potongan MAX_UPLOAD_CHUNK_SIZE (1 MB), boleh paralel, dan dapat dilanjutkan setelah koneksi putus.
  • Waktu rekam nyata (started_at): Liodra menebak kapan video direkam (dari nama file, metadata, atau input Anda) agar playback berbasis waktu dan timeline Lenz sejajar dengan kejadian sebenarnya.
  • Autoplay sebagai stream: dengan autoplay=true, video didaftarkan sebagai device file di channel vod dan diputar berulang, sehingga tersedia di RTSP/RTMP/HTTP-TS seperti kamera.

Di Lenz, fitur ini adalah halaman Video Management: unggah (autoplay aktif secara default), pratinjau lewat /play/ts/vod/{id}?transcode=true, koreksi timestamp, dan penugasan analitik offline ke Visionaire.

File disimpan di storage/vods/ bersama file .info (metadata) dan thumbnail JPEG. Channel vod tidak direkam, jadi memutar video sebagai stream tidak menghasilkan rekaman baru.


Cara Menggunakan

Unggah chunk pertama

curl -X POST "http://localhost:9080/api/v1/videos/upload?autoplay=true" \
  -F "file=@part-000.bin" \
  -F "filename=cctv lobby 20260915103000.mp4" \
  -F "chunk_index=0" \
  -F "total_chunks=1200" \
  -F "total_size=1258291200"

Respons berisi session_id dan video_id. Simpan keduanya. Anda juga bisa mengirim started_at (RFC3339) untuk menetapkan waktu rekam secara eksplisit.

Kirim chunk berikutnya

Sertakan session_id pada setiap chunk (chunk_index 1 sampai total_chunks - 1). Urutan bebas dan boleh paralel. Pantau kemajuan dengan GET /api/v1/videos/upload/status/{session_id} (progress, chunks_received, bytes_written).

Lanjutkan bila terputus

curl http://localhost:9080/api/v1/videos/upload/resume/{session_id}

Field missing_chunks menyebutkan indeks yang belum diterima; kirim ulang hanya itu dengan session_id yang sama. Sesi yang tidak diinginkan dibatalkan dengan POST /api/v1/videos/upload/cancel/{session_id}.

Setelah lengkap

Liodra merakit file, membaca durasi dan metadata, membuat thumbnail, lalu (bila autoplay=true) mendaftarkan device vod/{video_id}. Status video berubah uploading → processing → completed. Periksa dengan GET /api/v1/videos/{id}.

Tonton, potong, atau analisis

# tonton sebagai stream berulang (autoplay)
ffplay "http://localhost:9080/api/v1/play/ts/vod/{video_id}"

# ambil 5 menit mulai 10:35 UTC sebagai MP4
curl -o clip.mp4 "http://localhost:9080/api/v1/playbacks/vod/{video_id}?start=2026-09-15T10:35:00Z&duration=300&download=true"

Untuk Visionaire, isi stream_address dengan rtsp://<host-liodra>:8554/vod/{video_id} (atau RTMP dengan ?vhost=vod).


Fitur Utama

Penentuan started_at

Prioritas dari tertinggi ke terendah:

  1. started_at yang dikirim klien saat chunk pertama (started_at_src: original).
  2. Pola tanggal pada nama file sesuai UPLOAD_FILENAME_DATETIME_FORMAT (default YYYYMMDDHHMMSS, mis. cam01_20260915103000.mp4) (filename).
  3. Tanggal encode atau tanggal modifikasi dari metadata container file; nilai epoch atau sebelum tahun 2000 diabaikan (mediainfo).
  4. Tanggal unggah pukul 00:00 UTC.

Nilainya dapat dikoreksi kapan saja dengan PATCH /api/v1/videos/{id} (started_at, opsional started_at_src: manual atau vllm bila berasal dari ekstraksi AI seperti yang dilakukan Lenz dari thumbnail). ended_at dihitung ulang otomatis.

Playback berbasis waktu untuk file

GET /api/v1/playbacks/vod/{id} memakai pola yang sama dengan playback DVR: tanpa parameter mengembalikan satu segmen (start = started_at, duration = durasi video); dengan start + duration mengalirkan MPEG-TS dari offset start - started_at; download=true menghasilkan MP4. start harus berada di dalam started_at..ended_at, kalau tidak ditolak 400. Endpoint daily dan hourly juga tersedia agar komponen date picker dan scrubber yang sama di Lenz dapat dipakai ulang.

Daftar, pencarian, dan paginasi

GET /api/v1/videos mendukung search (parsial pada id dan original_filename), sort_by (original_filename, file_size, duration, started_at, created_at), sort_order, page, dan per_page (0 = semua). Setiap item menyertakan objek device bila video sedang diputar sebagai stream, sehingga status streaming tampil tanpa panggilan tambahan.

Thumbnail

Dibuat otomatis saat unggah: 10 frame pertama diekstrak, frame hitam/seragam/rusak dibuang berdasarkan varian piksel, frame valid pertama diubah ukurannya maksimum 720p dan dikompresi JPEG 80%. GET /api/v1/videos/{id}/thumbnail mengembalikan JPEG (dibuat saat diminta bila belum ada); POST pada path yang sama membuatnya ulang. Video dengan tinggi di atas MAX_UPLOAD_RESOLUTION (4096) mendapat placeholder.

Autoplay dan kendali stream

Device autoplay bernama vod/{video_id} bisa dikelola seperti device lain: POST /api/v1/devices/file/vod/{video_id}/stop untuk menjeda, .../restart untuk melanjutkan, dan muncul di GET /api/v1/devices/file. Menghapus video (DELETE /api/v1/videos/{id}) juga menghapus device, metadata, dan thumbnail-nya.

Batas dan format

BatasDefaultVariabel
Ukuran file50 GBMAX_UPLOAD_FILE_SIZE
Ukuran chunk1 MBMAX_UPLOAD_CHUNK_SIZE
Tinggi maksimum untuk thumbnail4096 pxMAX_UPLOAD_RESOLUTION
Formatmp4, avi, mov, mkv

API Reference

Detail lengkap di API Reference: VoD.

MethodPathFungsi
POST/api/v1/videos/uploadUnggah satu chunk (?autoplay=true)
GET/api/v1/videos/upload/resume/{session_id}Chunk yang masih hilang
GET/api/v1/videos/upload/status/{session_id}Kemajuan unggahan
POST/api/v1/videos/upload/cancel/{session_id}Batalkan sesi
GET/api/v1/videosDaftar video
GET/api/v1/videos/{id}Detail video
PATCH/api/v1/videos/{id}Koreksi started_at
DELETE/api/v1/videos/{id}Hapus video
GET/api/v1/videos/{id}/daily, /hourlyDistribusi untuk date picker dan scrubber
GET / POST/api/v1/videos/{id}/thumbnailAmbil atau buat ulang thumbnail
GET/api/v1/playbacks/vod/{id}Playback berbasis waktu

Tips & Troubleshooting

Selanjutnya

On this page