Я хочу имитировать систему вызова в приложении, используя react-native-opentok
.Я успешно инициировал метод голосового вызова, просто используя <Publish />
и <Subscribe />
, но когда я добавил video={true}
к обоим, чтобы начать сеанс видеовызова, подписчик в моем симуляторе показывает мне камеру с моегореальное устройство, хотя я не вижу себя как <Publisher />
;с моего реального устройства он продолжает показывать мне пустой холст.
Вот мой компонент видеовызова
import React, { Component } from 'react';
import { View, Text, StyleSheet, Image, SafeAreaView, TouchableOpacity } from 'react-native';
import Container from '@components/container';
import Api from '@utils/api';
import { Icon } from 'native-base';
import NewCall from '@components/new-call';
import Sound from 'react-native-sound';
import OpenTok, { Publisher, Subscriber } from 'react-native-opentok';
class VideoCall extends Component {
constructor(props) {
super(props);
this.state = { loading: true, call_answered: false, status: '' };
}
componentDidMount = async () => {
await this.setup_component();
await this.connect_to_session();
}
setup_component = async () => {
await this.setState({ appointment: this.props.navigation.getParam('appointment'), status: this.props.navigation.getParam('status'), loading: false })
OpenTok.on(OpenTok.events.ON_SIGNAL_RECEIVED, e => {
if (e.type == 'answered') this.setState({ status: e.type })
if (e.type == 'hangup') this.hangup('hunged up')
})
}
connect_to_session = async () => {
try {
if (this.state.status == 'calling') OpenTok.sendSignal(this.state.appointment.call_session, 'video_call')
if (this.state.status == 'getting a call') this.ring()
} catch (e) {
console.warn(e);
}
}
respond = async (e) => {
if (await e == 'answered') {
await this.setState({ status: e })
OpenTok.sendSignal(this.state.appointment.call_session, 'answered')
}
}
ring = () => {
let ringtone = new Sound('default_ringtone.mp3', Sound.MAIN_BUNDLE, error => {
if (error) {
console.warn(error);
return;
}
})
ringtone.play((success) => {
if (success) console.warn('successfully playing')
else {
console.warn('playback failed due to audio decoding errors');
whoosh.reset();
}
})
ringtone.release()
}
hangup = (e) => {
if (e == 'hunged up') {
OpenTok.disconnect(this.state.appointment.call_session);
this.props.navigation.goBack(null)
} else {
OpenTok.sendSignal(this.state.appointment.call_session, 'hangup')
OpenTok.disconnect(this.state.appointment.call_session);
this.props.navigation.goBack(null)
}
}
render() {
if (!this.state.appointment) return false;
return (
<Container loading={ this.state.loading }>
<Image source={ require('@images/audio-call.png')} style={{ position: 'absolute', width: '100%', height: '100%' }} />
<SafeAreaView style={{ flex: 1, position: 'relative' }}>
{
(this.state.status == 'answered')
? <View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}>
<Publisher
style={{ position: 'absolute', top: 0, right: 0, left: 0, bottom: 0, zIndex: 90 }}
sessionId={this.state.appointment.call_session}
video={ true }
onSubscribeStart={() => {
console.log('subscription started');
}}
videoScale="fill"
cameraDirection="front"
onSubscribeStop={() => {
console.log('subscription stopped');
}}
/>
<Subscriber
sessionId={this.state.appointment.call_session}
onPublishStart={() => {
console.log('publish started');
}}
onPublishStop={() => {
console.log('publish stoped');
}}
style={{ position: 'absolute', top: 40, right: 10, width: 100, height: 200, zIndex: 100 }}
video={ true }
ref={ref => {
this.publisherRef = ref;
}}
/>
{/* <View style={{ position: 'absolute', top: 40, right: 10, width: 100, height: 200, zIndex: 100, backgroundColor: 'red' }} /> */}
</View>
: null
}
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'flex-start', paddingTop: 50 }}>
{ (this.state.status == 'calling' || this.state.status == 'getting a call')
? <View style={{ width: 200, height: 200, borderRadius: 100, backgroundColor: '#a4a4a4' }}>
<Image source={ require('@images/male-avatar.png') } style={{ width: 200, height: 200, resizeMode: 'cover' }} />
</View>
: null
}
</View>
{
(this.state.status == 'getting a call')
? <NewCall respond={ this.respond } />
: (this.state.status == 'calling')
? <View style={{ flex: 0, paddingVertical: 40, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: '#fff', fontFamily: 'DINNextLTArabic-Regular', fontSize: 22, lineHeight: 24 }}>Calling ...</Text>
</View>
: (this.state.status == 'answered')
? <View style={{ flex: 0, paddingVertical: 30, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: '#fff', fontSize: 22, lineHeight: 24, fontFamily: 'DINNextLTArabic-Regular', marginVertical: 10 }}>02:25</Text>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TouchableOpacity style={{ width: 80, height: 80, borderRadius: 100, alignItems: 'center', justifyContent: 'center', backgroundColor: '#A7A8C4' }}>
<Icon name="megaphone" type="Foundation" style={{ fontSize: 40, color: '#26296A', marginTop: 5 }} />
</TouchableOpacity>
</View>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TouchableOpacity style={{ width: 100, height: 100, borderRadius: 100, alignItems: 'center', justifyContent: 'center', backgroundColor: '#E16897' }}>
<Icon name="phone" type="Feather" style={{ fontSize: 40, color: '#fff', lineHeight: 42, transform: [{ rotate: '135deg' }] }} />
</TouchableOpacity>
</View>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TouchableOpacity style={{ width: 80, height: 80, borderRadius: 100, alignItems: 'center', justifyContent: 'center', backgroundColor: '#A7A8C4' }}>
<Icon name="microphone-off" type="MaterialCommunityIcons" style={{ fontSize: 40, color: '#26296A', lineHeight: 42 }} />
</TouchableOpacity>
</View>
</View>
</View>
: null
}
</SafeAreaView>
</Container>
);
}
}
export default VideoCall;
Что здесь может быть не так?