nimeet Docs
中文

Media Pull (Input Online Media Stream)

Cloud player lifecycle, playback state derivation, region paths, update/destroy, quota and callbacks.

Version v1.1.0 · Updated 2026-10-26 · revision 1

Media Pull pulls external media streams into a channel ("input online media stream"): you give it a URL (RTMP/FLV/HLS/RTSP) and it appears in the channel as a "player user", which other participants subscribe to exactly like a normal user.

Concepts

ConceptMeaning
playerA pull instance: one source stream → one uid in the channel
uid / accountThe player's identity inside the channel (a numeric uid and an optional account name)
playbackUrlAn address that can be played directly once the pull is established (generated by us, for easier debugging)
idleTimeoutSeconds after which the player is reclaimed when nobody is watching
repeatTimeNumber of loops (0 means play forever)
seekPositionStart position (seconds), used to "start playing from second N"

Creating a player

bash
curl -s -X POST "$NIMEET_API_BASE/cn-shanghai/v1/projects/$APP_ID/cloud-player/players?streamIp=$STREAM_IP" \
  -H "Authorization: Basic $NIMEET_CUSTOMER_BASIC" \
  -H 'Content-Type: application/json' \
  -d '{
    "player": {
      "streamUrl": "https://example.com/media/weekly-intro.m3u8",
      "channelName": "weekly-sync",
      "uid": 30001,
      "name": "intro-video",
      "idleTimeout": 120
    }
  }'

player (required) fields:

FieldTypeDescription
streamUrlstringSource address; the supported protocols are listed under "Supported sources" below
channelNamestringTarget channel
uidintegerThe uid the player uses inside the channel (do not collide with a real user)
accountstring \nullOptional account name
namestring \nullBusiness name
audioOptions / videoOptionsobjectVolume, aspect-ratio scaling / cropping, and so on
idleTimeoutintegerIdle reclamation seconds
playTs / seekPositionintegerStart timestamp / start position
repeatTimeintegerNumber of loops

Lifecycle

OperationEndpoint
CreatePOST /{region}/v1/projects/{appId}/cloud-player/players
Query oneGET /{region}/v1/projects/{appId}/cloud-player/players/{id}
ListGET /v1/projects/{appId}/cloud-player/players (pageSize/pageToken/filter)
UpdatePATCH /{region}/v1/projects/{appId}/cloud-player/players/{id} (can set isPause, seekPosition)
DestroyDELETE /{region}/v1/projects/{appId}/cloud-player/players/{id}

The status is derived from whether the player participant actually exists: running / paused / stopped / failed. It is not an in-memory field that merely "looks like it is playing" — reconcile corrects records that disagree with the media plane.

Supported sources

ProtocolDescription
RTMP / RTMPSLive sources; the lowest latency
HTTP-FLVA common low-latency live distribution format
HLS (m3u8)Works for both on-demand and live; seekPosition is supported for on-demand
RTSPCameras and security devices; sources that require authentication must be converted by you first

streamUrl must be an address the server can reach: internal addresses, loopback addresses, and addresses that require an interactive login cannot be pulled. If you need a test source, create a push stream with the 14-streaming-lifecycle.mjs example first, then feed its playback address to the player.

Controlling playback

bash
# pause / resume
curl -s -X PATCH "$NIMEET_API_BASE/cn-shanghai/v1/projects/$APP_ID/cloud-player/players/$PLAYER_ID?sequence=1" \
  -H "Authorization: Basic $NIMEET_CUSTOMER_BASIC" \
  -H 'Content-Type: application/json' \
  -d '{"player":{"isPause":true}}'

# seek to second 60
curl -s -X PATCH "$NIMEET_API_BASE/cn-shanghai/v1/projects/$APP_ID/cloud-player/players/$PLAYER_ID" \
  -H "Authorization: Basic $NIMEET_CUSTOMER_BASIC" \
  -H 'Content-Type: application/json' \
  -d '{"player":{"seekPosition":60}}'

sequence is optimistic concurrency control: on a concurrent update the stale sequence gets 409; GET the resource again and resubmit.

Relationship with other participants in the channel

  • A player is a participant that only publishes and never subscribes;
  • Real users can subscribe to it normally (the user-published event fires as usual, with mediaType being audio/video);
  • Recording (composite) mixes it into the layout like any other video — which is exactly how you get "intro video + real people" in one stream;
  • Destroying a player is equivalent to that user leaving the channel, and triggers user-left.

Quotas and errors

ScenarioResponse
Service not enabled403 service_not_enabled
Concurrent players exceeded (500)429 streaming_quota_exceeded
Unreachable source addressCreation succeeds, but status turns into a failure state on query and the error field explains why
uid duplicates an existing playerNot rejected (players with the same uid may coexist in practice). Two participants sharing a uid make subscribers unable to tell them apart, so guarantee uniqueness yourself

End-to-end example

bash
node run-all.mjs --only=19

19-media-pull-lifecycle.mjs: create → query → pause → resume → destroy (writes, so it needs --all).

Generated by the documentation build pipeline · 2026-10-31 01:24:02 UTC · Documentation center v1.1.0.

Content follows the public API definitions.

ni-meet is a self-hosted RTC PaaS with a LiveKit-based media plane (Apache-2.0) and an Agora-compatible API.