实施群组通话(很多2个)kurento-room-client-android

时间:2018-11-25 05:35:21

标签: android kurento

我可以使用nubomedia(kurento-room-client-android)实现一对一视频通话,但是无法实现多个视频通话。请指导我。我可以在onRemoteStreamAdded方法上获得多个视频流。我检查不同用户的onIceCandiate状态。只有一个本地和一个远程iceCandidate状态已连接并完成,其余的远程用户仍在检查中。出于测试目的,我编写了onRemoteStreamAdded代码。请不要判断。

public class PeerVideoActivity extends AppCompatActivity
    implements NBMWebRTCPeer.Observer, RoomListener {
  private static final String TAG = "PeerVideoActivity";
  private String usrArr;
  private NBMWebRTCPeer nbmWebRTCPeer;
  private SurfaceViewRenderer masterViewFirst, masterViewSecond;
  private boolean masterViewFirstAdded=false, masterViewSecondAdded=false;
  private SurfaceViewRenderer localView;
  private Map<Integer, String> videoRequestUserMapping;
  private int publishVideoRequestId;
  private TextView mCallStatus;
  private String username;
  private boolean isAdded = false;
  private HorizontalVideoStreamAdapter horizontalAdapter;
  private RecyclerView horizontal_recycler_view;
  private boolean isRemoteStreamAdded = false;
  private boolean backPressed = false;
  private Thread backPressedThread = null;
  private HashMap<String, Boolean> generateOfferMap, sendOfferMap, iceCandidtateMap;
  private ArrayList<MediaStream> remoteStreamList;
  private Handler mHandler = null;
  private CallState callState;

  private enum CallState {
    IDLE,
    PUBLISHING,
    PUBLISHED,
    WAITING_REMOTE_USER,
    RECEIVING_REMOTE_USER
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_conference);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    mHandler = new Handler();
    masterViewFirst = (SurfaceViewRenderer) findViewById(R.id.gl_surface_first);
    masterViewSecond= (SurfaceViewRenderer) findViewById(R.id.gl_surface_second);
    horizontal_recycler_view = (RecyclerView) findViewById(R.id.horizontal_recycler_view);
    remoteStreamList = new ArrayList<>();
    localView = (SurfaceViewRenderer) findViewById(R.id.gl_surface_local);
    this.mCallStatus = (TextView) findViewById(R.id.call_status);
    callState = CallState.IDLE;
    MainActivity.getKurentoRoomAPIInstance().addObserver(this);
  }

  @Override
  protected void onStart() {
    super.onStart();

    Bundle extras = getIntent().getExtras();
    this.username = extras.getString(Constants.USER_NAME, "");
    usrArr = extras.getString("usrArr");
    Log.i(TAG, "username: " + username);
    generateOfferMap = getUserMap();
    iceCandidtateMap = getUserMap();
    sendOfferMap = getUserMap();
    EglBase rootEglBase = EglBase.create();
    masterViewFirst.init(rootEglBase.getEglBaseContext(), null);
    masterViewFirst.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
    masterViewSecond.init(rootEglBase.getEglBaseContext(), null);
    masterViewSecond.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
    localView.init(rootEglBase.getEglBaseContext(), null);
    localView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);

    NBMMediaConfiguration peerConnectionParameters =
        new NBMMediaConfiguration(NBMMediaConfiguration.NBMRendererType.OPENGLES,
            NBMMediaConfiguration.NBMAudioCodec.OPUS, 0, NBMMediaConfiguration.NBMVideoCodec.VP8, 0,
            new NBMMediaConfiguration.NBMVideoFormat(320, 240, PixelFormat.RGB_888, 30),
            NBMMediaConfiguration.NBMCameraPosition.FRONT);

    videoRequestUserMapping = new HashMap<>();
    nbmWebRTCPeer = new NBMWebRTCPeer(peerConnectionParameters, this, localView, this);
    //nbmWebRTCPeer.registerMasterRenderer(masterViewFirst);
    //nbmWebRTCPeer.registerMasterRenderer(masterViewSecond);
    horizontalAdapter = new HorizontalVideoStreamAdapter(remoteStreamList, this, nbmWebRTCPeer,
        masterViewFirst, masterViewSecond);
    LinearLayoutManager horizontalLayoutManager =
        new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    horizontal_recycler_view.setLayoutManager(horizontalLayoutManager);
    horizontal_recycler_view.setAdapter(horizontalAdapter);
    Log.i(TAG, "Initializing nbmWebRTCPeer...");
    nbmWebRTCPeer.initialize();
    callState = CallState.PUBLISHING;
    mCallStatus.setText("Publishing...");
  }

  @Override
  protected void onStop() {
    //endCall();
    super.onStop();
  }

  @Override
  protected void onPause() {
    //nbmWebRTCPeer.stopLocalMedia();
    super.onPause();
  }

  @Override
  protected void onResume() {
    super.onResume();
    nbmWebRTCPeer.startLocalMedia();
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
  }

