VOIP/Video Consultations
VoipConfig Object
interface VoipConfig {
id?: number;
consultation_id?: number;
api_key?: string;
call_id?: string;
token?: string;
created_at?: string;
updated_at?: string;
}
For
VOIPconsultation the config data will be invoipConfigand forVIDEOwill be invideoConfig, but they share the same data structure so we use one interface for both:VoipConfig.
VOIP and Video consultations are rendered and handled the same way.
The difference is to enable the video on Video consultations and disable it for VOIP consultations.
VOIP/Video Components
These are the components available 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;