Why Other devices not connect?

Hello, everything works very smoothly.
I can video call for testing with a device without any problems.
Image cannot be transferred when I try with another device. What could be the problem?

`import React, {Component} from ‘react’;
import {
SafeAreaView,
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
ActivityIndicator, TouchableHighlight
} from ‘react-native’;
import Icon from ‘react-native-vector-icons/FontAwesome5’;
import {
mediaDevices,
RTCPeerConnection,
RTCSessionDescription,
RTCView,
RTCIceCandidate,
} from ‘react-native-webrtc’;
import {withSocketContext} from “…/…/…/config/create-context-socket”;
import {inject} from “mobx-react”;
const screenHeight =Math.round(Dimensions.get(‘window’).height);
const screenWidth = Math.round(Dimensions.get(‘window’).width);
@Inject(‘AuthStore’)
class VideoCall extends Component<any, any> {
configuration: any = {iceServers: [{url: ‘stun:stun.l.google.com:19302’}]};
state: any = {
localStream: ‘’,
remoteStream: ‘’,
to: ‘’,
from: ‘’,
type: ‘’,
isFinish: false,
isMuted:false,
};
socket = this.props.socket;
peer = new RTCPeerConnection(this.configuration);

startLocalStream = async () => {
    // isFront will determine if the initial camera should face user or environment
    const isFront = true;
    const devices = await mediaDevices.enumerateDevices();

    const facing = isFront ? 'front' : 'environment';
    const videoSourceId = devices.find(
        device => device.kind === 'videoinput' && device.facing === facing,
    );
    const facingMode = isFront ? 'user' : 'environment';
    const constraints: any = {
        audio: true,
        video: {
            mandatory: {
                minWidth: 500, // Provide your own width, height and frame rate here
                minHeight: 300,
                minFrameRate: 30,
            },
            facingMode,
            optional: videoSourceId ? [{sourceId: videoSourceId}] : [],
        },
    };
    const newStream = await mediaDevices.getUserMedia(constraints);
    this.setState({
        localStream: newStream,
    });
    this.peer.addStream(newStream);
};

createAndSendOffer = async () => {
    const offer = await this.peer.createOffer();
    const sd = new RTCSessionDescription(offer);
    this.peer.setLocalDescription(sd);

    // send offer infi via socket.io
    this.socket.emit(
        'call_test',
        this.state.to,
        JSON.stringify({sdp: sd}),
    );
};

createAndSendAnswer = async () => {
    const {from} = this.state;
    const answer = await this.peer.createAnswer();
    const ans = new RTCSessionDescription(answer);
    await this.peer.setLocalDescription(ans);
    if (ans) {
        this.socket.emit('call_test', from, JSON.stringify({sdp: ans}));
    }
    // wsc.send(JSON.stringify({ sdp: ans }));
};

initCall = async () => {
    // send any ice candidates to the other peer

    this.peer.onicecandidate = this.onIceCandidateHandler;
    // once remote stream arrives, show it in the remote video element
    this.peer.onaddstream = this.onAddStreamHandler;
};

onIceCandidateHandler = evt => {
    if (!evt || !evt.candidate) return;
    //Send Candidadte
    if (this.state.from) {
        this.socket.emit(
            'call_test',
            this.state.from,
            JSON.stringify({candidate: evt.candidate}),
        );
    } else {
        this.socket.emit(
            'call_test',
            this.state.to,
            JSON.stringify({candidate: evt.candidate}),
        );
    }
    // wsc.send(JSON.stringify({candidate: evt.candidate}));
};

onAddStreamHandler = evt => {
    // videoCallButton.setAttribute('disabled', true);
    // endCallButton.removeAttribute('disabled');
    // set remote video stream as source for remote video HTML5 element
    this.setState({
        remoteStream: evt.stream,
    });
};

dispose = () => {
    this.peer.close();
    this.peer.removeStream(this.state.localStream);
    this.setState({localStream: ''});
    this.props.navigation.goBack();
};

sendDismiss = isOffer => {
    this.socket.emit(
        'call_test',
        (this.props.AuthStore.token == this.state.from) ? this.state.to : this.state.from,
        'dismiss',
    );
    this.dispose();
};

async componentDidMount() {

    await this.initCall();
    await this.startLocalStream();
    const to = this.props.navigation.getParam('to', '');
    const from = this.props.navigation.getParam('from', '');
    const type = this.props.navigation.getParam('type', 'ingoing');
    console.log('Arayan ',from);
    console.log('Alıcı',to);
    //if (type === 'outgoing') {
        this.setState({
            to: to,
            from: from,
            type: type,
        });

    //}

    this.socket.on('call_test', async (to, evt) => {
        if (evt === 'dismiss') {
            this.dispose();
            return;
        }
        if (evt === 'ready') {
            await this.createAndSendOffer();
            setTimeout(async () => {
                this.socket.emit(
                    'call_test',
                    this.state.to,
                    'calling me',
                );
                this.setState({
                    isFinish: true,
                });
            }, 1000);
        }
        let signal: any = null;

        if (evt !== 'calling me' && evt !== 'ready') {
            signal = JSON.parse(evt);
        }
        console.log(signal)
        if (signal && signal.hasOwnProperty('sdp') && signal.sdp) {
            this.peer.setRemoteDescription(new RTCSessionDescription(signal.sdp));
        } else if (signal && signal.candidate) {
            this.peer.addIceCandidate(new RTCIceCandidate(signal.candidate));
        } else if (signal && signal.closeConnection) {
        } else if (evt === 'calling me') {
            this.createAndSendAnswer();
        }
    });


    if (!this.state.isFinish && this.state.type === 'outgoing') {
        this.readyConversation();
    }

}

componentWillUnmount() {
    const {from} = this.state;
    this.dispose();
    this.sendDismiss(from ? false : true);
}

readyConversation = () => {
    this.socket.emit('call_test', this.state.from, 'ready');
    this.setState({
        isFinish: true,
    });
};

switchCamera = async  () => {
    this.state.localStream.getVideoTracks().forEach(track => track._switchCamera());
};

toggleMute = () => {
    if (!this.remoteStream) return;
    this.state.localStream.getAudioTracks().forEach(track => {

        track.enabled = !track.enabled;
        this.setState({
            isMuted:!track.enabled
        })

    });
};

render() {
    const {isFinish} = this.state;

    return (
        <SafeAreaView style={styles.root}>
            <TouchableOpacity onPress={this.switchCamera} style={styles.changeCamera} >
                <Image style={{ width:60,height:60}} source={require('../../../../assets/image/app/turn-camera.png') } />
            </TouchableOpacity>
            <RTCView  streamURL={this.state.remoteStream && this.state.remoteStream.toURL()} style={styles.localVideo} mirror={true} />
            <RTCView  streamURL={this.state.localStream && this.state.localStream.toURL()} mirror={true} style={styles.remoteVideo} />
            {!this.state.isFinish &&
            <View style={styles.loading}>
                <ActivityIndicator size={30} color={"white"}/>
                <Text style={{color: 'white', fontSize: 14, marginLeft: 15, fontFamily: 'Rubik-Bold'}}>Bağlanıyor,
                    Lütfen bekleyiniz...</Text>
            </View>
            }
            <View style={styles.buttonContainer}>
                <TouchableHighlight style={[styles.button2, styles.microphoneButton]} onPress={() => this.toggleMute()}>
                    <Icon name={(this.state.isMuted) ? 'microphone-alt-slash' : 'microphone-alt' }  size={20}  color={'white'}/>
                </TouchableHighlight>

                <TouchableHighlight style={[styles.button, styles.buttonCall]} onPress={() => this.sendDismiss()}>
                    <Icon name={"phone-slash"} size={20} color={"white"} />
                </TouchableHighlight>
            </View>
        </SafeAreaView>

    );
}

}
const styles = StyleSheet.create({
root: {
flex: 1,

},
changeCamera:{
    top: 30,
    right: 10,
    position: "absolute",
    zIndex:2,
    elevation:2,
},
localVideo: {
    width: '100%',
    height: '100%',
    backgroundColor:"black",


},
remoteVideo: {
    top: 30,
    left: 30,
    width: 114,
    height: 170,
    backgroundColor: "rgba(230, 230, 230,1)",
    position: "absolute",
    zIndex:999,
    elevation:999,
},
buttonContainer:{
    top:screenHeight - 140,
    position:'absolute',
    alignSelf: 'center',
    flexDirection:'row',
    justifyContent:'center',
    marginTop:20,
    alignItems:'center',
},
button: {
    width:60,
    height:60,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom:20,
    borderRadius:30,
    margin:10,
    shadowColor: 'black',
    shadowOpacity: .8,
    shadowOffset: {
        height:2,
        width:-2
    },
    elevation:4,
},
button2: {
    width:40,
    height:40,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom:20,
    borderRadius:30,
    margin:10,
    shadowColor: 'black',
    shadowOpacity: .8,
    shadowOffset: {
        height:2,
        width:-2
    },
    elevation:4,
},
buttonCall: {
    backgroundColor: "red",
},
microphoneButton: {
    backgroundColor: "rgba(255,255,255,0.4)",
},
icon: {
    width:35,
    height:35,
}
,
loading:{
    flexDirection:'row',
    justifyContent:'center',
    alignItems:'center',
    backgroundColor: "rgba(0, 0, 0,100.7)",
    position:'absolute',
    top:'50%',
    width:'90%',
    alignSelf: 'center',
    height:50,
}

});

export default withSocketContext(VideoCall);
`

