INTEGRITY Dokumentace

Lokální účastník

Spravujte místní mediální zařízení uživatele, ovládejte zvuk, video a sdílení obrazovky a zpracovávejte události ve schůzkách RealtimeKit.

Úvod

Místní uživatel je přístupný přes meeting.self a obsahuje všechny informace a metody týkající se aktuálního účastníka. Patří sem ovládání médií, správa zařízení, metadata účastníka a informace o stavu.

Vlastnosti

Vlastnosti metadat

Přístup k identifikátorům účastníků a zobrazovaným informacím:

// Participant identifiers
meeting.self.id; // Peer ID (unique per session)
meeting.self.userId; // User ID (persistent across sessions)
meeting.self.customParticipantId; // Custom identifier set by developer
meeting.self.name; // Display name
meeting.self.picture; // Display picture URL
import { useRealtimeKitSelector } from "@cloudflare/realtimekit-react";

// Participant identifiers
const id = useRealtimeKitSelector((m) => m.self.id);
const userId = useRealtimeKitSelector((m) => m.self.userId);
const customParticipantId = useRealtimeKitSelector(
	(m) => m.self.customParticipantId,
);
const name = useRealtimeKitSelector((m) => m.self.name);
const picture = useRealtimeKitSelector((m) => m.self.picture);
// Participant identifiers
meeting.localUser.id // Peer ID (unique per session)
meeting.localUser.userId // User ID (persistent across sessions)
meeting.localUser.customParticipantId // Custom identifier set by developer
meeting.localUser.name // Display name
meeting.localUser.picture // Display picture URL
// Participant identifiers
meeting.localUser.id // Peer ID (unique per session)
meeting.localUser.userId // User ID (persistent across sessions)
meeting.localUser.customParticipantId // Custom identifier set by developer
meeting.localUser.name // Display name
meeting.localUser.picture // Display picture URL
import { useRealtimeKitSelector } from "@cloudflare/realtimekit-react-native";

// Participant identifiers
const id = useRealtimeKitSelector((m) => m.self.id);
const userId = useRealtimeKitSelector((m) => m.self.userId);
const customParticipantId = useRealtimeKitSelector(
	(m) => m.self.customParticipantId,
);
const name = useRealtimeKitSelector((m) => m.self.name);
const picture = useRealtimeKitSelector((m) => m.self.picture);

Vlastnosti médií

Přístup k mediálním trackům a stavům místního uživatele:

// Media state flags
meeting.self.audioEnabled; // Boolean: Is audio enabled?
meeting.self.videoEnabled; // Boolean: Is video enabled?
meeting.self.screenShareEnabled; // Boolean: Is screen share active?

// Media tracks (MediaStreamTrack objects)
meeting.self.audioTrack; // Audio MediaStreamTrack (available when audioEnabled is true)
meeting.self.videoTrack; // Video MediaStreamTrack (available when videoEnabled is true)
meeting.self.screenShareTracks; // Object: { video: MediaStreamTrack, audio?: MediaStreamTrack }

// Permissions granted by user
meeting.self.mediaPermissions; // Current audio/video permissions
// Media state flags
const audioEnabled = useRealtimeKitSelector((m) => m.self.audioEnabled);
const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);
const screenShareEnabled = useRealtimeKitSelector(
	(m) => m.self.screenShareEnabled,
);

// Media tracks (MediaStreamTrack objects)
const audioTrack = useRealtimeKitSelector((m) => m.self.audioTrack);
const videoTrack = useRealtimeKitSelector((m) => m.self.videoTrack);
const screenShareTracks = useRealtimeKitSelector(
	(m) => m.self.screenShareTracks,
);

// Permissions granted by user
const mediaPermissions = useRealtimeKitSelector((m) => m.self.mediaPermissions);
// Media state flags
meeting.localUser.audioEnabled // Boolean: Is audio enabled?
meeting.localUser.videoEnabled // Boolean: Is video enabled?
meeting.localUser.screenShareEnabled // Boolean: Is screen share active?

// Permissions granted by user
meeting.localUser.isCameraPermissionGranted // Camera permission status
meeting.localUser.isMicrophonePermissionGranted // Microphone permission status
// Media state flags
meeting.localUser.audioEnabled // Boolean: Is audio enabled?
meeting.localUser.videoEnabled // Boolean: Is video enabled?
meeting.localUser.screenShareEnabled // Boolean: Is screen share active?

// Permissions granted by user
meeting.localUser.isCameraPermissionGranted // Camera permission status
meeting.localUser.isMicrophonePermissionGranted // Microphone permission status
// Media state flags
const audioEnabled = useRealtimeKitSelector((m) => m.self.audioEnabled);
const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);
const screenShareEnabled = useRealtimeKitSelector(
	(m) => m.self.screenShareEnabled,
);

// Media tracks (MediaStreamTrack objects)
const audioTrack = useRealtimeKitSelector((m) => m.self.audioTrack);
const videoTrack = useRealtimeKitSelector((m) => m.self.videoTrack);
const screenShareTracks = useRealtimeKitSelector(
	(m) => m.self.screenShareTracks,
);

// Permissions granted by user
const mediaPermissions = useRealtimeKitSelector((m) => m.self.mediaPermissions);

Vlastnosti stavu

Přístup ke stavu místnosti a stavu účastníka:

// Room state
meeting.self.roomJoined; // Boolean: Has joined the meeting?
meeting.self.roomState; // Current room state (see possible values below)
meeting.self.isPinned; // Boolean: Is the local user pinned?

// Permissions and config
meeting.self.permissions; // Capabilities defined by preset
meeting.self.config; // Configuration for meeting appearance

Hodnoty stavu místnosti:

// Room state
const roomJoined = useRealtimeKitSelector((m) => m.self.roomJoined);
const roomState = useRealtimeKitSelector((m) => m.self.roomState);
const isPinned = useRealtimeKitSelector((m) => m.self.isPinned);

// Permissions and config
const permissions = useRealtimeKitSelector((m) => m.self.permissions);
const config = useRealtimeKitSelector((m) => m.self.config);

Příklad: Podmíněné vykreslování na základě stavu místnosti

const roomState = useRealtimeKitSelector((m) => m.self.roomState);

return (
	<>
		{roomState === "disconnected" && <div>You are disconnected</div>}
		{roomState === "waitlisted" && <div>Waiting for host to admit you</div>}
		{roomState === "joined" && <div>You are in the meeting</div>}
	</>
);

