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 } ] }