1

For a few days I have a problem that I do not understand at all. Everything seems to be working well, finally everything should be working well with everything I read right and left and all my tries. I would like to share audio and video on android with Webrtc from client A to client B and vice versa.

The problem is that when onAddStream(MediaStream mediaStream) is called I have mediaStream.videoTracks.get(0).state() = LIVE and mediaStream.videoTracks.size()) = 1 but 0 frames received in the Remoterender. (But on both clients everything is OK in the Localrender).

I think the problem is a network issue in that when client B creates the response to client A's offer it only receives half of the candidate ices and only audio with sdpindex at 0.

I don't understand why! (I tried on different emulator or real phone devices and different networks always the same)

Here is the code I am using. I specify that I know it's not the best, but for my tests I use a somewhat rudimentary signaling server with the Google Volley library and an SQL database instead of node or Firebase database.

If anyone has any idea why I only have audio on client B, or 0 frames in the remoteRender.

public void createPeerConnection() {
        if (mPeerConnection != null) return;
        final ArrayList<PeerConnection.IceServer> iceServers = new ArrayList<>();
         iceServers.add(PeerConnection.IceServer.builder("stun:stun1.l.google.com:19302").createIceServer());
     iceServers.add(PeerConnection.IceServer.builder("stun:stun2.l.google.com:19302").createIceServer());
      iceServers.add(PeerConnection.IceServer.builder("stun:stun3.l.google.com:19302").createIceServer());
      iceServers.add(PeerConnection.IceServer.builder("stun:stun4.l.google.com:19302").createIceServer());
        iceServers.add(PeerConnection.IceServer.builder("stun:relay.meterd.ca:80").createIceServer());
        iceServers.add(PeerConnection.IceServer.builder("turn:relay.meterd.ca:80").setUsername("877d7df597a8a3c4hf48275566").setPassword("tmprAF+d/lDMEzbfAhtt").createIceServer());
        iceServers.add(PeerConnection.IceServer.builder("turn:relay.meterd.ca:443").setUsername("877d7df597a8a3c4hf48275566").setPassword("tmprAF+d/lDMEzbfAhtt").createIceServer());
        iceServers.add(PeerConnection.IceServer.builder("turn:relay.metered.ca:443?transport=tcp").setUsername("877d7df597a8a3c4hf48275566").setPassword("tmprAF+d/lDMEzbfAhtt").createIceServer());
        mPeerConnection = mFactory.createPeerConnection(rtcConfiguration, this);
        Log.d(TAG, "Peer Connection created");

    }

    Connection(final Context context, ConnectionListener listener) {
        final PeerConnectionFactory.InitializationOptions options = PeerConnectionFactory.InitializationOptions.builder(context)
               .setEnableInternalTracer(true)
                .setFieldTrials("WebRTC-H264HighProfile/Enabled/")
                .createInitializationOptions();
        final VideoEncoderFactory encoderFactory;
        final VideoDecoderFactory decoderFactory;
     encoderFactory = new SoftwareVideoEncoderFactory();
     decoderFactory = new SoftwareVideoDecoderFactory();
    
        PeerConnectionFactory.initialize(options);
        PeerConnectionFactory.Options options1 = new PeerConnectionFactory.Options();
     options1.disableEncryption = true;
     options1.disableNetworkMonitor  =  true;

        mFactory = PeerConnectionFactory.builder()
                .setOptions(options1)
                .setVideoEncoderFactory(encoderFactory)
                .setVideoDecoderFactory(decoderFactory)
                .createPeerConnectionFactory();
                 mListener = listener;
    }

   public void initializeMediaDevices(final Context context,  SurfaceViewRenderer localRenderer) throws Exception {

        MediaStream mMediaStream = mFactory.createLocalMediaStream(MEDIA_STREAM_ID);;
         mVideoCapturer =   createCameraCapturer(context);
        final VideoSource videoSource = mFactory.createVideoSource(false);

      //  videoSource.adaptOutputFormat(VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_FPS);
        final EglBase.Context eglContext = EglBase.create().getEglBaseContext();
        final SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("captureThread", eglContext);
        mVideoCapturer.initialize(surfaceTextureHelper, context, videoSource.getCapturerObserver());

        localRenderer.init(eglContext, new RendererCommon.RendererEvents() {
            @Override
            public void onFirstFrameRendered() {
                Log.d(TAG, "onFirstFrameRendered");
            }

            @Override
            public void onFrameResolutionChanged(int i, int i1, int i2) {
                Log.d(TAG, "Frame resolution changed");
                Log.d(TAG, "Frame resolution changed : "+i);
                Log.d(TAG, "Frame resolution changed : "+i1);
                Log.d(TAG, "Frame resolution changed : "+i2);
            }
        });

    localRenderer.setEnableHardwareScaler(true);

        mVideoCapturer.startCapture(VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_FPS);

      //  localRenderer.setEnableHardwareScaler(true);
        final VideoTrack videoTrack = mFactory.createVideoTrack(VIDEO_TRACK_ID, videoSource);
        videoTrack.setEnabled(true);
       localRenderer.setMirror(true);
       videoTrack.addSink(localRenderer);

      final AudioSource audioSource = mFactory.createAudioSource(new MediaConstraints());
   final AudioTrack audioTrack = mFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource);
    audioTrack.setEnabled(true);
      //  audioTrack.setEnabled(true);
      //  audioTrack.setVolume(100);

      mMediaStream.addTrack(videoTrack);
       mMediaStream.addTrack(audioTrack);
   mPeerConnection.addStream(mMediaStream);
 public void createOffer() {
        final MediaConstraints mediaConstraints = new MediaConstraints();
        mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
      mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
      
        mPeerConnection.createOffer(new SdpObserver() {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                mListener.createofferonCreateSuccess(sessionDescription);
                mPeerConnection.setLocalDescription(this, sessionDescription);
            }

            @Override
            public void onSetSuccess() {
                Log.d(TAG, "Local description set success");

                mListener.createofferonSetSuccess();
            }

            @Override
            public void onCreateFailure(String s) {
                Log.e(TAG, "Failed to create local offer error:" + s);
            }

            @Override
            public void onSetFailure(String s) {
                Log.e(TAG, "Failed to set local description error:" + s);
            }
        }, mediaConstraints);
    }