Hodnoty stavu místnosti:

// Room state
meeting.localUser.roomJoined // Boolean: Has joined the meeting?
meeting.localUser.waitListStatus // Waitlist status (None, Waiting, Accepted, Rejected)
meeting.localUser.isPinned // Boolean: Is the local user pinned?

// Permissions and config
meeting.localUser.permissions // Capabilities defined by preset
meeting.localUser.presetName // Name of preset for local user
meeting.localUser.presetInfo // Typed object representing preset information
// Room state
meeting.localUser.roomJoined // Boolean: Has joined the meeting?
meeting.localUser.waitListStatus // Waitlist status (None, Waiting, Accepted, Rejected)
meeting.localUser.isPinned // Boolean: Is the local user pinned?

// Permissions and config
meeting.localUser.permissions // Capabilities defined by preset
meeting.localUser.presetName // Name of preset for local user
meeting.localUser.presetInfo // Typed object representing preset information
// Room state
const roomJoined = useRealtimeKitSelector((m) => m.self.roomJoined);
const roomState = useRealtimeKitSelector((m) => m.self.roomState);
const isPinned = useRealtimeKitSelector((m) => m.self.isPinned);

// Permissions and config
const permissions = useRealtimeKitSelector((m) => m.self.permissions);
const config = useRealtimeKitSelector((m) => m.self.config);

Příklad: Podmíněné vykreslování na základě stavu místnosti

const roomState = useRealtimeKitSelector((m) => m.self.roomState);

return (
	<>
		{roomState === "disconnected" && <Text>You are disconnected</Text>}
		{roomState === "waitlisted" && <Text>Waiting for host to admit you</Text>}
		{roomState === "joined" && <Text>You are in the meeting</Text>}
	</>
);

Hodnoty stavu místnosti:

Ovládací prvky médií

Ovládání zvuku

Ztlumení a zapnutí mikrofonu:

// Enable audio (unmute)
await meeting.self.enableAudio();

// Disable audio (mute)
await meeting.self.disableAudio();

// Check current status
const isAudioEnabled = meeting.self.audioEnabled;
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";

function AudioControls() {
	const [meeting] = useRealtimeKitClient();
	const audioEnabled = useRealtimeKitSelector((m) => m.self.audioEnabled);

	const toggleAudio = async () => {
		if (audioEnabled) {
			await meeting.self.disableAudio();
		} else {
			await meeting.self.enableAudio();
		}
	};

	return (
		<button onClick={toggleAudio}>{audioEnabled ? "Mute" : "Unmute"}</button>
	);
}
// Enable audio (unmute)
meeting.localUser.enableAudio { error: AudioError? -> }

// Disable audio (mute)
meeting.localUser.disableAudio { error: AudioError? -> }

// Check current status
val isAudioEnabled = meeting.localUser.audioEnabled
// Enable audio (unmute)
meeting.localUser.enableAudio { err in }

// Disable audio (mute)
meeting.localUser.disableAudio { err in }

// Check current status
let isAudioEnabled = meeting.localUser.audioEnabled
import {
	useRealtimeKitClient,
	useRealtimeKitSelector,
} from "@cloudflare/realtimekit-react-native";
import { TouchableHighlight, Text } from "react-native";

function AudioControls() {
	const [meeting] = useRealtimeKitClient();
	const audioEnabled = useRealtimeKitSelector((m) => m.self.audioEnabled);

	const toggleAudio = async () => {
		if (audioEnabled) {
			await meeting.self.disableAudio();
		} else {
			await meeting.self.enableAudio();
		}
	};

	return (
		<TouchableHighlight onPress={toggleAudio}>
			<Text>{audioEnabled ? "Mute" : "Unmute"}</Text>
		</TouchableHighlight>
	);
}

Ovládání videa

Zapnutí a vypnutí kamery:

// Enable video
await meeting.self.enableVideo();

// Disable video
await meeting.self.disableVideo();

// Check current status
const isVideoEnabled = meeting.self.videoEnabled;
function VideoControls() {
	const [meeting] = useRealtimeKitClient();
	const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);

	const toggleVideo = async () => {
		if (videoEnabled) {
			await meeting.self.disableVideo();
		} else {
			await meeting.self.enableVideo();
		}
	};

	return (
		<button onClick={toggleVideo}>
			{videoEnabled ? "Stop Video" : "Start Video"}
		</button>
	);
}
// Enable video
meeting.localUser.enableVideo { error: VideoError? -> }

// Disable video
meeting.localUser.disableVideo { error: VideoError? -> }

// Check current status
val isVideoEnabled = meeting.localUser.videoEnabled
// Enable video
meeting.localUser.enableVideo { err in }

// Disable video
meeting.localUser.disableVideo { err in }

// Check current status
let isVideoEnabled = meeting.localUser.videoEnabled
function VideoControls() {
	const [meeting] = useRealtimeKitClient();
	const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);

	const toggleVideo = async () => {
		if (videoEnabled) {
			await meeting.self.disableVideo();
		} else {
			await meeting.self.enableVideo();
		}
	};

	return (
		<TouchableHighlight onPress={toggleVideo}>
			<Text>{videoEnabled ? "Stop Video" : "Start Video"}</Text>
		</TouchableHighlight>
	);
}

Ovládání sdílení obrazovky

Spuštění a zastavení sdílení obrazovky:

// Enable screen share
await meeting.self.enableScreenShare();

// Disable screen share
await meeting.self.disableScreenShare();

// Check current status
const isScreenShareEnabled = meeting.self.screenShareEnabled;
function ScreenShareControls() {
	const [meeting] = useRealtimeKitClient();
	const screenShareEnabled = useRealtimeKitSelector(
		(m) => m.self.screenShareEnabled,
	);

	const toggleScreenShare = async () => {
		if (screenShareEnabled) {
			await meeting.self.disableScreenShare();
		} else {
			await meeting.self.enableScreenShare();
		}
	};

	return (
		<button onClick={toggleScreenShare}>
			{screenShareEnabled ? "Stop Sharing" : "Share Screen"}
		</button>
	);
}
// Enable screen share
meeting.localUser.enableScreenShare()

// Disable screen share
meeting.localUser.disableScreenShare()

// Check current status
val isScreenShareEnabled = meeting.localUser.screenShareEnabled
// Enable screen share
let err: ScreenShareError? = meeting.localUser.enableScreenShare()

