Can't able to show Remote string in latest version of RN(0.72.3)

I’m try to implement 1 to 1 video call in latest react-native version with socket.io-client but can’t render remote string. I don’t know is it because of latest version of react-native or anything else. Here is my server and room file code.

Server.js

const express = require("express");
const { createServer } = require("http");
const { Server } = require('socket.io');

const app = express();

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: { origin: "*" },
  // transports: ["websocket"],
  connectTimeout: 2 * 60 * 1000,
});
const port = process.env.PORT || 8089;
httpServer.listen(port, () => {
  console.log('Server listening at port %d', port);
});

app.get("/", (req, res) => {
  return res.send("<h1>Connected</h1>");
});

io.on('connection', (socket) => {
  console.log("connected", socket.id)
  socket.on('disconnect', () => {
    console.log(`Disconnected: ${socket.id}`);
  });

  socket.on("join", (roomId) => {
    socket.join(roomId);
  });

  socket.on('offer', function (data) {
    const { roomId = '' } = data;
    io.to(roomId).emit('received-offer', data);
  });

  socket.on('offers-answer', function (data) {
    const { roomId = '' } = data;
    io.to(roomId).emit('offers-answer', data);
  });

  socket.on('candidate', function (data) {
    const { roomId = '' } = data;
    io.to(roomId).emit('candidate', data);
  });

  socket.on('peer:nego:needed', function (data) {
    const { roomId = '' } = data;
    io.to(roomId).emit('peer:nego:needed', data);
  });

  socket.on('peer:nego:done', function (data) {
    const { roomId = '' } = data;
    io.to(roomId).emit('peer:nego:done', data);
  });

  socket.on("connection_error", (err) => {
    console.log("connection_error", err);
  })
});

server package.json

{
  "name": "wcam",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.18.2",
    "nodemon": "^3.0.1",
    "socket.io": "^4.7.1"
  }
}

React Native
Room.tsx

import React, {
  useRef,
  useState,
  useEffect,
  useCallback,
  MutableRefObject,
} from "react";
import {
  Text,
  View,
  Pressable,
  StyleSheet,
  SafeAreaView,
} from "react-native";
import {
  RTCView,
  MediaStream,
  mediaDevices,
  RTCIceCandidate,
  RTCPeerConnection,
  RTCSessionDescription,
} from "react-native-webrtc";
import io, { Socket } from "socket.io-client";
import { RTCSessionDescriptionInit } from "react-native-webrtc/lib/typescript/RTCSessionDescription";

import { RoomScreenProps } from "../navigation/NavigationType";

const options = {
  mandatory: {
    OfferToReceiveAudio: true,
    OfferToReceiveVideo: true,
    VoiceActivityDetection: true
  }
};

const servers = {
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' },
    { urls: 'stun:stun1.l.google.com:19302' }
  ],
};