public static void createAnswerFromRemoteOffer(final String remoteOffer) {
        SdpObserver observer = new SdpObserver() {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                Log.d(TAG, "Local answer created");
                mPeerConnection.setLocalDescription(this,sessionDescription);
                mListener.createAnswerFromRemoteOffercreatesuccess(sessionDescription);
            }
    
            @Override
            public void onSetSuccess() {
                mListener.createAnswerFromRemoteOfferSetsuccess();
                Log.d(TAG, "Set offer description was successful");
            }
    
            @Override
            public void onCreateFailure(String s) {
                Log.e(TAG, "Failed to create local answer error:" + s);
            }
    
            @Override
            public void onSetFailure(String s) {
                Log.e(TAG, "Failed to set offer description error :" + s);
            }
        };
    
      final    SessionDescription sessionDescription = new SessionDescription(SessionDescription.Type.OFFER, remoteOffer);
      final MediaConstraints mediaConstraintss = new MediaConstraints();
       mediaConstraintss.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
      mediaConstraintss.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
    
        mPeerConnection.setRemoteDescription(observer, sessionDescription) ;
        mPeerConnection.createAnswer(observer,  new MediaConstraints());
    }
 public static void createAnswerFromRemoteOffer2(final String remoteOffer) {
        SdpObserver observer = new SdpObserver() {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                Log.d(TAG, "Local answer created 3");

                mListener.createAnswerFromRemoteOffer2onCreateSucess(sessionDescription);
            }

            @Override
            public void onSetSuccess() {
                mListener.createAnswerFromRemoteOffer2onSetSuces();
                Log.d(TAG, "Set offer description 3  was successful");
            }

            @Override
            public void onCreateFailure(String s) {
                Log.e(TAG, "Failed to create local 3 answer error:" + s);
            }

            @Override
            public void onSetFailure(String s) {
                Log.e(TAG, "Failed to set offer 3 description error :" + s);
            }
        };
  final SessionDescription sessionDescription = new SessionDescription(SessionDescription.Type.ANSWER, remoteOffer);
        mPeerConnection.setRemoteDescription(observer, sessionDescription) ;
    }

  public static void addRemoteIceCandidate(final JSONObject iceCandidateData) throws JSONException {
        String icecandidate = iceCandidateData.getString("ICECANDIDATE");
        final String sdpmid = iceCandidateData.getString("SDPMID");
        final int sdpMLineIndex = iceCandidateData.getInt("SDPINDEX");
        IceCandidate iceCandidate = new IceCandidate(sdpmid, sdpMLineIndex, icecandidate);

        Log.d(TAG,"add remote candidate "+iceCandidate.toString());
        Log.d(TAG,"add remote sdpmid "+sdpmid);
        Log.d(TAG,"add remote sdpindex "+sdpMLineIndex);

         if (queuedRemoteCandidates != null) {
            queuedRemoteCandidates.add(iceCandidate);
       } else {
            mPeerConnection.addIceCandidate(iceCandidate);
       }

    }