// Disable screen share
meeting.localUser.disableScreenShare()

Viz Nastavení sdílení obrazovky (iOS) sekci s konfigurací specifickou pro danou platformu.

function ScreenShareControls() {
	const [meeting] = useRealtimeKitClient();
	const screenShareEnabled = useRealtimeKitSelector(
		(m) => m.self.screenShareEnabled,
	);

	const toggleScreenShare = async () => {
		if (screenShareEnabled) {
			await meeting.self.disableScreenShare();
		} else {
			await meeting.self.enableScreenShare();
		}
	};

	return (
		<TouchableHighlight onPress={toggleScreenShare}>
			<Text>{screenShareEnabled ? "Stop Sharing" : "Share Screen"}</Text>
		</TouchableHighlight>
	);
}

Změnit zobrazované jméno

Aktualizujte zobrazované jméno před připojením ke schůzce:

await meeting.self.setName("New Name");
await meeting.self.setName("New Name");
meeting.localUser.setDisplayName("New Name")
meeting.localUser.setDisplayName(name: "New Name")
await meeting.self.setName("New Name");

Správa mediálních zařízení

Získání dostupných zařízení

// Get all media devices
const devices = await meeting.self.getAllDevices();

// Get all audio input devices (microphones)
const audioDevices = await meeting.self.getAudioDevices();

// Get all video input devices (cameras)
const videoDevices = await meeting.self.getVideoDevices();

// Get all audio output devices (speakers)
const speakerDevices = await meeting.self.getSpeakerDevices();

// Get device by ID
const device = await meeting.self.getDeviceById("device-id", "audio");

// Get current devices being used
const currentDevices = meeting.self.getCurrentDevices();
// Returns: { audio: MediaDeviceInfo, video: MediaDeviceInfo, speaker: MediaDeviceInfo }
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
import { useState, useEffect } from "react";

function DeviceSelector() {
	const [meeting] = useRealtimeKitClient();
	const [audioDevices, setAudioDevices] = useState([]);
	const [videoDevices, setVideoDevices] = useState([]);

	useEffect(() => {
		if (!meeting) return;

		const loadDevices = async () => {
			const audio = await meeting.self.getAudioDevices();
			const video = await meeting.self.getVideoDevices();
			setAudioDevices(audio);
			setVideoDevices(video);
		};

		loadDevices();
	}, [meeting]);

	const handleDeviceChange = async (device) => {
		await meeting.self.setDevice(device);
	};

	return (
		<div>
			<select
				onChange={(e) => {
					const device = audioDevices.find(
						(d) => d.deviceId === e.target.value,
					);
					handleDeviceChange(device);
				}}
			>
				{audioDevices.map((device) => (
					<option key={device.deviceId} value={device.deviceId}>
						{device.label}
					</option>
				))}
			</select>
		</div>
	);
}

Získání aktuálně používaných zařízení:

const currentDevices = meeting.self.getCurrentDevices();
// Returns: { audio: MediaDeviceInfo, video: MediaDeviceInfo, speaker: MediaDeviceInfo }
// Get all audio devices
val audioDevices: List<AudioDevice> = meeting.localUser.getAudioDevices()

// Get all video devices
val videoDevices: List<VideoDevice> = meeting.localUser.getVideoDevices()

// Get currently selected audio device
val selectedAudioDevice: AudioDevice = meeting.localUser.getSelectedAudioDevice()

// Get currently selected video device
val selectedVideoDevice: VideoDevice = meeting.localUser.getSelectedVideoDevice()
// Get all audio devices
let audioDevices = meeting.localUser.getAudioDevices()

// Get all video devices
let videoDevices = meeting.localUser.getVideoDevices()

// Get currently selected audio device
let selectedAudioDevice = meeting.localUser.getSelectedAudioDevice()

// Get currently selected video device
let selectedVideoDevice = meeting.localUser.getSelectedVideoDevice()
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react-native";
import { useState, useEffect } from "react";
import { FlatList, TouchableHighlight, Text, View } from "react-native";

function DeviceSelector() {
	const [meeting] = useRealtimeKitClient();
	const [audioDevices, setAudioDevices] = useState([]);
	const [videoDevices, setVideoDevices] = useState([]);

	useEffect(() => {
		if (!meeting) return;

		const loadDevices = async () => {
			const audio = await meeting.self.getAudioDevices();
			const video = await meeting.self.getVideoDevices();
			setAudioDevices(audio);
			setVideoDevices(video);
		};

		loadDevices();
	}, [meeting]);

	const handleDeviceChange = async (device) => {
		await meeting.self.setDevice(device);
	};

	return (
		<View>
			<FlatList
				data={audioDevices}
				renderItem={({ item }) => (
					<TouchableHighlight onPress={() => handleDeviceChange(item)}>
						<Text>{item.label}</Text>
					</TouchableHighlight>
				)}
				keyExtractor={(item) => item.deviceId}
			/>
		</View>
	);
}

Získání aktuálně používaných zařízení:

const currentDevices = meeting.self.getCurrentDevices();
// Returns: { audio: MediaDeviceInfo, video: MediaDeviceInfo, speaker: MediaDeviceInfo }

Změnit zařízení

Přepnout na jiné mediální zařízení:

// Get all devices
const devices = await meeting.self.getAllDevices();

// Set a specific device (replaces device of the same kind)
await meeting.self.setDevice(devices[0]);

Použijte příklad selektoru zařízení z předchozí sekce. handleDeviceChange funkce ukazuje, jak přepínat zařízení.

// Get all audio devices
val audioDevices = meeting.localUser.getAudioDevices()

// Set audio device
meeting.localUser.setAudioDevice(audioDevices[0])

// Get all video devices
val videoDevices = meeting.localUser.getVideoDevices()

// Set video device
meeting.localUser.setVideoDevice(videoDevices[0])

// Switch between front and back camera on devices with 2 cameras
meeting.localUser.switchCamera()
// Set audio device
meeting.localUser.setAudioDevice(device)

// Set video device
meeting.localUser.setVideoDevice(videoDevice: device)

// Switch between front and back camera
meeting.localUser.switchCamera()

Použijte příklad selektoru zařízení z předchozí sekce. handleDeviceChange funkce ukazuje, jak přepínat zařízení.

const handleDeviceChange = async (device) => {
	await meeting.self.setDevice(device);
};

Zobrazení lokálního videa