const RoomView = ({ navigation, route }: RoomScreenProps) => {
  const roomId = "ABC123";
  const { type } = route?.params ?? {};
  const socket = useRef(null) as MutableRefObject<Socket | null>;
  const peer = useRef(null) as MutableRefObject<RTCPeerConnection | null>;
  const [localStream, setLocalStream] = useState<MediaStream | null>(null);
  const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);
  const [remoteCandidates, setRemoteCandidates] = useState<RTCIceCandidate[]>([]);

  let connected = false;

  const handleTracks = useCallback((event: any) => {
    // console.log("GOT TRACKS!!", JSON.stringify(event));
    const [stream] = event?.streams ?? [];
    setRemoteStream(stream);
  }, []);

  useEffect(() => {
    connectSocket();
    getLocalMedia();
    return () => {
      if (peer.current) {
        peer.current.close();
      }
      if (socket.current) {
        socket.current?.disconnect();
      }
      connected = false;
    }
  }, []);

  useEffect(() => {
    if (localStream) {
      setPeerConnection();
    }
    return () => {
      if (localStream?.getTracks().length) {
        localStream?.getTracks().forEach(t => t.stop());
      }
    }
  }, [localStream]);

  const getLocalMedia = async () => {
    try {
      const local = await mediaDevices.getUserMedia({
        video: true,
        audio: true,
      });
      setLocalStream(local);
    } catch (error) {
      console.log("getLocalMedia error", error);
    }
  };

  const handleNegoNeeded = async () => {
    if (!peer.current) return;
    try {
      const offer = await peer.current?.createOffer(options);
      await peer.current.setLocalDescription(new RTCSessionDescription(offer));
      socket.current?.emit("peer:nego:needed", { offer, roomId });
    } catch (error) {
      console.log("handleNegoNeeded error", error);
    }
  };

  useEffect(() => {
    if (connected && localStream && localStream?.getTracks().length) {
      peer.current?.addEventListener("negotiationneeded", handleNegoNeeded);
    }
    return () => {
      if (connected && localStream && localStream?.getTracks().length) {
        peer.current?.removeEventListener("negotiationneeded", handleNegoNeeded);
      }
    };
  }, [handleNegoNeeded, peer.current, localStream, connected]);

  const connectSocket = () => {
    if (socket.current != null) socket.current = null;
    socket.current = io("http://192.168.0.195:8089", {
      path: "/socket.io",
      transports: ["polling"],
      forceNew: true,
      upgrade: true,
      reconnectionAttempts: 3,
      timeout: 2 * 60 * 1000,
    });
    socket.current.connect();
    socket.current.on("connect", () => {
      socket.current?.emit("join", roomId);
      setTimeout(() => {
        connected = true;
      }, 1000);
    });
    socket.current.on("connect_error", (err: any) => {
      console.log("socket error", err);
      if (err == 'timeout') {
        socket.current?.connect();
      }
    });
  };

  const setPeerConnection = async () => {
    try {
      peer.current = new RTCPeerConnection(servers);
      peer.current?.addEventListener("track", handleTracks);
      peer.current?.addEventListener("icecandidate", (e: any) => {
        if (e?.candidate) {
          socket.current?.emit("candidate", { roomId, candidate: e?.candidate ?? {} })
        }
      });

      localStream?.getTracks().forEach(track => {
        peer.current?.addTrack(track, localStream);
      });

      const offer = await peer.current?.createOffer(options);
      await peer.current?.setLocalDescription(new RTCSessionDescription(offer));
      socket.current?.emit("offer", { roomId, offer });
    } catch (error) {
      console.log("setPeerConnection error", error);
    }
  };

  const processCandidates = () => {
    if (remoteCandidates.length < 1) { return; };
    remoteCandidates.map((candidate: any) => peer.current?.addIceCandidate(candidate));
    setRemoteCandidates([]);
  };

  const handleReceivedOffer = useCallback(async ({ offer }: { offer: RTCSessionDescription | RTCSessionDescriptionInit }) => {
    if (!peer.current) return;
    try {
      await peer.current.setRemoteDescription(offer);
      const ans = await peer.current.createAnswer();
      await peer.current.setLocalDescription(new RTCSessionDescription(ans));

      processCandidates();

      socket.current?.emit("offers-answer", { roomId, ans });
    } catch (error) {
      console.log("handleReceivedOffer error", error);
    }
  }, [socket.current]);

  const handleOfferAnswer = useCallback(async ({ ans }: { ans: RTCSessionDescriptionInit }) => {
    if (!peer.current) return;
    try {
      await peer.current.setLocalDescription(ans);
    } catch (error) { }
  }, []);

  const handleNegoNeedIncomming = useCallback(async ({ offer }: { offer: RTCSessionDescription | RTCSessionDescriptionInit }) => {
    if (!peer.current) return;
    try {
      await peer.current.setRemoteDescription(offer);
      const ans = await peer.current.createAnswer();
      await peer.current.setLocalDescription(new RTCSessionDescription(ans));
      socket.current?.emit("peer:nego:done", { roomId, ans });
    } catch (error) {
      console.log("handleNegoNeedIncomming error", error);
    }
  }, [socket.current]);

  const handleNegoNeedFinal = useCallback(async ({ ans }: { ans: RTCSessionDescriptionInit }) => {
    if (!peer.current) return;
    try {
      await peer.current.setLocalDescription(ans);
    } catch (error) {
      console.log("handleNegoNeedFinal error", error);
    }
  }, []);

  const handleCandidate = useCallback(({ candidate }: any) => {
    try {
      const iceCandidate = new RTCIceCandidate(candidate);
      if (peer.current?.remoteDescription == null) {
        setRemoteCandidates(prevCandidate => [...prevCandidate, iceCandidate]);
        return;
      }
      return peer.current?.addIceCandidate(iceCandidate);
    } catch (error) {
      console.log("handleCandidate error", error);
    }
  }, []);

  useEffect(() => {
    if (socket.current) {
      socket.current.on("received-offer", handleReceivedOffer);
      socket.current.on("offers-answer", handleOfferAnswer);
      socket.current.on("peer:nego:needed", handleNegoNeedIncomming);
      socket.current.on("peer:nego:done", handleNegoNeedFinal);
      socket.current.on("candidate", handleCandidate);
    }
    return () => {
      if (socket.current) {
        socket.current.off("received-offer", handleReceivedOffer);
        socket.current.off("offers-answer", handleOfferAnswer);
        socket.current.off("peer:nego:needed", handleNegoNeedIncomming);
        socket.current.off("peer:nego:done", handleNegoNeedFinal);
        socket.current.off("candidate", handleCandidate);
      }
    }
  }, [
    socket.current,
    handleReceivedOffer,
    handleOfferAnswer,
    handleCandidate,
    handleNegoNeedIncomming,
    handleNegoNeedFinal,
  ]);

  return (
    <SafeAreaView style={styles.container}>
      <Pressable onPress={() => navigation.pop()}>
        <Text style={{ color: "#000" }}>Back</Text>
      </Pressable>
      <View style={styles.videoViewStyle}>
        {
          localStream ? (
            <>
              <View style={{ borderWidth: 5, height: "49%", width: "100%" }}>
                <RTCView
                  zOrder={0}
                  objectFit="contain"
                  style={{ flex: 1 }}
                  streamURL={localStream.toURL()}
                />
              </View>
            </>
          ) : null
        }
        {
          remoteStream ? (
            <View style={{ borderWidth: 5, height: "49%", width: "100%" }}>
              <RTCView
                zOrder={1}
                style={{ flex: 1 }}
                streamURL={remoteStream.toURL()}
              />
            </View>
          ) : null
        }
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
  },
  videoViewStyle: {
    flex: 1,
    padding: 10,
    justifyContent: "space-between",
  },
});

