DEV Community

Cover image for Live camera streaming APIs compared: web player vs HLS vs RTMP
Imou-OpenPlatform
Imou-OpenPlatform

Posted on

Live camera streaming APIs compared: web player vs HLS vs RTMP

Which API can I use for live camera streaming? On Imou Open Platform there is no single live method. Use getKitToken + ImouPlayer for interactive web player monitoring (preview plus talk/PTZ/playback UI when the device supports those). Use bindDeviceLive when you need an HLS live URL for your own player. Use createDeviceRtmpLive when the consumer is an RTMP pipeline. Always fetch accessToken on the server first. kitToken is not accessToken. Capabilities still depend on the camera and subscribed services.

Why this comparison exists

Tutorials often start with protocol names. Production teams start with surfaces:

  • A SaaS Live tab with controls
  • A gated share page that already runs HLS.js
  • A media server that only speaks RTMP

Pick the API from the surface. Then wire tokens. Then worry about Wasm headers.

Official product context: Video Monitoring. Live overview: Custom live broadcast. Player: JS SDK.

Comparison table

Web player (ImouPlayer) HLS (bindDeviceLive) RTMP (createDeviceRtmpLive)
OpenAPI entry getKitToken bindDeviceLive createDeviceRtmpLive
Client credential Short-lived kitToken Live URL (treat as secret) RTMP address (treat as secret)
Best surface In-product browser / H5 console Custom HLS player, kiosk, partner embed Encoders, media servers, RTMP consumers
Controls Player chrome: live + talk/PTZ/playback if device allows You build chrome; URL is the contract Pipeline, not a SaaS joystick
Latency feel Interactive monitoring UX Segment-based HLS delay is normal Depends on your media stack
Auth mistake Pasting accessToken into the player Publishing the HLS URL in a public ticket Exposing RTMP in frontend config
Effort Host JS + Wasm; correct WasmLibPath / isolation headers Issue URL after ACL; wire HLS.js / native You already have RTMP infra

Cloud live messaging refers to common protocol families (HLS / FLV / RTMP depending on interface and device). Match the method to what the client consumes. Do not invent a “universal WebRTC SKU” here.

streamId: 0 = HD, 1 = SD. Dashboards should default SD.

Path 1 — Web player sequence

User opens Live tab
  → SaaS session + ACL(deviceId)
  → BFF: cached accessToken
  → getKitToken
  → SPA: ImouPlayer.init({ kitToken })
  → on unmount: destroy player
Enter fullscreen mode Exit fullscreen mode

Use when: operators stay in your product and may need talk, PTZ, or in-player playback later. Those features are still capability-gated. The player path does not magically add motors or mics.

Minimal BFF idea:

POST /api/cameras/:id/kit-token
  authorize(user, id)
  token = getKitToken(accessToken, device, channel, ...)
  return { kitToken, expiresHint }
Enter fullscreen mode Exit fullscreen mode

Never return accessToken or appSecret.

Cache kitToken ~1 hour server-side; expect ~2 hour TTL per JS docs—re-mint rather than stretching OpenAPI tokens into the browser.

Path 2 — HLS sequence

User opens share/kiosk (already authenticated to YOUR app)
  → ACL
  → BFF: bindDeviceLive(deviceId, channelId, streamId)
  → return HLS URL to HLS.js / video element
  → on end: unbind / expire according to live object APIs
Enter fullscreen mode Exit fullscreen mode

Docs: bindDeviceLive.

Use when: you standardize on HLS, or a partner player only takes a playlist URL.

Do not use HLS as a substitute for talk. Two-way audio wants an interactive session (ImouPlayer / OpenSDK), not a guess that the .m3u8 includes a mic.

Security: anyone with the URL may watch. Issue only from authenticated BFF routes. Log issuance.

Path 3 — RTMP sequence

Media process needs ingest/playback in RTMP
  → ACL (service account or operator)
  → createDeviceRtmpLive(...)
  → hand address to ffmpeg / media server
  → lifecycle: list/status/unbind as documented
Enter fullscreen mode Exit fullscreen mode

Use when: the next hop is already RTMP. Do not pick RTMP because a blog said “streaming = RTMP,” then try to play it in a random <video> tag.

Shared preamble (all three paths)

  1. Create app, bind devices on open.imoulife.com.
  2. accessToken on BFF — accessToken docs.
  3. listDeviceDetailsByPage for pickers—not hard-coded serials.
  4. Authorize in your ACL.
  5. Mint one of: kitToken / HLS URL / RTMP URL.
  6. Open on demand; tear down on leave.
  7. Watch live-view quota: My Resources.

Native mobile primary clients: OpenSDK is the lane; this article is the three streaming contracts web/backend teams argue about.

Testing each path (without fake latency SLAs)

Web player: Assert the network tab never contains appSecret or a reusable admin accessToken. Force-expire kitToken and confirm the BFF re-mints. Toggle streamId 1→0 on a single tile, not on the wall. If you enable talk or PTZ in QA, use a known-capable device and a known-fixed device so the UI hide-path is tested.

HLS: Confirm the playlist is issued only after your session cookie/JWT. Rotate or unbind and confirm the old URL dies (or is treated as dead in your product). Do not screenshot the .m3u8 into Slack.

RTMP: Keep credentials in the media worker config, not in a public SPA bundle. Verify teardown so you do not leak standing live objects.

FLV: Some live families mention FLV alongside HLS/RTMP depending on interface and device. If your client is not an FLV player, do not pick an FLV-shaped response and hope the browser figures it out. Match client ↔ method.

Error mapping worth doing once

Upstream-ish failure User-visible copy
ACL deny You don’t have access to this camera
Device not in OpenAPI pool Camera isn’t bound to this application
Player given accessToken (Don’t; fix engineering) Black screen
Live object expired / 404 Refresh live session (re-bind / re-kit)
Quota Too many live views; close a tile

Keep raw OpenAPI payloads in server logs.

Quota (qualitative, no fake Mbps)

Every live path can consume live-view (and related) quota. A wall of HD HLS plus a pile of ImouPlayer instances is still N streams. Cap concurrency in the product. Prefer SD on mosaics. No invented latency SLAs in this post—HLS will feel like HLS.

Mixing paths in one product

A pattern that works:

  • Detail page: ImouPlayer (kitToken) for controls.
  • Wall / TV: HLS tiles after the same ACL, SD default.
  • Broadcast tool: RTMP only in that tool.

One BFF rule: authorize → mint matching credential → on-demand open → teardown.

Pitfalls

  • kitTokenaccessToken. Highest-severity footgun for the web player.
  • Prefetch all live objects at login → timeouts / 404s / quota spike. Light App guidance: don’t request stream sources before the slot is active.
  • PTZ/talk/playback assumed on HLS. Those are device + interactive SDK/API features.
  • GB28181 as the international integration story: skip it; use OpenAPI/SDK.
  • SKU fanfic. Capabilities come from the device, not this article.

Decision cheat (30 seconds)

Need talk / PTZ / in-player playback UI in the browser?
  → ImouPlayer + getKitToken

Already have HLS.js / Safari native HLS?
  → bindDeviceLive

ffmpeg / media server wants RTMP?
  → createDeviceRtmpLive

Unsure?
  → ImouPlayer for the primary SaaS Live tab
Enter fullscreen mode Exit fullscreen mode

Register at open.imoulife.com. Imou Open Platform focuses on cloud video and AIoT and provides APIs, SDKs, and low-code components so vendors and developers can ship the right live path faster—web player, HLS, or RTMP—without mixing up play tokens and admin tokens.

Top comments (0)