/*    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_video_chat, menu);
        return true;
    }*/

/*    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }*/

  @Override
  public void onBackPressed() {
    // If back button has not been pressed in a while then trigger thread and toast notification
    if (!this.backPressed) {
      this.backPressed = true;
      Toast.makeText(this, "Press back again to end.", Toast.LENGTH_SHORT).show();
      this.backPressedThread = new Thread(new Runnable() {
        @Override
        public void run() {
          try {
            Thread.sleep(1000);
            backPressed = false;
          } catch (InterruptedException e) {
            Log.d("VCA-oBP", "Successfully interrupted");
          }
        }
      });
      this.backPressedThread.start();
    }
    // If button pressed the second time then call super back pressed
    // (eventually calls onDestroy)
    else {
      if (this.backPressedThread != null) this.backPressedThread.interrupt();
      super.onBackPressed();
    }
  }

  public void hangup(View view) {
    finish();
  }

  private void GenerateOfferForRemote(String remote_name) {
    nbmWebRTCPeer.generateOffer(remote_name, false);
    callState = CallState.WAITING_REMOTE_USER;
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        mCallStatus.setText(R.string.waiting_remote_stream);
      }
    });
  }

  public void receiveFromRemote(View view) {
    //GenerateOfferForRemote();
  }

  /**
   * Terminates the current call and ends activity
   */
  /*  private void endCall() {
        callState = CallState.IDLE;
        try
        {
            if (nbmWebRTCPeer != null) {
                nbmWebRTCPeer.close();
                nbmWebRTCPeer = null;
            }
        }
        catch (Exception e){e.printStackTrace();}
    }*/
  @Override
  public void onInitialize() {
    if (nbmWebRTCPeer != null) nbmWebRTCPeer.generateOffer("local", true);
  }

  @Override
  public void onLocalSdpOfferGenerated(final SessionDescription sessionDescription,
      final NBMPeerConnection nbmPeerConnection) {
    if (callState == CallState.PUBLISHING || callState == CallState.PUBLISHED) {
      Log.d(TAG, "local " + sessionDescription.type);
      //publishVideoRequestId = ++Constants.id;
      Log.i("sendPublishVideo", username);
      MainActivity.getKurentoRoomAPIInstance()
          .sendPublishVideo(sessionDescription.description, username);
    } else { // Asking for remote user video
      Log.d(TAG, "remote " + sessionDescription.type);
      if (sendOfferMap != null) {
        for (Map.Entry<String, Boolean> entry : sendOfferMap.entrySet()) {
          if (entry.getValue()) {
            MainActivity.getKurentoRoomAPIInstance()
                .sendPublishVideo(sessionDescription.description, entry.getKey());
            entry.setValue(false);
          }
        }
      }
    }
  }

  @Override
  public void onLocalSdpAnswerGenerated(SessionDescription sessionDescription,
      NBMPeerConnection nbmPeerConnection) {
  }

  @Override
  public void onIceCandidate(IceCandidate iceCandidate, NBMPeerConnection nbmPeerConnection) {
    int sendIceCandidateRequestId = ++Constants.id;
    if (callState == CallState.PUBLISHING || callState == CallState.PUBLISHED) {
      MainActivity.getKurentoRoomAPIInstance()
          .sendOnIceCandidate(this.username, iceCandidate.sdp, iceCandidate.sdpMid,
              Integer.toString(iceCandidate.sdpMLineIndex));
    } else {
      if (iceCandidtateMap != null) {
        for (Map.Entry<String, Boolean> entry : iceCandidtateMap.entrySet()) {
          if (entry.getValue()) {
            MainActivity.getKurentoRoomAPIInstance()
                .sendOnIceCandidate(entry.getKey(), iceCandidate.sdp, iceCandidate.sdpMid,
                    Integer.toString(iceCandidate.sdpMLineIndex));
            entry.setValue(false);
          }
        }
      }
      //MainActivity.getKurentoRoomAPIInstance().sendOnIceCandidate(nbmPeerConnection.getConnectionId(), iceCandidate.sdp,
      //        iceCandidate.sdpMid, Integer.toString(iceCandidate.sdpMLineIndex), sendIceCandidateRequestId);
    }
  }

  @Override
  public void onIceStatusChanged(PeerConnection.IceConnectionState iceConnectionState,
      NBMPeerConnection nbmPeerConnection) {
    Log.i(TAG, "onIceStatusChanged");
  }

  @Override
  public void onRemoteStreamAdded(final MediaStream mediaStream,
      final NBMPeerConnection nbmPeerConnection) {
    Log.i(TAG, "Enter onRemoteStreamAdded");
    if (!nbmPeerConnection.getConnectionId().equalsIgnoreCase("local")) {
      remoteStreamList.add(mediaStream);

      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          mCallStatus.setText("");

          if(remoteStreamList != null) {
            if (remoteStreamList.size() == 1) {
              //nbmWebRTCPeer.attachRendererToRemoteStream(masterViewFirst, remoteStreamList.get(0));
              remoteStreamList.get(0).videoTracks.get(0).addRenderer(new VideoRenderer(masterViewFirst));
            } else if (remoteStreamList.size() ==2) {
              remoteStreamList.get(1).videoTracks.get(0).addRenderer(new VideoRenderer(masterViewSecond));
            }
          }
        }
      });
    }
    Log.i(TAG, "onRemoteStreamAdded :" + remoteStreamList.size());
    Log.i(TAG, "Exit onRemoteStreamAdded");
    }

    @Override public void onRemoteStreamRemoved (MediaStream mediaStream, NBMPeerConnection
    nbmPeerConnection){
      Log.i(TAG, "onRemoteStreamRemoved");
    }

    @Override public void onPeerConnectionError (String s){
      Log.i(TAG, "onPeerConnectionError:" + s);
    }

    @Override public void onDataChannel (DataChannel dataChannel, NBMPeerConnection connection){
      Log.i(TAG, "[datachannel] Peer opened data channel");
    }

    @Override public void onBufferedAmountChange ( long l, NBMPeerConnection connection, DataChannel
    channel){

    }

    public void sendHelloMessage (DataChannel channel){
        /*byte[] rawMessage = "Hello Peer!".getBytes(Charset.forName("UTF-8"));
        ByteBuffer directData = ByteBuffer.allocateDirect(rawMessage.length);
        directData.put(rawMessage);
        directData.flip();
        DataChannel.Buffer data = new DataChannel.Buffer(directData, false);
        channel.send(data);*/
    }

    @Override public void onStateChange (NBMPeerConnection connection, DataChannel channel){
      Log.i(TAG, "[datachannel] DataChannel onStateChange: " + channel.state());
       /* if (channel.state() == DataChannel.State.OPEN) {
            sendHelloMessage(channel);
            Log.i(TAG, "[datachannel] Datachannel open, sending first hello");
        }*/
    }

    @Override public void onMessage (DataChannel.Buffer buffer, NBMPeerConnection
    connection, DataChannel channel){
      Log.i(TAG, "[datachannel] Message received: " + buffer.toString());
      //sendHelloMessage(channel);
    }