export default RoomView;

package.json

{
  "name": "WCam",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start",
    "test": "jest"
  },
  "dependencies": {
    "@react-navigation/native": "^6.1.7",
    "@react-navigation/native-stack": "^6.9.13",
    "react": "18.2.0",
    "react-native": "0.72.3",
    "react-native-safe-area-context": "^4.7.1",
    "react-native-screens": "^3.22.1",
    "react-native-webrtc": "^111.0.3",
    "socket.io-client": "^4.7.1"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native/eslint-config": "^0.72.2",
    "@react-native/metro-config": "^0.72.9",
    "@tsconfig/react-native": "^3.0.0",
    "@types/react": "^18.0.24",
    "@types/react-test-renderer": "^18.0.0",
    "babel-jest": "^29.2.1",
    "eslint": "^8.19.0",
    "jest": "^29.2.1",
    "metro-react-native-babel-preset": "0.76.7",
    "prettier": "^2.4.1",
    "react-test-renderer": "18.2.0",
    "typescript": "4.8.4"
  },
  "engines": {
    "node": ">=16"
  }
}
System:
  OS: macOS 12.6
  CPU: (8) arm64 Apple M1
  Memory: 94.75 MB / 8.00 GB
  Shell:
    version: 5.8.1
    path: /bin/zsh
