Android WebRTC 未接收要显示的帧,获取 0 帧

问题描述

我正在尝试从计算机设备摄像头接收视频到 Android 应用程序。我正在使用 Google 的 libwebrtc 库。

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

我正在使用带有 REST API 的信令服务器建立对等连接。我正在构建一个对等连接工厂,然后是对等连接。然后我正在创建从 libwebrtc 库中获得的 SDP 报价。我正在通过 REST API 向信令服务器发送 SDP 报价。我正在通过 REST API 得到答案(重复调用它)。然后提供对等连接的答案。但在所有这些步骤之后,我得到了 0 帧

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.

对等连接:

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();

创建对等连接并观察

    //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);

创建和发送优惠

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);

为对等连接提供远程应答

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());
            }
        });

创建媒体约束

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;

来自图书馆的统计数据

{ 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,id: RTCCodec_0_Inbound_101,payloadType: 101,mimeType: "video/rtx",sdpFmtpLine: "apt=100" },id: RTCCodec_0_Inbound_104,payloadType: 104,mimeType: "video/red",clockRate: 90000 },id: RTCCodec_0_Inbound_106,payloadType: 106,mimeType: "video/ulpfec",id: RTCCodec_0_Inbound_124,payloadType: 124,sdpFmtpLine: "apt=104" },id: RTCCodec_0_Inbound_125,payloadType: 125,sdpFmtpLine: "apt=127" },id: RTCCodec_0_Inbound_127,payloadType: 127,sdpFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f" },id: RTCCodec_0_Inbound_96,payloadType: 96,mimeType: "video/VP8",id: RTCCodec_0_Inbound_97,payloadType: 97,sdpFmtpLine: "apt=96" },id: RTCCodec_0_Inbound_98,payloadType: 98,mimeType: "video/VP9",id: RTCCodec_0_Inbound_99,payloadType: 99,sdpFmtpLine: "apt=98" },type: peer-connection,id: RTCPeerConnection,dataChannelsOpened: 0,dataChannelsClosed: 0 },type: transport,id: RTCTransport_0_1,bytesSent: 0,packetsSent: 0,bytesReceived: 0,packetsReceived: 0,dtlsstate: "new",selectedCandidatePairChanges: 0 } ] }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)