2

I am attempting to receive video from a computer device camera to Android App. I am using Google's libwebrtc library.

implementation("org.webrtc:google-webrtc:1.0.32006")

I am making peer connection using a signaling server with REST Apis. I am building a peer connection factory and then Peer connection. Then I am creating SDP offer which I am getting form the libwebrtc library. I am sending SDP offer to signaling server over REST API. I am getting the answer over REST API(calling it repetitively). Then providing the answer to peer connection. But after all these steps I am getting 0 frames

I/org.webrtc.Logging: EglRenderer: svrDuration: 4016 ms. Frames received: 0. Dropped: 0. Rendered: 0. Render fps: .0. Average render time: NA. Average swapBuffer time: NA.

Peer Connection:

PeerConnectionFactory.InitializationOptions options = PeerConnectionFactory.
                InitializationOptions.builder(getApplicationContext())
                .setEnableInternalTracer(true)
                .setFieldTrials("WebRTC-H264HighProfile/Enabled/")
                .createInitializationOptions();

        PeerConnectionFactory.initialize(options);

rootEglBase = EglBase.create();

PeerConnectionFactory.Options factoryOptions = new PeerConnectionFactory.Options();
factoryOptions.disableEncryption = true;
factoryOptions.disableNetworkMonitor = true;

PeerConnectionFactory factory = PeerConnectionFactory.builder()
        .setVideoDecoderFactory(new DefaultVideoDecoderFactory(rootEglBase.getEglBaseContext()))
        .setVideoEncoderFactory(new DefaultVideoEncoderFactory(rootEglBase.getEglBaseContext(), true, true))
        .setOptions(factoryOptions)
        .createPeerConnectionFactory();

peerConnection = createPeerConnection(factory);
createDataChannel();

Creating peer connection and observing

    //Building RTC Config
        PeerConnection.RTCConfiguration rtcConfig =
                new PeerConnection.RTCConfiguration(iceServers);
        // TCP candidates are only useful when connecting to a server that supports
        // ICE-TCP.
        rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED;
        rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE;
        rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE;
        rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY;
        // Use ECDSA encryption.
        rtcConfig.keyType = PeerConnection.KeyType.ECDSA;
        // Enable DTLS for normal calls and disable for loopback calls.
//        rtcConfig.enableDtlsSrtp = !peerConnectionParameters.loopback;
        rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN;

        //PeerConnection Observer
        PeerConnection.Observer pcObserver = new PeerConnectionObserver() {

            @Override
            public void onIceCandidate(IceCandidate iceCandidate) {
                Log.d(TAG, "onIceCandidate: ");
                peerConnection.addIceCandidate(iceCandidate);
            }

            @Override
            public void onAddStream(MediaStream mediaStream) {
                Log.d(TAG, "onAddStream: " + mediaStream.videoTracks.size());
                VideoTrack remoteVideoTrack = mediaStream.videoTracks.get(0);
                remoteVideoTrack.setEnabled(true);
                remoteVideoTrack.addSink(binding.svr);
            }
        };

        //Creating Peer Connection
        return factory.createPeerConnection(rtcConfig, pcObserver);

Creating and sending the offer

MediaConstraints sdpMediaConstraints = offerConstraint();

        peerConnection.createOffer(new SimpleSdpObserver() {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                Log.d(TAG, "onCreateSuccess: Creating offer");
                //sending offer over REST API

            }
        }, sdpMediaConstraints);

Providing remote answer to peer connection

SessionDescription sessionDescription = new SessionDescription(SessionDescription.Type.ANSWER, sdp);
        peerConnection.setRemoteDescription(new SimpleSdpObserver(), sessionDescription);
        peerConnection.getStats(new RTCStatsCollectorCallback() {
            @Override
            public void onStatsDelivered(RTCStatsReport rtcStatsReport) {
                Log.d(TAG, rtcStatsReport.toString());
            }
        });

Creating Media Constraints

MediaConstraints mediaConstraints = new MediaConstraints();
        ArrayList<MediaConstraints.KeyValuePair> keyValuePairs = new ArrayList<>();
//I want video only
//        keyValuePairs.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
        keyValuePairs.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
        mediaConstraints.mandatory.addAll(keyValuePairs);
        return mediaConstraints;

Stats from library

{ timestampUs: 1627320290808253, stats: [
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_100, payloadType: 100, mimeType: "video/H264", clockRate: 90000, sdpFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f" },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_101, payloadType: 101, mimeType: "video/rtx", clockRate: 90000, sdpFmtpLine: "apt=100" },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_104, payloadType: 104, mimeType: "video/red", clockRate: 90000 },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_106, payloadType: 106, mimeType: "video/ulpfec", clockRate: 90000 },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_124, payloadType: 124, mimeType: "video/rtx", clockRate: 90000, sdpFmtpLine: "apt=104" },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_125, payloadType: 125, mimeType: "video/rtx", clockRate: 90000, sdpFmtpLine: "apt=127" },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_127, payloadType: 127, mimeType: "video/H264", clockRate: 90000, sdpFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f" },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_96, payloadType: 96, mimeType: "video/VP8", clockRate: 90000 },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_97, payloadType: 97, mimeType: "video/rtx", clockRate: 90000, sdpFmtpLine: "apt=96" },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_98, payloadType: 98, mimeType: "video/VP9", clockRate: 90000 },
{ timestampUs: 1627320290808253, type: codec, id: RTCCodec_0_Inbound_99, payloadType: 99, mimeType: "video/rtx", clockRate: 90000, sdpFmtpLine: "apt=98" },
{ timestampUs: 1627320290808253, type: peer-connection, id: RTCPeerConnection, dataChannelsOpened: 0, dataChannelsClosed: 0 },
{ timestampUs: 1627320290808253, type: transport, id: RTCTransport_0_1, bytesSent: 0, packetsSent: 0, bytesReceived: 0, packetsReceived: 0, dtlsState: "new", selectedCandidatePairChanges: 0 } ] }
  • Have you fixed your issue? I suggest you to listen "onConnectionChange" to check if you got any connection, by stats transport it looks like you didn't got CONNECTED state. – Vadim Eksler Oct 11 '21 at 05:34

0 Answers0