Binaries:
  Node:
    version: 16.20.1
    path: /usr/local/bin/node
  Yarn:
    version: 1.22.19
    path: /opt/homebrew/bin/yarn
  npm:
    version: 9.7.2
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2023.06.12.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.12.1
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 22.2
      - iOS 16.2
      - macOS 13.1
      - tvOS 16.1
      - watchOS 9.1
  Android SDK: Not Found
IDEs:
  Android Studio: 2022.1 AI-221.6008.13.2211.9619390
  Xcode:
    version: 14.2/14C18
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 11.0.19
    path: /usr/bin/javac
  Ruby:
    version: 3.2.2
    path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.72.3
    wanted: 0.72.3
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

Generally speaking i’m not seeing anything too obvious :thinking:
Other than i’d do most of the logic for call handling inside a class outside of a component instead as component re-rendering due to state changes can and will cause issues.

Can you provide the logs from the devices while trying to get things connected.
Along with the error you’re experiencing in full, if any.

Should be possible to get them via xCode/Android Studio depending on platform.
Or you can use Flipper which is integrated into RN apps by default.

device 1 offer

{"sdp": "v=0
o=- 637374093836039665 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS 5d241e6c-303b-4e81-8a2b-9fd38e06f69f
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Vg+G
a=ice-pwd:vi7JHA0hYGY6GE00qmh/7yTQ
a=ice-options:trickle renomination
a=fingerprint:sha-256 DA:4E:5E:E0:8C:7A:58:89:BE:6F:90:68:F2:EF:46:44:DF:1D:91:36:CB:DC:2C:63:A5:82:EE:03:59:09:A4:AA
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 6e5b3e2a-a3d1-4e54-bc78-2ab6d61523fd
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:63 red/48000/2
a=fmtp:63 111/111
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
a=ssrc:1669300578 cname:gN994q5XTAxEqd0t
a=ssrc:1669300578 msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 6e5b3e2a-a3d1-4e54-bc78-2ab6d61523fd
m=video 9 UDP/TLS/RTP/SAVPF 98 99 39 40 100 101 127 103 104
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Vg+G
a=ice-pwd:vi7JHA0hYGY6GE00qmh/7yTQ
a=ice-options:trickle renomination
a=fingerprint:sha-256 DA:4E:5E:E0:8C:7A:58:89:BE:6F:90:68:F2:EF:46:44:DF:1D:91:36:CB:DC:2C:63:A5:82:EE:03:59:09:A4:AA
a=setup:actpass
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 8418cfc5-0f7c-490f-a242-5f4606c3519b
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:98 VP8/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:39 AV1/90000
a=rtcp-fb:39 goog-remb
a=rtcp-fb:39 transport-cc
a=rtcp-fb:39 ccm fir
a=rtcp-fb:39 nack
a=rtcp-fb:39 nack pli
a=rtpmap:40 rtx/90000
a=fmtp:40 apt=39
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 profile-id=0
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 red/90000
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=127
a=rtpmap:104 ulpfec/90000
a=ssrc-group:FID 69004228 2622992284
a=ssrc:69004228 cname:gN994q5XTAxEqd0t
a=ssrc:69004228 msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 8418cfc5-0f7c-490f-a242-5f4606c3519b
a=ssrc:2622992284 cname:gN994q5XTAxEqd0t
a=ssrc:2622992284 msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 8418cfc5-0f7c-490f-a242-5f4606c3519b
", "type": "offer"}

device 1 answer

{"sdp": "v=0
o=- 6228583487676156853 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS 4C900EF1-6A91-423E-B9A9-5E6DFC51B447
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:YlFr
a=ice-pwd:a9/9YFKnIT7KcD6e75mT2oet
a=ice-options:trickle renomination
a=fingerprint:sha-256 81:4D:5E:AA:B9:25:A5:C4:5A:70:34:DA:66:4D:06:BE:20:DD:A6:03:84:07:76:43:FA:89:58:62:C1:FC:33:13
a=setup:active
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:4C900EF1-6A91-423E-B9A9-5E6DFC51B447 092E4681-E2BC-4CE8-9276-67AF0391FDD1
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:63 red/48000/2
a=fmtp:63 111/111
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
a=ssrc:2778062490 cname:1cJoZ1v2iEmL1E1+
m=video 9 UDP/TLS/RTP/SAVPF 98 99 39 40 100 101 127 103 104
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:YlFr
a=ice-pwd:a9/9YFKnIT7KcD6e75mT2oet
a=ice-options:trickle renomination
a=fingerprint:sha-256 81:4D:5E:AA:B9:25:A5:C4:5A:70:34:DA:66:4D:06:BE:20:DD:A6:03:84:07:76:43:FA:89:58:62:C1:FC:33:13
a=setup:active
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:4C900EF1-6A91-423E-B9A9-5E6DFC51B447 BDA1CF90-4C1F-4E03-B2F4-D3FDE242C8D9
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:98 VP8/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:39 AV1/90000
a=rtcp-fb:39 goog-remb
a=rtcp-fb:39 transport-cc
a=rtcp-fb:39 ccm fir
a=rtcp-fb:39 nack
a=rtcp-fb:39 nack pli
a=rtpmap:40 rtx/90000
a=fmtp:40 apt=39
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 red/90000
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=127
a=rtpmap:104 ulpfec/90000
a=ssrc-group:FID 642066867 2783444657
a=ssrc:642066867 cname:1cJoZ1v2iEmL1E1+
a=ssrc:2783444657 cname:1cJoZ1v2iEmL1E1+
", "type": "answer"}

device 2 offer

{"sdp": "v=0
o=- 637374093836039665 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS 5d241e6c-303b-4e81-8a2b-9fd38e06f69f
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Vg+G
a=ice-pwd:vi7JHA0hYGY6GE00qmh/7yTQ
a=ice-options:trickle renomination
a=fingerprint:sha-256 DA:4E:5E:E0:8C:7A:58:89:BE:6F:90:68:F2:EF:46:44:DF:1D:91:36:CB:DC:2C:63:A5:82:EE:03:59:09:A4:AA
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 6e5b3e2a-a3d1-4e54-bc78-2ab6d61523fd
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:63 red/48000/2
a=fmtp:63 111/111
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
a=ssrc:1669300578 cname:gN994q5XTAxEqd0t
a=ssrc:1669300578 msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 6e5b3e2a-a3d1-4e54-bc78-2ab6d61523fd
m=video 9 UDP/TLS/RTP/SAVPF 98 99 39 40 100 101 127 103 104
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Vg+G
a=ice-pwd:vi7JHA0hYGY6GE00qmh/7yTQ
a=ice-options:trickle renomination
a=fingerprint:sha-256 DA:4E:5E:E0:8C:7A:58:89:BE:6F:90:68:F2:EF:46:44:DF:1D:91:36:CB:DC:2C:63:A5:82:EE:03:59:09:A4:AA
a=setup:actpass
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 8418cfc5-0f7c-490f-a242-5f4606c3519b
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:98 VP8/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:39 AV1/90000
a=rtcp-fb:39 goog-remb
a=rtcp-fb:39 transport-cc
a=rtcp-fb:39 ccm fir
a=rtcp-fb:39 nack
a=rtcp-fb:39 nack pli
a=rtpmap:40 rtx/90000
a=fmtp:40 apt=39
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 profile-id=0
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 red/90000
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=127
a=rtpmap:104 ulpfec/90000
a=ssrc-group:FID 69004228 2622992284
a=ssrc:69004228 cname:gN994q5XTAxEqd0t
a=ssrc:69004228 msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 8418cfc5-0f7c-490f-a242-5f4606c3519b
a=ssrc:2622992284 cname:gN994q5XTAxEqd0t
a=ssrc:2622992284 msid:5d241e6c-303b-4e81-8a2b-9fd38e06f69f 8418cfc5-0f7c-490f-a242-5f4606c3519b
", "type": "offer"}

device 2 answer

{"sdp": "v=0
o=- 6228583487676156853 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS 4C900EF1-6A91-423E-B9A9-5E6DFC51B447
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:YlFr
a=ice-pwd:a9/9YFKnIT7KcD6e75mT2oet
a=ice-options:trickle renomination
a=fingerprint:sha-256 81:4D:5E:AA:B9:25:A5:C4:5A:70:34:DA:66:4D:06:BE:20:DD:A6:03:84:07:76:43:FA:89:58:62:C1:FC:33:13
a=setup:active
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:4C900EF1-6A91-423E-B9A9-5E6DFC51B447 092E4681-E2BC-4CE8-9276-67AF0391FDD1
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:63 red/48000/2
a=fmtp:63 111/111
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
a=ssrc:2778062490 cname:1cJoZ1v2iEmL1E1+
m=video 9 UDP/TLS/RTP/SAVPF 98 99 39 40 100 101 127 103 104
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:YlFr
a=ice-pwd:a9/9YFKnIT7KcD6e75mT2oet
a=ice-options:trickle renomination
a=fingerprint:sha-256 81:4D:5E:AA:B9:25:A5:C4:5A:70:34:DA:66:4D:06:BE:20:DD:A6:03:84:07:76:43:FA:89:58:62:C1:FC:33:13
a=setup:active
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:4C900EF1-6A91-423E-B9A9-5E6DFC51B447 BDA1CF90-4C1F-4E03-B2F4-D3FDE242C8D9
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:98 VP8/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:39 AV1/90000
a=rtcp-fb:39 goog-remb
a=rtcp-fb:39 transport-cc
a=rtcp-fb:39 ccm fir
a=rtcp-fb:39 nack
a=rtcp-fb:39 nack pli
a=rtpmap:40 rtx/90000
a=fmtp:40 apt=39
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 red/90000
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=127
a=rtpmap:104 ulpfec/90000
a=ssrc-group:FID 642066867 2783444657
a=ssrc:642066867 cname:1cJoZ1v2iEmL1E1+
a=ssrc:2783444657 cname:1cJoZ1v2iEmL1E1+
", "type": "answer"}

error in device 2

error [Error: Session error code: ERROR_CONTENT. Session error description: Failed to apply the description for m= section with mid='0': Local fingerprint does not match identity. Expected: sha-256 1F:52:7D:EA:7B:D5:4D:45:D0:E4:71:AC:F6:09:EF:96:1F:82:08:2D:7E:9E:B2:0F:85:5C:BC:AF:F8:22:77:F4 Got: sha-256 B0:8C:CA:D7:3D:D3:77:02:EA:9A:98:EE:DF:72:89:C2:6F:F8:60:EC:24:93:34:0D:6A:A4:2C:AF:41:AD:00:4A.]

Ahhhh alrighty, that is indeed a bit of an issue.
That error would indicate the offer and answer aren’t matching due to using different fingerprints.
The answer has to correspond to some degree with the received offer.

It appears as if you are creating multiple offers and answers and of-course that mixed with sending them over to the other device which is doing the same will end up with potential mismatches.

Over here recently i explained the sequence to get a call connected correctly.
Try logging all of the events as they are happening and compare the sequence.

I tested it but is still not working. I checked it in two android 13.0 device Oneplus and google.

Logs: logs - Google Drive

I’m assuming them logs are combined from 2 devices at the same time?
Why am i seeing 3 offers and 3 answers?

Is that 3 attempted call sessions, 1 offer and answer each?
If it was then you wouldn’t be receiving the fingerprint mismatch error as each of the sessions offers and answers would match.

Also do you have anything messing with the session descriptions?
They appear to show repeated information which isn’t normal behavior.

I’m also shocked with this behaviour because my call is one to one not one to many.

I didn’t do anything with session description.

If you have any working example then please share that will be helpful.

Sadly i don’t have an example app as of yet but do plan to provide some over here in the near future.
On the other hand you can read the guide i wrote some while back which explains the sequence.
You can find that over here.

Best bet, add logging to each and every stage so you know which functions are running, how many times and even when. That would at least give you a head start.

created example with latest react-native and react-native-webrtc version :smiley: :smiley: :smiley: :smiley: :smiley:!!!

The plan is to use the latest versions and standards when the time comes :+1: