# Stream a single participant's video By default, Realtime Media Streams (RTMS) sends the video data of the active speaker. If your app needs to track a specific participant, you can switch to individual stream mode. In this mode, you choose which participant's video to receive and can change that selection at any time during the meeting. > **Note** > > Only one individual video stream can be active at a time. Subscribing to a new participant automatically unsubscribes from the previous one. ## Prerequisites Complete the [Working with streams](/docs/rtms/meetings/work-with-streams/) flow through **Step 3: App establishes signaling connection** before configuring individual video streams. ## Step 1: Configure the media handshake request When sending the [media handshake request](/docs/rtms/event-reference/#media-handshake-request), set `data_opt` to `4` (`VIDEO_SINGLE_INDIVIDUAL_STREAM`) in the `video` media parameters. This tells the RTMS server that your app will manage video subscriptions manually rather than receiving the active speaker automatically. ```json { "msg_type": 3, "protocol_version": 1, "meeting_uuid": "your_meeting_uuid", "rtms_stream_id": "your_rtms_stream_id", "signature": "your_signature", "media_type": 2, "media_params": { "video": { "codec": 5, "resolution": 2, "data_opt": 4, "fps": 25 } } } ``` No video data is sent until you subscribe to a participant. ## Step 2: Subscribe to participant video events Once the stream is active, subscribe to `PARTICIPANT_VIDEO_ON` (event type `8`) and `PARTICIPANT_VIDEO_OFF` (event type `9`) events using the [Subscribe to events](/docs/rtms/event-reference/#subscribe-to-events) message. These events tell your app which participants have their cameras on and are available to subscribe to. ```json { "msg_type": 18, "event_type": [8, 9] } ``` ## Step 3: Receive participant video events When a participant turns their camera on, the signaling connection sends a [participant video on](/docs/rtms/event-reference/#participant-video-on) event. Use the `user_id` from this event to send a video subscription request in the next step. ```json { "msg_type": 6, "event": { "event_type": 8, "timestamp": 1727384349123, "participants": [ { "user_id": 16778240 } ] } } ``` When a participant turns their camera off, the signaling connection sends a [participant video off](/docs/rtms/event-reference/#participant-video-off) event. If your app is currently subscribed to that participant, no further video data will arrive until you subscribe to a different participant. ```json { "msg_type": 6, "event": { "event_type": 9, "timestamp": 1727384349123, "participants": [ { "user_id": 16778240 } ] } } ``` ## Step 4: Subscribe to a participant's video stream Send a [video subscription request](/docs/rtms/event-reference/#video-subscription-request) through the signaling connection with the `user_id` of the participant you want to receive video from. Set `subscribe` to `true` to start receiving video from that participant, or `false` to stop. ```json { "msg_type": 28, "user_id": 16778240, "subscribe": true, "timestamp": 1738392033699 } ``` The signaling connection responds with a [video subscription response](/docs/rtms/event-reference/#video-subscription-response). A `status_code` of `0` means the subscription was successful and video data will begin arriving on the media connection. ```json { "msg_type": 29, "user_id": 16778240, "status_code": 0, "reason": "OK", "timestamp": 1738392033699 } ``` ## Step 5: Switch to a different participant To switch the video stream to a different participant, send a new [video subscription request](/docs/rtms/event-reference/#video-subscription-request) with the new participant's `user_id`. You do not need to unsubscribe from the current participant first, the RTMS server handles this automatically when the new subscription request arrives. ```json { "msg_type": 28, "user_id": 98765432, "subscribe": true, "timestamp": 1738392099000 } ``` ## Step 6: Unsubscribe from a participant's video stream To stop receiving video without subscribing to a different participant, send a [video subscription request](/docs/rtms/event-reference/#video-subscription-request) with `subscribe` set to `false`. No video data will be sent until you send a new subscription request. ```json { "msg_type": 28, "user_id": 16778240, "subscribe": false, "timestamp": 1738392099000 } ``` ## Handling video gaps When there is no active individual subscription — such as after a participant turns off their camera or you have explicitly unsubscribed — the RTMS server sends no video data. If your app is recording the meeting for playback, insert filler frames during these gaps when muxing video with audio. Use timestamps from audio packets to determine the duration of each gap. For more information, see [Combining media data](/docs/rtms/meetings/media/#combining-media-data).