Registrace video prvku

Připojte místní video track k <video> element:

<video id="local-video" autoplay playsinline></video>
const videoElement = document.getElementById("local-video");

// Register the video element to display video
meeting.self.registerVideoElement(videoElement);

// For local preview (not sent to other users), pass true as second argument
meeting.self.registerVideoElement(videoElement, true);

Zrušení registrace video prvku

Odeberte video prvek, jakmile již není potřeba:

meeting.self.deregisterVideoElement(videoElement);

Použijte komponentu UI Kit

Zobrazte místní video pomocí komponenty video dlaždice z UI Kit:

import { RtkParticipantTile } from "@cloudflare/realtimekit-react-ui";
import { useRealtimeKitSelector } from "@cloudflare/realtimekit-react";

function LocalVideo() {
	const localUser = useRealtimeKitSelector((m) => m.self);

	return <RtkParticipantTile participant={localUser} />;
}

Ruční správa video elementu

Vytvoření vlastních implementací video prvku:

import {
	useRealtimeKitClient,
	useRealtimeKitSelector,
} from "@cloudflare/realtimekit-react";
import { useEffect, useRef } from "react";

function LocalVideoCustom() {
	const [meeting] = useRealtimeKitClient();
	const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);
	const videoTrack = useRealtimeKitSelector((m) => m.self.videoTrack);
	const videoRef = useRef(null);

	useEffect(() => {
		if (!videoRef.current || !meeting) return;

		// Register video element
		meeting.self.registerVideoElement(videoRef.current);

		return () => {
			// Cleanup: deregister on unmount
			meeting.self.deregisterVideoElement(videoRef.current);
		};
	}, [meeting]);

	return (
		<video
			ref={videoRef}
			autoPlay
			playsInline
			muted
			style={{ display: videoEnabled ? "block" : "none" }}
		/>
	);
}

Získání zobrazení videa

Načtěte zobrazení náhledu vlastního videa, které vykresluje stream místní kamery:

// Get the self-preview video view
val videoView = meeting.localUser.getSelfPreview()

Pro vykreslování videa ostatních účastníků použijte:

// Get video view for camera stream
val participantVideoView = participant.getVideoView()

// Get video view for screenshare stream
val screenshareView = participant.getScreenShareVideoView()

Správa životního cyklu

Řiďte vykreslování videa pomocí metod životního cyklu:

// Start rendering video
videoView.renderVideo()

// Stop rendering video (but keep the view)
videoView.stopVideoRender()

// Release native resources when done
videoView.release()

Kompletní příklad

import android.os.Bundle
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import io.dyte.core.VideoView

class MainActivity : AppCompatActivity() {
    private lateinit var videoView: VideoView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Get the self-preview video view
        videoView = meeting.localUser.getSelfPreview()

        // Add to your layout
        val container = findViewById<FrameLayout>(R.id.video_container)
        container.addView(videoView)

        // Start rendering
        videoView.renderVideo()
    }

    override fun onPause() {
        super.onPause()
        // Stop rendering when activity is paused
        videoView.stopVideoRender()
    }

    override fun onResume() {
        super.onResume()
        // Resume rendering when activity is resumed
        videoView.renderVideo()
    }

    override fun onDestroy() {
        super.onDestroy()
        // Clean up resources
        videoView.release()
    }
}

Získání zobrazení videa

Načtěte zobrazení videí, která vykreslují video streamy účastníků:

// Get video view for local camera stream
let videoView = meeting.localUser.getVideoView()

// Get video view for screenshare stream
let screenshareView = meeting.localUser.getScreenShareVideoView()

Správa životního cyklu

UIView automaticky spravuje vlastní životní cyklus a při opuštění aktuálního okna uvolní nativní prostředky. Ruční úklid není potřeba.

Příklad

import UIKit
import RealtimeKit

class VideoViewController: UIViewController {
    private var videoView: UIView?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Get the video view for local camera
        videoView = meeting.localUser.getVideoView()

        // Add to your view hierarchy
        if let videoView = videoView {
            videoView.frame = view.bounds
            videoView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            view.addSubview(videoView)
        }
    }
}

Pro sdílení obrazovky:

// Get and display screenshare view
let screenshareView = meeting.localUser.getScreenShareVideoView()
if let screenshareView = screenshareView {
    screenshareView.frame = view.bounds
    screenshareView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.addSubview(screenshareView)
}
import React from "react";
import { useRealtimeKitSelector } from "@cloudflare/realtimekit-react-native";
import { MediaStream, RTCView } from "@cloudflare/react-native-webrtc";

export default function VideoView() {
	const { videoTrack } = useRealtimeKitSelector(
		(m) => m.participants.active,
	).toArray()[0];
	const stream = new MediaStream(undefined);
	stream.addTrack(videoTrack);
	return (
		<RTCView
			objectFit={"cover"}
			style={{ flex: 1 }}
			streamURL={stream.toURL()}
			mirror={true}
			zOrder={1}
		/>
	);
}

Nastavení sdílení obrazovky (iOS)

Přidání rozšíření Broadcast Upload Extension

V Xcode přidejte Broadcast Upload Extension prostřednictvím FileNewTarget. Vyberte iOSBroadcast Upload Extension a vyplňte požadované informace.

Konfigurovat skupiny aplikací

Přidejte své rozšíření do app group:

  1. Přejděte na target svého rozšíření v projektu
  2. Na kartě Signings & Capabilities klikněte na tlačítko + vlevo nahoře
  3. Add App Groups
  4. Přidejte App Groups také do své hlavní aplikace a zajistěte, aby byl identifikátor App Group u obou stejný

Konfigurovat SampleHandler

Upravte svou třídu SampleHandler:

import RealtimeKit

class SampleHandler: RtkSampleHandler {}

Aktualizace Info.plist

Zajistěte, že obě Soubory Info.plist aplikace a rozšíření obsahují tyto klíče:

<key>RTKRTCAppGroupIdentifier</key>
<string>(name of the group you have created)</string>

Přidejte tento klíč do souboru Info.plist hlavní aplikace:

<key>RTKRTCScreenSharingExtension</key>
<string>(Bundle Identifier of the Broadcast upload extension)</string>

Povolit sdílení obrazovky

Spusťte rozšíření pro vysílání a povolte sdílení obrazovky:

meeting.localUser.enableScreenShare()

Chcete-li ukončit sdílení obrazovky:

meeting.localUser.disableScreenShare()

Přidání rozšíření Broadcast Upload Extension

V Xcode přidejte Broadcast Upload Extension prostřednictvím FileNewTarget. Vyberte iOSBroadcast Upload Extension a vyplňte požadované informace.

Konfigurovat skupiny aplikací

Přidejte své rozšíření do app group:

  1. Přejděte na target svého rozšíření v projektu.
  2. V Signing & Capabilities kartě klikněte na + a přidejte App Groups.
  3. Přidejte stejnou App Group do hlavního cíle aplikace (main app target) a pro oba použijte stejný identifikátor.

Přidání zdrojů sdílení obrazovky přes Podfile

SDK obsahuje pomocný skript v Ruby, který přidá potřebné zdrojové soubory Swift pro sdílení obrazovky přímo do cíle Broadcast Upload Extension. Přidejte následující do svého Podfile:

# Add this line at the top
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "@cloudflare/realtimekit-react-native/ios/scripts/screenshare_sources.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

target 'YourApp' do
  ...
  post_install do |installer|
    ...
	  # Add this line here
    add_screenshare_sources(
      installer,
      project_name: 'YourApp',              # your Xcode project name (without .xcodeproj)
      extension_target_name: 'YourAppScreenshare' # your Broadcast Upload Extension target name
    )
	  ...
  end
end

target 'YourAppScreenshare' do
# Remove the old steps added if any
end

Poté spusťte:

pod install

Konfigurovat SampleHandler

Ve svém Broadcast Upload Extension upravte SampleHandler.swift:

class SampleHandler: RTKScreenshareHandler {
  override init() {
    super.init(
      appGroupIdentifier: "<YOUR_APP_GROUP_IDENTIFIER>",
      bundleIdentifier: "<YOUR_APP_BUNDLE_IDENTIFIER>"
    )
  }
}

Nahraďte <YOUR_APP_GROUP_IDENTIFIER> se skupinou App Group, kterou jste vytvořili (například group.com.yourcompany.yourapp) a <YOUR_APP_BUNDLE_IDENTIFIER> s bundle identifier vaší hlavní aplikace.

Aktualizace Info.plist

Přidejte následující klíč do obě vaše hlavní aplikace a rozšíření Info.plist soubory:

<key>RTCAppGroupIdentifier</key>
<string>(YOUR_APP_GROUP_IDENTIFIER)</string>

Přidejte tento klíč do hlavní aplikace Info.plist pouze:

<key>RTCAppScreenSharingExtension</key>
<string>(Bundle Identifier of the Broadcast upload extension)</string>

Povolit sdílení obrazovky

meeting.self.enableScreenShare();

Chcete-li ukončit sdílení obrazovky:

meeting.self.disableScreenShare();

Události

Připojeno k místnosti

Spustí se, když se místní uživatel připojí ke schůzce:

meeting.self.on("roomJoined", () => {
	console.log("Successfully joined the meeting");
});
const roomJoined = useRealtimeKitSelector((m) => m.self.roomJoined);

useEffect(() => {
	if (roomJoined) {
		console.log("Successfully joined the meeting");
	}
}, [roomJoined]);

Nebo použijte posluchač událostí:

useEffect(() => {
	if (!meeting) return;

	const handleRoomJoined = () => {
		console.log("Successfully joined the meeting");
	};

	meeting.self.on("roomJoined", handleRoomJoined);

	return () => {
		meeting.self.off("roomJoined", handleRoomJoined);
	};
}, [meeting]);

Android SDK používá jiný model událostí. Sledujte roomJoined vlastnost změní, nebo použijte posluchače pro změny stavu.

iOS SDK používá jiný model událostí. Sledujte roomJoined vlastnost změní, nebo použijte posluchače pro změny stavu.

const roomJoined = useRealtimeKitSelector((m) => m.self.roomJoined);

useEffect(() => {
	if (roomJoined) {
		console.log("Successfully joined the meeting");
	}
}, [roomJoined]);

Nebo použijte posluchač událostí:

useEffect(() => {
	if (!meeting) return;

	const handleRoomJoined = () => {
		console.log("Successfully joined the meeting");
	};

	meeting.self.on("roomJoined", handleRoomJoined);

	return () => {
		meeting.self.off("roomJoined", handleRoomJoined);
	};
}, [meeting]);

Odpojeno od místnosti

Spustí se, když místní uživatel opustí schůzku:

meeting.self.on("roomLeft", ({ state }) => {
	console.log("Left the meeting with state:", state);

	// Handle different leave states
	if (state === "left") {
		console.log("User voluntarily left");
	} else if (state === "kicked") {
		console.log("User was kicked from the meeting");
	} else if (state === "ended") {
		console.log("Meeting has ended");
	} else if (state === "disconnected") {
		console.log("Lost connection to meeting");
	}
});

Možné hodnoty stavu: 'left', 'kicked', 'ended', 'rejected', 'disconnected', 'failed'

const roomJoined = useRealtimeKitSelector((m) => m.self.roomJoined);

useEffect(() => {
	if (!roomJoined) {
		console.log("Left the meeting");
	}
}, [roomJoined]);

Nebo pro podrobný stav použijte posluchač událostí:

meeting.self.on("roomLeft", ({ state }) => {
	if (state === "left") {
		console.log("User voluntarily left");
	} else if (state === "kicked") {
		console.log("User was kicked");
	}
});

Použijte RtkSelfEventListener a sledovat tak, kdy je místní uživatel odebrán ze schůzky:

meeting.addSelfEventListener(object : RtkSelfEventListener {
    override fun onRemovedFromMeeting() {
        // display alert that user is no longer in the meeting
    }
})

iOS SDK používá jiný model událostí. Sledujte roomJoined vlastnost změní, nebo použijte posluchače pro změny stavu.

const roomJoined = useRealtimeKitSelector((m) => m.self.roomJoined);

useEffect(() => {
	if (!roomJoined) {
		console.log("Left the meeting");
	}
}, [roomJoined]);

Nebo pro podrobný stav použijte posluchač událostí:

meeting.self.on("roomLeft", ({ state }) => {
	if (state === "left") {
		console.log("User voluntarily left");
	} else if (state === "kicked") {
		console.log("User was kicked");
	}
});

Aktualizace videa

Spustí se při zapnutí nebo vypnutí videa:

meeting.self.on("videoUpdate", ({ videoEnabled, videoTrack }) => {
	console.log("Video state:", videoEnabled);

	if (videoEnabled) {
		// Video track is available, can display it
		const videoElement = document.getElementById("my-video");
		const stream = new MediaStream();
		stream.addTrack(videoTrack);
		videoElement.srcObject = stream;
		videoElement.play();
	}
});
const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);
const videoTrack = useRealtimeKitSelector((m) => m.self.videoTrack);

useEffect(() => {
	if (videoEnabled && videoTrack) {
		console.log("Video is enabled");
		// Handle video track
	}
}, [videoEnabled, videoTrack]);
meeting.addSelfEventListener(object : RtkSelfEventListener {
    override fun onVideoUpdate(isEnabled: Boolean) {
        if (isEnabled) {
            // video is enabled, other participants can see local user
        } else {
            // video is disabled, other participants cannot see local user
        }
    }
})
extension MeetingViewModel: RtkSelfEventListener {
    func onVideoUpdate(isEnabled: Bool) {
        if (isEnabled) {
            // video is enabled, other participants can see local user
        } else {
            // video is disabled, other participants cannot see local user
        }
    }
}
const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);
const videoTrack = useRealtimeKitSelector((m) => m.self.videoTrack);

useEffect(() => {
	if (videoEnabled && videoTrack) {
		console.log("Video is enabled");
		// Handle video track
	}
}, [videoEnabled, videoTrack]);

Aktualizace zvuku

Spustí se při zapnutí nebo vypnutí zvuku:

meeting.self.on("audioUpdate", ({ audioEnabled, audioTrack }) => {
	console.log("Audio state:", audioEnabled);

	if (audioEnabled) {
		// Audio track is available
		console.log("Microphone is on");
	}
});
const audioEnabled = useRealtimeKitSelector((m) => m.self.audioEnabled);
const audioTrack = useRealtimeKitSelector((m) => m.self.audioTrack);

useEffect(() => {
	if (audioEnabled && audioTrack) {
		console.log("Audio is enabled");
		// Handle audio track
	}
}, [audioEnabled, audioTrack]);
meeting.addSelfEventListener(object : RtkSelfEventListener {
    override fun onAudioUpdate(isEnabled: Boolean) {
        if (isEnabled) {
            // audio is enabled, other participants can hear local user
        } else {
            // audio is disabled, other participants cannot hear local user
        }
    }
})
extension MeetingViewModel: RtkSelfEventListener {
    func onAudioUpdate(isEnabled: Bool) {
        if (isEnabled) {
            // audio is enabled, other participants can hear local user
        } else {
            // audio is disabled, other participants cannot hear local user
        }
    }
}
const audioEnabled = useRealtimeKitSelector((m) => m.self.audioEnabled);
const audioTrack = useRealtimeKitSelector((m) => m.self.audioTrack);

useEffect(() => {
	if (audioEnabled && audioTrack) {
		console.log("Audio is enabled");
		// Handle audio track
	}
}, [audioEnabled, audioTrack]);

Aktualizace sdílení obrazovky

Spustí se při zahájení nebo ukončení sdílení obrazovky:

meeting.self.on(
	"screenShareUpdate",
	({ screenShareEnabled, screenShareTracks }) => {
		console.log("Screen share state:", screenShareEnabled);

		if (screenShareEnabled) {
			// Screen share tracks are available
			const screenElement = document.getElementById("my-screen-share");
			const stream = new MediaStream();
			stream.addTrack(screenShareTracks.video);
			if (screenShareTracks.audio) {
				stream.addTrack(screenShareTracks.audio);
			}
			screenElement.srcObject = stream;
			screenElement.play();
		}
	},
);
const screenShareEnabled = useRealtimeKitSelector(
	(m) => m.self.screenShareEnabled,
);
const screenShareTracks = useRealtimeKitSelector(
	(m) => m.self.screenShareTracks,
);

useEffect(() => {
	if (screenShareEnabled && screenShareTracks) {
		console.log("Screen sharing is active");
		// Handle screen share tracks
	}
}, [screenShareEnabled, screenShareTracks]);
meeting.addSelfEventListener(object : RtkSelfEventListener {
    override fun onScreenShareStartFailed(reason: String) {
        // screen share failed to start
    }

    override fun onScreenShareUpdate(isEnabled: Boolean) {
        if (isEnabled) {
            // screen share is enabled
        } else {
            // screen share is disabled
        }
    }
})
meeting.addSelfEventListener(self)

extension MeetingViewModel: RtkSelfEventListener {
    func onRemovedFromMeeting() {
        // User was removed from the meeting (kicked or meeting ended)
        // Display alert or navigate to exit screen
    }

    func onMeetingRoomDisconnected() {
        // Lost connection to the meeting room
        // Display reconnection UI or error message
    }
}

Můžete také sledovat roomJoined vlastnost pro změny stavu:

let isInMeeting = meeting.localUser.roomJoined
const screenShareEnabled = useRealtimeKitSelector(
	(m) => m.self.screenShareEnabled,
);
const screenShareTracks = useRealtimeKitSelector(
	(m) => m.self.screenShareTracks,
);

useEffect(() => {
	if (screenShareEnabled && screenShareTracks) {
		console.log("Screen sharing is active");
		// Handle screen share tracks
	}
}, [screenShareEnabled, screenShareTracks]);

Aktualizace zařízení

Spustí se při změně aktivního zařízení:

meeting.self.on("deviceUpdate", ({ device }) => {
	// Handle device change
	if (device.kind === "audioinput") {
		console.log("Microphone changed:", device.label);
	} else if (device.kind === "videoinput") {
		console.log("Camera changed:", device.label);
	} else if (device.kind === "audiooutput") {
		console.log("Speaker changed:", device.label);
	}
});
useEffect(() => {
	if (!meeting) return;

	const handleDeviceUpdate = ({ device }) => {
		if (device.kind === "audioinput") {
			console.log("Microphone changed:", device.label);
		} else if (device.kind === "videoinput") {
			console.log("Camera changed:", device.label);
		}
	};

	meeting.self.on("deviceUpdate", handleDeviceUpdate);

	return () => {
		meeting.self.off("deviceUpdate", handleDeviceUpdate);
	};
}, [meeting]);
meeting.self.addSelfEventListener(object : RtkSelfEventListener() {
    override fun onAudioDeviceChanged(device: AudioDevice) {
        // Handle audio device change
        println("Audio device changed: ${device.label}")
    }

    override fun onVideoDeviceChanged(device: VideoDevice) {
        // Handle video device change
        println("Video device changed: ${device.label}")
    }
})
meeting.self.addSelfEventListener(self)

