INTEGRITY Documentation

Media Acquisition Approaches

RealtimeKit provides flexible approaches for acquiring and managing participant media (audio and video tracks). By default, the SDK handles media acquisition automatically when you initialize it. However, certain use cases require accessing media tracks before or independently of SDK initialization.

Manual track handling is not available on this platform.

When to use custom media acquisition

Custom media acquisition is useful when you need to:

Initialize the SDK first, then access media tracks from the meeting object. This is the simplest approach and suitable for most use cases.

When to use: You need to access media tracks after SDK initialization for logging, analysis, or integration with other services.

import { useEffect } from 'react';
import { useRealtimeKitClient } from '@cloudflare/realtimekit-react';

export default function App() {
	const [meeting, initMeeting] = useRealtimeKitClient();

    useEffect(() => {
    	initMeeting({ authToken: "<auth-token>" });
    }, []);

    useEffect(() => {
        if(meeting){
            console.log('audioTrack:: ', meeting.self.audioTrack);
            console.log('videoTrack:: ', meeting.self.videoTrack);
        }

    }, [meeting])

    return <div>Your meeting component comes here</div>;

}
const authToken = "<auth-token>";
const meeting = await RealtimeKitClient.init({
	authToken,
});

console.log("audioTrack:: ", meeting.self.audioTrack);
console.log("videoTrack:: ", meeting.self.videoTrack);
class AppComponent {
	title = "MyProject";
	@ViewChild("myid") meetingComponent: RtkMeeting;
	rtkMeeting: RealtimeKitClient;

	async ngAfterViewInit() {
		const meeting = await RealtimeKitClient.init({
			authToken: "<auth-token>",
		});

		console.log("audioTrack:: ", meeting.self.audioTrack);
		console.log("videoTrack:: ", meeting.self.videoTrack);
	}
}

Approach 2: Media-first

Initialize the media handler first using RealtimeKitClient.initMedia(), then pass it to the SDK during initialization. The SDK reuses the acquired media tracks without requesting permissions again.

When to use: You need to acquire media tracks minutes in advance before joining a session. This is particularly useful for EdTech assessment platforms where you want to enable proctoring or tracking systems early without managing WebSocket connections or handling media disconnects that come with full SDK initialization.

Benefits:

  • SDK manages media acquisition and browser compatibility.
  • Participants are not prompted for permissions twice.
  • Media tracks are automatically synchronized between your validation service and the SDK.
  • Acquire media early without the complexity of managing SDK connection state.
import { useEffect, useState } from 'react';
import RealtimeKitClient from '@cloudflare/realtimekit';
import type { RTKSelfMedia } from '@cloudflare/realtimekit';
import { useRealtimeKitClient } from '@cloudflare/realtimekit-react';

export default function App() {
	const [meeting, initMeeting] = useRealtimeKitClient();
    const [media, setMedia] = useState<RTKSelfMedia>();
    const [readyToInitializeSDK, setReadyToInitializeSDK] = useState(false);

    useEffect(() => {
        async function initMediaWithoutSDKInitialization(){
            const mediaFromSDK = await RealtimeKitClient.initMedia({
              video : true,
              audio: true,
            });

            setMedia(mediaFromSDK);

            console.log('audioTrack', mediaFromSDK.audioTrack);
            console.log('videoTrack', mediaFromSDK.videoTrack);

            setTimeout(() => {
                // Once you are ready to initialize the SDK, set this to true
                // To mimic a real world scenario, we are setting it to true after 5 seconds
                setReadyToInitializeSDK(true);
            }, 5000);
        }
        if(!media){
            initMediaWithoutSDKInitialization();
        }
    }, [media]);

    useEffect(() => {
        if(meeting){
            return;
        }
        if(!readyToInitializeSDK){
            return;
        }
        if(!media){
            return;
        }
    	initMeeting({ authToken: "<auth-token>", defaults: { mediaHandler: media } });
    }, [meeting, readyToInitializeSDK, media]);

    return <div>Your meeting component comes here</div>;
}

Initialize the media handler first using RealtimeKitClient.initMedia(), then pass it to the SDK during initialization. The SDK reuses the acquired media tracks without requesting permissions again.