/*    private Runnable offerWhenReady = new Runnable() {
      @Override
      public void run() {
        // Generate offers to receive video from all peers in the room
        if (generateOfferMap != null) {
          for (Map.Entry<String, Boolean> entry : generateOfferMap.entrySet()) {
            if (entry.getValue()) {
              GenerateOfferForRemote(entry.getKey());
              Log.i(TAG, "I'm " + username + " DERP: Generating offer for peer " + entry.getKey());
              // Set value to false so that if this function is called again we won't
              // generate another offer for this user
              entry.setValue(false);
            }
          }
        }
      }
    };*/

  private void offerWhenReady(){
    if (generateOfferMap != null) {
      for (Map.Entry<String, Boolean> entry : generateOfferMap.entrySet()) {
        if (entry.getValue()) {
          GenerateOfferForRemote(entry.getKey());
          Log.i(TAG, "I'm " + username + " DERP: Generating offer for peer " + entry.getKey());
          // Set value to false so that if this function is called again we won't
          // generate another offer for this user
          entry.setValue(false);
        }
      }
    }
  }

    @Override public void onRoomResponse (/*RoomResponse*/ String response){
      Log.d(TAG, "OnRoomResponse:" + response);
      if (response != null) {
        try {
          JSONObject obj = new JSONObject(response);
          if (obj.getString("rsp").equals("answer")) {
            if (obj.getString("answer") != null) {
              SessionDescription sd =
                  new SessionDescription(SessionDescription.Type.ANSWER, obj.getString("answer"));

              // Check if we are waiting for publication of our own vide
              if (callState == CallState.PUBLISHING) {
                callState = CallState.PUBLISHED;
                nbmWebRTCPeer.processAnswer(sd, "local");
                //mHandler.postDelayed(offerWhenReady, 2000);
                offerWhenReady();

                // Check if we are waiting for the video publication of the other peer
              } else if (callState == CallState.WAITING_REMOTE_USER) {
                //String user_name = Integer.toString(publishVideoRequestId);
                callState = CallState.RECEIVING_REMOTE_USER;
                //String connectionId = videoRequestUserMapping.get(publishVideoRequestId);
                String connectionId = obj.getString("userId");
                nbmWebRTCPeer.processAnswer(sd, connectionId);
              } else {
                callState = CallState.RECEIVING_REMOTE_USER;
                //String connectionId = videoRequestUserMapping.get(publishVideoRequestId);
                String connectionId = obj.getString("userId");
                nbmWebRTCPeer.processAnswer(sd, connectionId);
              }
            }
          } else if (obj.getString("rsp") != null) {
            if (obj.getString("rsp").equals(RoomListener.METHOD_ICE_CANDIDATE)) {
              JSONObject childObj = obj.getJSONObject("candidate");
              String sdpMid = childObj.getString("sdpMid");
              int sdpMLineIndex = Integer.valueOf(childObj.get("sdpMLineIndex").toString());
              String sdp = childObj.getString("candidate");
              String userId = obj.getString("userId");
              IceCandidate ic = new IceCandidate(sdpMid, sdpMLineIndex, sdp);

              if (callState == CallState.PUBLISHING || callState == CallState.PUBLISHED) {
                nbmWebRTCPeer.addRemoteIceCandidate(ic, "local");
              } else {
                nbmWebRTCPeer.addRemoteIceCandidate(ic, userId);
              }
            }
          }
        } catch (JSONException e) {
          e.printStackTrace();
        }
      }
       /* int requestId =response.getId();

        if (requestId == publishVideoRequestId){

            SessionDescription sd = new SessionDescription(SessionDescription.Type.ANSWER,
                                                            response.getValue("sdpAnswer").get(0));

            // Check if we are waiting for publication of our own vide
            if (callState == CallState.PUBLISHING){
                callState = CallState.PUBLISHED;
                nbmWebRTCPeer.processAnswer(sd, "local");
                mHandler.postDelayed(offerWhenReady, 2000);

            // Check if we are waiting for the video publication of the other peer
            } else if (callState == CallState.WAITING_REMOTE_USER){
                //String user_name = Integer.toString(publishVideoRequestId);
                callState = CallState.RECEIVING_REMOTE_USER;
                String connectionId = videoRequestUserMapping.get(publishVideoRequestId);
                nbmWebRTCPeer.processAnswer(sd, connectionId);
            }
        }*/

    }

    @Override public void onRoomError (RoomError error){
      Log.e(TAG, "OnRoomError:" + error);
    }

    @Override public void onRoomNotification (RoomNotification notification){
      Log.i(TAG, "OnRoomNotification (state=" + callState.toString() + "):" + notification);
/*        Map<String, Object> map = notification.getParams();

        if(notification.getMethod().equals(RoomListener.METHOD_ICE_CANDIDATE)) {
            String sdpMid = map.get("sdpMid").toString();
            int sdpMLineIndex = Integer.valueOf(map.get("sdpMLineIndex").toString());
            String sdp = map.get("candidate").toString();
            IceCandidate ic = new IceCandidate(sdpMid, sdpMLineIndex, sdp);

            if (callState == CallState.PUBLISHING || callState == CallState.PUBLISHED) {
                nbmWebRTCPeer.addRemoteIceCandidate(ic, "local");
            } else {
                nbmWebRTCPeer.addRemoteIceCandidate(ic, "remote");
            }
        }

        // Somebody in the room published their video
        else if(notification.getMethod().equals(RoomListener.METHOD_PARTICIPANT_PUBLISHED)) {
            mHandler.postDelayed(offerWhenReady, 2000);
        }*/
    }

    @Override public void onRoomConnected () {
    }

    @Override public void onRoomDisconnected () {
      Utils.showFinishingError(this, "Disconnected", "You have been disconnected from room.");
    }

    private HashMap<String, Boolean> getUserMap () {
      HashMap<String, Boolean> map = new HashMap<>();
      if (usrArr != null) {
        try {
          JSONArray arr = new JSONArray(usrArr);
          if (arr.length() > 0) {
            map = new HashMap();
            for (int i = 0; i < arr.length(); i++) {
              JSONObject obj = (JSONObject) arr.get(i);
              map.put(obj.getString("userId"), true);
              //GenerateOfferForRemote(obj.getString("userId"));
            }
          }
        } catch (JSONException e) {
          e.printStackTrace();
        }
      }
      return map;
    }
  }

0 个答案:

没有答案