CLIENT B only audio candidate

2023-03-19 16:08:17.575 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:1800307301 1 udp 2122187263 fec0::5054:ff:fe12:3456 59467 typ host generation 0 ufrag iT+A network-id 2::UNKNOWN
2023-03-19 16:08:17.579 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:841689039 1 udp 2122129151 10.0.2.16 37211 typ host generation 0 ufrag iT+A network-id 5 network-cost 10::UNKNOWN
2023-03-19 16:08:17.583 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:3776784094 1 udp 2122056191 fec0::9ebc:2b3f:a56d:1ed8 48463 typ host generation 0 ufrag iT+A network-id 6 network-cost 10::UNKNOWN
2023-03-19 16:08:17.585 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:559267639 1 udp 2122005759 ::1 33214 typ host generation 0 ufrag iT+A network-id 4::UNKNOWN
2023-03-19 16:08:17.591 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:1510613869 1 udp 2121932543 127.0.0.1 54583 typ host generation 0 ufrag iT+A network-id 3::UNKNOWN
2023-03-19 16:08:17.626 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:1847424209 1 tcp 1518280447 10.0.2.15 55839 typ host tcptype passive generation 0 ufrag iT+A network-id 1::UNKNOWN
2023-03-19 16:08:17.632 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:1889982791 1 udp 1685921535 92.134.12.255 63997 typ srflx raddr 10.0.2.16 rport 37211 generation 0 ufrag iT+A network-id 5 network-cost 10:stun:64.233.163.127:19302:UNKNOWN
2023-03-19 16:08:17.636 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:634224277 1 tcp 1518207487 fec0::5054:ff:fe12:3456 43771 typ host tcptype passive generation 0 ufrag iT+A network-id 2::UNKNOWN
2023-03-19 16:08:17.651 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:2091440959 1 tcp 1518149375 10.0.2.16 47563 typ host tcptype passive generation 0 ufrag iT+A network-id 5 network-cost 10::UNKNOWN
2023-03-19 16:08:17.690 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:2946423342 1 tcp 1518076415 fec0::9ebc:2b3f:a56d:1ed8 51819 typ host tcptype passive generation 0 ufrag iT+A network-id 6 network-cost 10::UNKNOWN
2023-03-19 16:08:17.695 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:1645442729 1 udp 1686052607 92.134.12.255 63999 typ srflx raddr 10.0.2.15 rport 56570 generation 0 ufrag iT+A network-id 1:stun:64.233.163.127:19302:UNKNOWN
2023-03-19 16:08:17.702 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:1876313031 1 tcp 1518025983 ::1 52341 typ host tcptype passive generation 0 ufrag iT+A network-id 4::UNKNOWN
2023-03-19 16:08:17.707 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:344579997 1 tcp 1517952767 127.0.0.1 53745 typ host tcptype passive generation 0 ufrag iT+A network-id 3::UNKNOWN
2023-03-19 16:08:17.711 29728-29772 CCC                     pid-29728                            D  onIceCandidateReceived : audio:0:candidate:2181291358 1 udp 1685858559 2a01:cb10:8bce:d100:e429:c6d5:f617:76b6 64000 typ srflx raddr fec0::9ebc:2b3f:a56d:1ed8 rport 48463 generation 0 ufrag iT+A network-id 6 network-cost 10:stun:2a00:1450:4010:c06::7f:19302:UNKNOWN

