Skip to main content

VOIP/Video Consultations

VoipConfig Object

interface VoipConfig {
id?: number;
consultation_id?: number;
apiKey?: string;
call_id?: string;
token?: string;
}

For VOIP consultation the config data will be in voipConfig and for VIDEO will be in videoConfig but it will be the same data structure so will be using one interface for both VoipConfig

VOIP and Video consultations are rendered and handled the same way, the difference is ro enable the video on Video consultations and disable it for VOIP consultations.

VOIP/Video Components

These are the components we have to handle these consultations:

TBIPublisher
TBISession
TBISubscriber
TBISubscriberView

VOIP/Video Example

Check the below code example of using our ready-to-use components to handle VOIP/Video consultations:

import React, { useRef, useState } from 'react';
import {
TBIPublisher,
TBISession,
TBISubscriber,
TBISubscriberView,
} from 'react-native-altibbi';
import { Dimensions, View, Text } from 'react-native';

const Video = (props) => {
const data = props.route.params.event;
const voip = props.route.params.voip;

const [audio, setAudio] = useState<boolean>(true);
const [video, setVideo] = useState<boolean>(!voip);
const [camera, setCamera] = useState<'front' | 'back'>('front');
const sessionRef = useRef(null);

const toggleVideo = () => setVideo((prev) => !prev);
const toggleAudio = () => setAudio((prev) => !prev);
const switchCamera = () =>
setCamera((prev) => {
if (prev === 'front') {
return 'back';
} else {
return 'front';
}
});

const renderSubscribers = (subscribers) => {
if (subscribers && subscribers.length > 0) {
const { width: screenWidth, height: screenHeight } =
Dimensions.get('window');
return subscribers.map((streamId) => (
<TBISubscriberView
streamId={streamId}
style={{ width: screenWidth, height: screenHeight }}
/>
));
}
};

return (
<TBISession
options={{
androidZOrder: 'onTop',
androidOnTop: 'publisher',
}}
ref={(ref) => (sessionRef.current = ref)}
apiKey={data.api_key}
sessionId={data.call_id}
token={data.token}
eventHandlers={{
streamDestroyed: (event) => {},
error: (event) => {},
otrnError: (event) => {},
}}
>
<TBISubscriber
eventHandlers={{
error: (event) => {},
otrnError: (event) => {},
}}
>
{renderSubscribers}
</TBISubscriber>
<TBIPublisher
style={{
position: 'absolute',
width: 100,
height: 100,
top: 0,
margin: 5,
right: 0,
}}
properties={{
cameraPosition: camera,
publishVideo: video,
publishAudio: audio,
enableDtx: true,
}}
eventHandlers={{
streamDestroyed: (event) => {},
error: (event) => {},
otrnError: (event) => {},
}}
/>
<View
style={{
flexDirection: 'row',
padding: 8,
position: 'absolute',
backgroundColor: 'white',
bottom: 0,
left: 0,
right: 0,
justifyContent: 'center',
}}
>
<Text
style={{
fontSize: 20,
marginRight: 10,
color: video ? 'blue' : 'red',
}}
onPress={() => toggleVideo()}
>
{`Video ${video ? 'On' : 'Off'}`}
</Text>
<Text
style={{
fontSize: 20,
marginRight: 10,
color: audio ? 'blue' : 'red',
}}
onPress={() => toggleAudio()}
>
{`Audio ${audio ? 'On' : 'Off'}`}
</Text>
<Text
style={{ fontSize: 20, marginRight: 10 }}
onPress={() => switchCamera()}
>
camera ({camera})
</Text>
</View>
</TBISession>
);
};

export default Video;