Placeholder Watermark
During live stream mixing, if the multi-video layout scheme is set to custom mode, the MCU service will display a black screen when it fails to receive a participant's video data. This typically occurs in two scenarios:
- The participant turns off their camera
- The participant stops publishing their video stream
By configuring a placeholder image, the MCU will use the specified image to fill the screen when video data is unavailable. The placeholder is implemented as a watermark (referred to as "placeholder watermark" hereafter), supporting both text and image watermarks. Text watermarks are superimposed above image watermarks.
In custom layout mode for live stream mixing, you can use the placeholder watermark API to:
- Set (or remove) a placeholder image for participants who turn off their cameras
- Set (or remove) a placeholder image for participants who stop publishing video streams
Notes
-
Placeholder watermarks only take effect in custom layout mode. They don't work in floating or adaptive modes.
In floating and adaptive modes, participant views are hidden when cameras are turned off or video streams are unpublished.
-
The placeholder image appears at the same position as defined in the custom layout. For example, if using the Live Stream Mixing API for custom layout, the placeholder will use the last configured coordinates from the
input.video
parameters. -
Placeholder images are proportionally scaled to fill the participant's designated area, with cropping applied if aspect ratios differ.
-
Each placeholder supports up to 10 lines of text and 5 image watermarks.
-
Overlapping rules for placeholder elements (images/text) follow their x, y, w, h coordinates—later elements overlay earlier ones.
-
Text always overlays images—images never overlay text.
Request Method
POST: https://data center domain/v2/rtc/mcu/placehold
Signature Rules: All requests to RC server APIs require authentication. See API Request Signature.
Request Body Parameters
The HTTP request body contains a JSON object with the following structure:
Parameter | Type | Description |
---|---|---|
version | Number | API version. Use the current recommended version: 2 |
sessionId | String | (Required) Session ID. Obtain this from RC server callbacks. See Room Status Callback. |
placehold | String | Object containing layout parameters (details below) |
placehold[i].action | Number | 1 : Set placeholder for participants who turn off cameras2 : Clear camera-off placeholder3 : Set placeholder for unpublished video streams4 : Clear unpublished-stream placeholder |
placehold[i].streamId | String | Video stream ID |
placehold[i].text[i].content | String | Text content |
placehold[i].text[i].fontSize | Number | Font size (px) |
placehold[i].text[i].color | String | Text color (black, white) |
placehold[i].text[i].alpha | Number | Transparency (0.0-1.0) |
placehold[i].text[i].x | Number | X coordinate (0.0-1.0) |
placehold[i].text[i].y | Number | Y coordinate (0.0-1.0) |
placehold[i].picture[i].uri | String | Image URL |
placehold[i].picture[i].w | Number | Width (relative to participant area) |
placehold[i].picture[i].h | Number | Height (relative to participant area) |
placehold[i].picture[i].x | Number | X coordinate (relative to participant area) |
placehold[i].picture[i].y | Number | Y coordinate (relative to participant area) |
JSON Example
{
"version": 2,
"sessionId": "aaa",
"placehold": [{
"action": 2,
"streamId": "stream1_RongCloudRTC",
"text": [{
"alpha": 1,
"color": "white",
"x": 0.1,
"y": 0.2,
"content": "abcde",
"fontSize": 30
},
{
"alpha": 0.2,
"color": "black",
"x": 0.3,
"y": 0.5,
"content": "hello, world",
"fontSize": 20
}
],
"picture": [{
"uri": "https://aaa",
"w": 0.1,
"h": 0.1,
"x": 0.1,
"y": 0.2
},
{
"uri": "https://ccc",
"w": 0.6,
"h": 0.6,
"x": 0.2,
"y": 0.2
}
]
},
{
"action": 3,
"streamId": "stream2_RongCloudRTC",
"text": [{
"alpha": 1,
"color": "white",
"x": 0.1,
"y": 0.2,
"content": "abcde",
"fontSize": 30
},
{
"alpha": 0.2,
"color": "black",
"x": 0.3,
"y": 0.5,
"content": "hello, world",
"fontSize": 20
}
],
"picture": [{
"uri": "https://aaa",
"w": 0.1,
"h": 0.1,
"x": 0.1,
"y": 0.2
},
{
"uri": "https://ccc",
"w": 0.6,
"h": 0.6,
"x": 0.2,
"y": 0.2
}
]
}
]
}
Removing Placeholders
The placeholder watermark API provides two actions to clear settings for specific stream IDs:
- Set
placehold[i].action
to 2: Clear camera-off placeholder - Set
placehold[i].action
to 4: Clear unpublished-stream placeholder
Note: Removing a stream from the mixing list via the Live Stream Mixing API will automatically clear all related placeholder settings for that stream ID.
Workflow Examples
Example 1: Unpublished Stream Scenario
This example demonstrates placeholder behavior when stream3 is published, unpublished, removed from mixing, and re-added:
- Configure custom layout with stream1, stream2, and stream3 (unpublished)
- Set unpublished-stream placeholder for stream3 (action=3)
- Participant publishes stream3 → placeholder disappears
- Participant unpublishes stream3 → placeholder reappears
- Remove stream3 from mixing → placeholder clears
- Re-add stream3 (unpublished) → no placeholder shown (settings were cleared)
- Reset unpublished-stream placeholder for stream3 (action=3) → placeholder appears
- Clear unpublished-stream placeholder (action=4) → placeholder disappears
Example 2: Camera Control Scenario
This example demonstrates placeholder behavior when stream3's camera is repeatedly toggled:
- Configure custom layout with stream1, stream2, and stream3 (published)
- Set camera-off placeholder for stream3 (action=1)
- Participant turns off camera → placeholder appears
- Participant turns on camera → placeholder disappears
- Remove stream3 from mixing → placeholder settings clear
- Re-add stream3 → no placeholder settings exist
- Participant turns off camera → black screen appears (no placeholder)
- Reset camera-off placeholder (action=1) → placeholder appears
- Clear camera-off placeholder (action=2) → placeholder disappears