CLIENT A audio and video candidate

2023-03-19 16:08:07.023  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:2091440959 1 tcp 1518149375 10.0.2.16 59483 typ host tcptype passive generation 0 ufrag 5HN1 network-id 5 network-cost 10::UNKNOWN
2023-03-19 16:08:07.023  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:1942891970 1 tcp 1518076415 fec0::523e:50b8:47ba:4673 47321 typ host tcptype passive generation 0 ufrag 5HN1 network-id 6 network-cost 10::UNKNOWN
2023-03-19 16:08:07.023  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:1876313031 1 tcp 1518025983 ::1 52945 typ host tcptype passive generation 0 ufrag 5HN1 network-id 4::UNKNOWN
2023-03-19 16:08:07.078  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:344579997 1 tcp 1517952767 127.0.0.1 37085 typ host tcptype passive generation 0 ufrag 5HN1 network-id 3::UNKNOWN
2023-03-19 16:08:07.082  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:1847424209 1 tcp 1518280447 10.0.2.15 41627 typ host tcptype passive generation 0 ufrag 5HN1 network-id 1::UNKNOWN
2023-03-19 16:08:07.085  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:634224277 1 tcp 1518207487 fec0::5054:ff:fe12:3456 55563 typ host tcptype passive generation 0 ufrag 5HN1 network-id 2::UNKNOWN
2023-03-19 16:08:07.089  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:2091440959 1 tcp 1518149375 10.0.2.16 51877 typ host tcptype passive generation 0 ufrag 5HN1 network-id 5 network-cost 10::UNKNOWN
2023-03-19 16:08:07.101  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:1942891970 1 tcp 1518076415 fec0::523e:50b8:47ba:4673 46365 typ host tcptype passive generation 0 ufrag 5HN1 network-id 6 network-cost 10::UNKNOWN
2023-03-19 16:08:07.102  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:1876313031 1 tcp 1518025983 ::1 33561 typ host tcptype passive generation 0 ufrag 5HN1 network-id 4::UNKNOWN
2023-03-19 16:08:07.103  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:344579997 1 tcp 1517952767 127.0.0.1 56545 typ host tcptype passive generation 0 ufrag 5HN1 network-id 3::UNKNOWN
2023-03-19 16:08:07.103  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:1582508722 1 udp 1685858559 2a01:cb10:8bce:d100:e429:c6d5:f617:76b6 63983 typ srflx raddr fec0::523e:50b8:47ba:4673 rport 43345 generation 0 ufrag 5HN1 network-id 6 network-cost 10:stun:2a00:1450:4010:c06::7f:19302:UNKNOWN
2023-03-19 16:08:07.152  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:1645442729 1 udp 1686052607 92.134.12.255 63981 typ srflx raddr 10.0.2.15 rport 35078 generation 0 ufrag 5HN1 network-id 1:stun:64.233.163.127:19302:UNKNOWN
2023-03-19 16:08:07.154  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:1889982791 1 udp 1685921535 92.134.12.255 63982 typ srflx raddr 10.0.2.16 rport 45157 generation 0 ufrag 5HN1 network-id 5 network-cost 10:stun:64.233.163.127:19302:UNKNOWN
2023-03-19 16:08:07.159  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:1645442729 1 udp 1686052607 92.134.12.255 63984 typ srflx raddr 10.0.2.15 rport 34609 generation 0 ufrag 5HN1 network-id 1:stun:64.233.163.127:19302:UNKNOWN
2023-03-19 16:08:07.165  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:1582508722 1 udp 1685858559 2a01:cb10:8bce:d100:e429:c6d5:f617:76b6 63988 typ srflx raddr fec0::523e:50b8:47ba:4673 rport 59153 generation 0 ufrag 5HN1 network-id 6 network-cost 10:stun:2a00:1450:4010:c06::7f:19302:UNKNOWN
2023-03-19 16:08:07.168  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:1889982791 1 udp 1685921535 92.134.12.255 63985 typ srflx raddr 10.0.2.16 rport 33873 generation 0 ufrag 5HN1 network-id 5 network-cost 10:stun:64.233.163.127:19302:UNKNOWN
2023-03-19 16:08:07.773  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:3729096449 1 udp 25108223 216.39.253.20 43389 typ relay raddr 92.134.12.255 rport 57285 generation 0 ufrag 5HN1 network-id 1:turn:216.39.253.20:443?transport=tcp:UNKNOWN
2023-03-19 16:08:07.774  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : audio:0:candidate:3729096449 1 udp 24977151 216.39.253.20 36391 typ relay raddr 92.134.12.255 rport 57284 generation 0 ufrag 5HN1 network-id 5 network-cost 10:turn:216.39.253.20:443?transport=tcp:UNKNOWN
2023-03-19 16:08:07.783  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:3729096449 1 udp 25108223 216.39.253.20 41892 typ relay raddr 92.134.12.255 rport 57286 generation 0 ufrag 5HN1 network-id 1:turn:216.39.253.20:443?transport=tcp:UNKNOWN
2023-03-19 16:08:07.784  9017-9059  CCC                     pid-9017                             D  onIceCandidateReceived : video:1:candidate:3729096449 1 udp 24977151 216.39.253.20 43228 typ relay raddr 92.134.12.255 rport 57287 generation 0 ufrag 5HN1 network-id 5 network-cost 10:turn:216.39.253.20:443?transport=tcp:UNKNOWN`

0 frames on client A and B on remoteRender, but the localRender good and display it

2023-03-19 16:08:35.861 29728-29779 org.webrtc.Logging      pid-29728                            I  CameraStatistics: Camera fps: 11.
2023-03-19 16:08:37.690 29728-29950 org.webrtc.Logging      pid-29728                            I  EglRenderer: remoteRendererDuration: 4003 ms. Frames received: 0. Dropped: 0. Rendered: 0. Render fps: .0. Average render time: NA. Average swapBuffer time: NA.
2023-03-19 16:08:37.862 29728-29779 org.webrtc.Logging      pid-29728                            I  CameraStatistics: Camera fps: 12.
2023-03-19 16:08:39.757 29728-29780 org.webrtc.Logging      pid-29728                            I  EglRenderer: local_viewDuration: 4003 ms. Frames received: 45. Dropped: 0. Rendered: 45. Render fps: 11.2. Average render time: 1100 us. Average swapBuffer time: 987 us.
2023-03-19 16:08:39.863 29728-29779 org.webrtc.Logging      pid-29728                            I  CameraStatistics: Camera fps: 11.
2023-03-19 16:08:41.696 29728-29950 org.webrtc.Logging      pid-29728                            I  EglRenderer: remoteRendererDuration: 4005 ms. Frames received: 0. Dropped: 0. Rendered: 0. Render fps: .0. Average render time: NA. Average swapBuffer time: NA.
2023-03-19 16:08:41.864 29728-29779 org.webrtc.Logging      pid-29728                            I  CameraStatistics: Camera fps: 12.
2023-03-19 16:08:43.758 29728-29780 org.webrtc.Logging      pid-29728                            I  EglRenderer: local_viewDuration: 4001 ms. Frames received: 45. Dropped: 0. Rendered: 45. Render fps: 11.2. Average render time: 1107 us. Average swapBuffer time: 980 us.
2023-03-19 16:08:43.865 29728-29779 org.webrtc.Logging      pid-29728                            I  CameraStatistics: Camera fps: 11.
2023-03-19 16:08:45.702 29728-29950 org.webrtc.Logging      pid-29728                            I  EglRenderer: remoteRendererDuration: 4006 ms. Frames received: 0. Dropped: 0. Rendered: 0. Render fps: .0. Average render time: NA. Average swapBuffer time: NA.
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Tokens
  • 11
  • 3
  • Welcome to SO! I think there should be a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example)! – Andy A. Mar 22 '23 at 07:51

0 Answers0