Can you give more information?
What devices are you testing with that has issues?
Also which version of the module and React-Native are you using?

first device huawei mate 20 lite
second device Samsung a7
React native version : 0.60.5
React native Webrtc version : 1.75.2

Have you tried running logcat during an ongoing call on both devices, see if theres any errors popping up from the module itself on the native side of things?

One of the simple ways would be to run Android Studio and use the logging feature that provides.

I tried another device worked there, but Samsung a7 also did not work

If you could possibly provide logs from logcat, that would help.
Looking over the code isn’t exactly helping as such.

device is not near me but i think a7 does not support

Shouldn’t be an issue, if the device doesn’t support hardware encoding/decoding then it would just downgrade to software encoding/decoding instead.

Could there be a situation with stun server, I am using google

Shouldn’t be, if it works solid on one device but not on another, that isn’t an issue with the STUN server.
We would have a better understanding if you could provide logs.

I don’t have the device that isn’t working.
how can I provide the diary.

Sadly that makes debugging the issue difficult.
Have you tried running the app using an android simulator?
and if so does it also experience the same issue?

works on emulator :confused:

If you can’t replicate the issue and you can’t get your hands on the device to see what was going on then it doesn’t seem like you’ll be able to figure out what the issue was and thus resolve it :confused:

I noticed something wifide is not a problem, but it is causing problems in cellular.
Could it be a proxy or something related?

There can be issues connecting between various networks from time to time which means having a TURN server would mostly resolve them issues.

Sadly having just a STUN server doesn’t always help.

I wonder how can I find the turn server, is it provided by google?

Not exactly.
You use a TURN server to relay media when network connections for some reason can’t be made directly peer to peer. There are some free servers but they are barely acceptable and tend to be slow/mostly in-usable.

Have you tried using this free TURN server?
https://numb.viagenie.ca/

Obviously it might not be that fast as there will probably be a lot of people using it.
That does mean the call connecting time will most likely be slow.
But it would let you test to see if the other devices work.

Hi @buldurmert did you got the answer of this problem?

1 Like