When to use: You need to acquire media tracks minutes in advance before joining a session. This is particularly useful for EdTech assessment platforms where you want to enable proctoring or tracking systems early without managing WebSocket connections or handling media disconnects that come with full SDK initialization.

Benefits:

  • SDK manages media acquisition and browser compatibility.
  • Participants are not prompted for permissions twice.
  • Media tracks are automatically synchronized between your validation service and the SDK.
  • Acquire media early without the complexity of managing SDK connection state.
const mediaFromSDK = await RealtimeKitClient.initMedia({
	video: true,
	audio: true,
});

setTimeout(() => {
	const authToken = "<auth-token>";
	RealtimeKitClient.init({
		authToken,
		defaults: {
			mediaHandler: mediaFromSDK,
		},
	}).then((meeting) => {
		// next - meeting.join();
	});
}, 5000);

Initialize the media handler first using RealtimeKitClient.initMedia(), then pass it to the SDK during initialization. The SDK reuses the acquired media tracks without requesting permissions again.

When to use: You need to acquire media tracks minutes in advance before joining a session. This is particularly useful for EdTech assessment platforms where you want to enable proctoring or tracking systems early without managing WebSocket connections or handling media disconnects that come with full SDK initialization.

Benefits:

  • SDK manages media acquisition and browser compatibility.
  • Participants are not prompted for permissions twice.
  • Media tracks are automatically synchronized between your validation service and the SDK.
  • Acquire media early without the complexity of managing SDK connection state.
class AppComponent {
	title = "MyProject";
	@ViewChild("myid") meetingComponent: RtkMeeting;
	rtkMeeting: RealtimeKitClient;

	async ngAfterViewInit() {
		const mediaFromSDK = await RealtimeKitClient.initMedia({
			video: true,
			audio: true,
		});

		setTimeout(() => {
			const authToken = "<auth-token>";
			RealtimeKitClient.init({
				authToken,
				defaults: {
					mediaHandler: mediaFromSDK,
				},
			}).then((meeting) => {
				// next - meeting.join();
			});
		}, 5000);
	}
}

Approach 3: Self-managed (advanced)

Acquire and manage media tracks independently using browser APIs, then pass them to the SDK when enabling audio and video.

When to use: You have existing media management infrastructure or need complete control over media acquisition.

Considerations:

Initialize the SDK with audio and video disabled, then enable them with your custom tracks:

import { useEffect } from 'react';
import { useRealtimeKitClient } from '@cloudflare/realtimekit-react';

export default function App() {
	const [meeting, initMeeting] = useRealtimeKitClient();

    useEffect(() => {
    	initMeeting({ authToken: "<auth-token>" });
    }, []);

    useEffect(() => {
        async function setupMediaTracks(){
            if (meeting) {
                let audioTrack; // Put the audioTrack that you acquired from browser here
                let videoTrack; // Put the videoTrack that you acquired from browser here
                await meeting.self.enableAudio(audioTrack);
                await meeting.self.enableVideo(videoTrack);
                // await meeting.self.join();
            }
        }
        setupMediaTracks();

    }, [meeting])

    return <div>Your meeting component comes here</div>;

}
const authToken = "<auth-token>";
const meeting = await RealtimeKitClient.init({
	authToken,
});

let audioTrack; // Put the audioTrack that you acquired from browser here
let videoTrack; // Put the videoTrack that you acquired from browser here
await meeting.self.enableAudio(audioTrack);
await meeting.self.enableVideo(videoTrack);
class AppComponent {
	title = "MyProject";
	@ViewChild("myid") meetingComponent: RtkMeeting;
	rtkMeeting: RealtimeKitClient;

	async ngAfterViewInit() {
		const meeting = await RealtimeKitClient.init({
			authToken: "<auth-token>",
		});

		let audioTrack; // Put the audioTrack that you acquired from browser here
		let videoTrack; // Put the videoTrack that you acquired from browser here
		await meeting.self.enableAudio(audioTrack);
		await meeting.self.enableVideo(videoTrack);
	}
}