// RtkSelfEventListener implementation
func onAudioDeviceChanged(device: AudioDevice) {
    // Handle audio device change
    print("Audio device changed: \(device.label)")
}

func onVideoDeviceChanged(device: VideoDevice) {
    // Handle video device change
    print("Video device changed: \(device.label)")
}
useEffect(() => {
	if (!meeting) return;

	const handleDeviceUpdate = ({ device }) => {
		if (device.kind === "audioinput") {
			console.log("Microphone changed:", device.label);
		} else if (device.kind === "videoinput") {
			console.log("Camera changed:", device.label);
		}
	};

	meeting.self.on("deviceUpdate", handleDeviceUpdate);

	return () => {
		meeting.self.off("deviceUpdate", handleDeviceUpdate);
	};
}, [meeting]);

Aktualizace seznamu zařízení

Spouští se, když se změní seznam dostupných zařízení (zařízení připojeno nebo odpojeno):

meeting.self.on("deviceListUpdate", ({ added, removed, devices }) => {
	console.log("Device list updated");
	console.log("Added devices:", added);
	console.log("Removed devices:", removed);
	console.log("All devices:", devices);
});
useEffect(() => {
	if (!meeting) return;

	const handleDeviceListUpdate = ({ added, removed, devices }) => {
		console.log("Device list updated");
		console.log("Added devices:", added);
		console.log("Removed devices:", removed);
		console.log("All devices:", devices);
	};

	meeting.self.on("deviceListUpdate", handleDeviceListUpdate);

	return () => {
		meeting.self.off("deviceListUpdate", handleDeviceListUpdate);
	};
}, [meeting]);
meeting.addSelfEventListener(object : RtkSelfEventListener {
    // Triggered when audio devices are added or removed
    override fun onAudioDevicesUpdated() {
        val audioDevices = meeting.localUser.getAudioDevices()
        // Update UI with new audio device list
    }
})
meeting.addSelfEventListener(object: RtkSelfEventListener {
    // Triggered when audio devices are added or removed
    func onAudioDevicesUpdated() {
        let audioDevices = meeting.localUser.getAudioDevices()
        // Update UI with new audio device list
    }
})
useEffect(() => {
	if (!meeting) return;

	const handleDeviceListUpdate = ({ added, removed, devices }) => {
		console.log("Device list updated");
		console.log("Added devices:", added);
		console.log("Removed devices:", removed);
		console.log("All devices:", devices);
	};

	meeting.self.on("deviceListUpdate", handleDeviceListUpdate);

	return () => {
		meeting.self.off("deviceListUpdate", handleDeviceListUpdate);
	};
}, [meeting]);

Network Quality Score

Sledujte kvalitu vlastního síťového připojení:

meeting.self.on(
	"mediaScoreUpdate",
	({ kind, isScreenshare, score, scoreStats }) => {
		if (kind === "video") {
			console.log(
				`Your ${isScreenshare ? "screenshare" : "video"} quality score is`,
				score,
			);
		}

		if (kind === "audio") {
			console.log("Your audio quality score is", score);
		}

		if (score < 5) {
			console.log("Your media quality is poor");
		}
	},
);

scoreStats poskytuje podrobné statistiky:

// Audio Producer
{
  "kind": "audio",
  "isScreenshare": false,
  "score": 10,
  "participantId": "meeting.self.id",
  "scoreStats": {
    "score": 10,
    "bitrate": 22452,
    "packetsLostPercentage": 0,
    "jitter": 0,
    "isScreenShare": false
  }
}

// Video Producer
{
  "kind": "video",
  "isScreenshare": false,
  "score": 10,
  "participantId": "meeting.self.id",
  "scoreStats": {
    "score": 10,
    "frameWidth": 640,
    "frameHeight": 480,
    "framesPerSecond": 24,
    "jitter": 0,
    "isScreenShare": false,
    "packetsLostPercentage": 0,
    "bitrate": 576195,
    "cpuLimitations": false,
    "bandwidthLimitations": false
  }
}
useEffect(() => {
	if (!meeting) return;

	const handleMediaScoreUpdate = ({
		kind,
		isScreenshare,
		score,
		scoreStats,
	}) => {
		if (kind === "video") {
			console.log(
				`Your ${isScreenshare ? "screenshare" : "video"} quality score is`,
				score,
			);
		}

		if (score < 5) {
			console.log("Your media quality is poor");
		}
	};

	meeting.self.on("mediaScoreUpdate", handleMediaScoreUpdate);

	return () => {
		meeting.self.off("mediaScoreUpdate", handleMediaScoreUpdate);
	};
}, [meeting]);

Android SDK aktuálně nezpřístupňuje skóre kvality sítě.

iOS SDK v současnosti neposkytuje skóre kvality sítě.

useEffect(() => {
	if (!meeting) return;

	const handleMediaScoreUpdate = ({
		kind,
		isScreenshare,
		score,
		scoreStats,
	}) => {
		if (kind === "video") {
			console.log(
				`Your ${isScreenshare ? "screenshare" : "video"} quality score is`,
				score,
			);
		}

		if (score < 5) {
			console.log("Your media quality is poor");
		}
	};

	meeting.self.on("mediaScoreUpdate", handleMediaScoreUpdate);

	return () => {
		meeting.self.off("mediaScoreUpdate", handleMediaScoreUpdate);
	};
}, [meeting]);

Aktualizace oprávnění

Spouští se, když se oprávnění dynamicky aktualizují:

// Listen to specific permission updates
meeting.self.permissions.on("chatUpdate", () => {
	console.log("Chat permissions updated");
	// Check meeting.self.permissions for updated permissions
});

meeting.self.permissions.on("pollsUpdate", () => {
	console.log("Polls permissions updated");
});

meeting.self.permissions.on("pluginsUpdate", () => {
	console.log("Plugins permissions updated");
});

// Listen to all permission updates
meeting.self.permissions.on("*", () => {
	console.log("Permissions updated");
});

Sledování oprávnění pomocí selectorů:

const permissions = useRealtimeKitSelector((m) => m.self.permissions);

useEffect(() => {
	console.log("Permissions updated:", permissions);
}, [permissions]);

Android SDK používá jiný model oprávnění. Podrobnosti najdete ve specifické dokumentaci pro Android.

iOS SDK používá jiný model oprávnění. Přečtěte si dokumentaci specifickou pro iOS.

Sledování oprávnění pomocí selectorů:

const permissions = useRealtimeKitSelector((m) => m.self.permissions);

useEffect(() => {
	console.log("Permissions updated:", permissions);
}, [permissions]);

Chyby oprávnění k médiím

Spouští se, když jsou oprávnění k médiím zamítnuta nebo selže zachytávání médií:

meeting.self.on("mediaPermissionError", ({ message, kind }) => {
	console.log(`Failed to capture ${kind}: ${message}`);

	// Handle different error types
	if (message === "DENIED") {
		console.log("User denied permission");
	} else if (message === "SYSTEM_DENIED") {
		console.log("System denied permission");
	} else if (message === "COULD_NOT_START") {
		console.log("Failed to start media stream");
	}
});

Možné hodnoty:

useEffect(() => {
	if (!meeting) return;

	const handlePermissionError = ({ message, kind }) => {
		console.log(`Failed to capture ${kind}: ${message}`);

		if (message === "DENIED") {
			// Show UI to guide user to grant permissions
		}
	};

	meeting.self.on("mediaPermissionError", handlePermissionError);

	return () => {
		meeting.self.off("mediaPermissionError", handlePermissionError);
	};
}, [meeting]);
meeting.addSelfEventListener(object : RtkSelfEventListener {
    override fun onMeetingRoomJoinedWithoutCameraPermission() {
        // meeting joined without camera permission
    }

    override fun onMeetingRoomJoinedWithoutMicPermission() {
        // meeting joined without microphone permission
    }
})
meeting.addSelfEventListener(self)

extension MeetingViewModel: RtkSelfEventListener {
    func onMeetingRoomJoinedWithoutCameraPermission() {
        // meeting joined without camera permission
    }

    func onMeetingRoomJoinedWithoutMicPermission() {
        // meeting joined without microphone permission
    }
}

Stav oprávnění můžete také zkontrolovat pomocí vlastností:

let hasCameraPermission = meeting.localUser.isCameraPermissionGranted
let hasMicPermission = meeting.localUser.isMicrophonePermissionGranted
useEffect(() => {
	if (!meeting) return;

	const handlePermissionError = ({ message, kind }) => {
		console.log(`Failed to capture ${kind}: ${message}`);

		if (message === "DENIED") {
			// Show UI to guide user to grant permissions
		}
	};

	meeting.self.on("mediaPermissionError", handlePermissionError);

	return () => {
		meeting.self.off("mediaPermissionError", handlePermissionError);
	};
}, [meeting]);

Stav Waitlist

Pro schůzky s povolenou čekárnou:

Sledujte roomState vlastnost pro stav čekárny. Hodnota 'waitlisted' signalizuje, že se uživatel nachází v čekárně.

const roomState = useRealtimeKitSelector((m) => m.self.roomState);

useEffect(() => {
	if (roomState === "waitlisted") {
		console.log("Waiting for host to admit you");
	}
}, [roomState]);
// Get current waitlist status
val waitListStatus = meeting.localUser.waitListStatus

// Listen to waitlist status changes
meeting.addSelfEventListener(object : RtkSelfEventListener {
    override fun onWaitListStatusUpdate(waitListStatus: WaitListStatus) {
        // handle waitlist status here
    }
})
// Get current waitlist status
let waitListStatus = meeting.localUser.waitListStatus

// Listen to waitlist status changes
extension MeetingViewModel: RtkSelfEventListener {
    func onWaitlistedUpdate() {
        // handle waitlist update
    }
}
const roomState = useRealtimeKitSelector((m) => m.self.roomState);

useEffect(() => {
	if (roomState === "waitlisted") {
		console.log("Waiting for host to admit you");
	}
}, [roomState]);

Události specifické pro iOS

iOS SDK poskytuje další události specifické pro danou platformu:

Senzor přiblížení

Spouští se, když senzor přiblížení zaznamená změnu (užitečné pro detekci přiložení k uchu):

extension MeetingViewModel: RtkSelfEventListener {
    func onProximityChanged() {
        // Handle proximity sensor change
        // Useful for detecting when device is near user's ear
    }
}

Události webináře

Pro funkce specifické pro webinář:

extension MeetingViewModel: RtkSelfEventListener {
    func onWebinarPresentRequestReceived() {
        // Handle request to present in webinar
    }

    func onStoppedPresenting() {
        // Handle stopped presenting in webinar
    }
}

Zprávy místnosti

Naslouchejte vysílaným zprávám v místnosti:

extension MeetingViewModel: RtkSelfEventListener {
    func onRoomMessage() {
        // Handle room broadcast message
    }
}

Připnutí a odepnutí

Připněte nebo odepněte sami sebe ve schůzce (vyžaduje odpovídající oprávnění):

Web SDK aktuálně nepodporuje připnutí lokálního účastníka.

Web SDK aktuálně nepodporuje připnutí lokálního účastníka.

Android SDK aktuálně nepodporuje připnutí místního účastníka.

// Pin yourself
meeting.localUser.pin()

// Unpin yourself
meeting.localUser.unpin()

// Check if pinned
let isPinned = meeting.localUser.isPinned
// Pin yourself
await meeting.self.pin();

// Unpin yourself
await meeting.self.unpin();

// Check if pinned
const isPinned = meeting.self.isPinned;

Aktualizace omezení médií

Aktualizujte rozlišení videa nebo sdílení obrazovky za běhu:

Web SDK aktuálně neumožňuje aktualizace omezení runtime pro lokálního účastníka.

Web SDK aktuálně neumožňuje aktualizace omezení runtime pro lokálního účastníka.

Android SDK aktuálně nezpřístupňuje aktualizace omezení za běhu.

iOS SDK v současnosti neposkytuje aktualizace omezení za běhu.

Aktualizace omezení videa

Aktualizujte rozlišení kamery, když už streamujete:

meeting.self.updateVideoConstraints({
	width: { ideal: 1920 },
	height: { ideal: 1080 },
});

Aktualizace omezení sdílení obrazovky

Aktualizujte rozlišení sdílení obrazovky, když už streamujete:

meeting.self.updateScreenshareConstraints({
	width: { ideal: 1920 },
	height: { ideal: 1080 },
});