2015-12-11 69 views
1

嗨)我有一些与Android上的webrtc truble。我阅读了许多手册和教程来解决我的问题。我看到很多像我这样的问题,但它无济于事。我们创建了自己的信令服务器,并且想要加入我的Android客户端。浏览器客户端得到我的报价和Android获得浏览器答案和候选人。之后,我的应用程序关闭,没有崩溃,logcat中没有消息。拜托,有人可以帮我吗?提前致谢。我的代码无法发送视频和音频在webrtc android

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN 
      | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
      | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
      | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
      | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 
    mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_0)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_1)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_2)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_3)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_4)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_5)); 
    setContentView(R.layout.video_chat_layout); 
    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 
    sid = sharedPreferences.getString("sessionId", null); 
    peerId = getIntent().getStringArrayListExtra("peerId"); 
    Log.d("myLogs", "peerId" + peerId); 
    videoView = (GLSurfaceView) findViewById(R.id.gl_surface); 
    pbBatteryIndicator = (ProgressBar) findViewById(R.id.batteryIndicator); 
    tvPercentIndicator = (TextView) findViewById(R.id.percentIndicator); 
    ivStrengthSignal = (ImageView) findViewById(R.id.wifiStrength); 
    chronometer = (Chronometer) findViewById(R.id.chronometer); 
    finishCall = (Button) findViewById(R.id.finishCall); 
    finishCall.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      finish(); 
     } 
    }); 
    chronometer.start(); 
    videoView.setPreserveEGLContextOnPause(true); 
    videoView.setKeepScreenOn(true); 
    VideoRendererGui.setView(videoView, new Runnable() { 
     @Override 
     public void run() { 
     } 
    }); 
    try { 
     remoteRender = VideoRendererGui.create(
       REMOTE_X, REMOTE_Y, 
       REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);//for remote video 
     localRender = VideoRendererGui.create(
       LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, 
       LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);//for local video 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    initSocket(getResources().getString(R.string.endpointSocketURL), getResources().getString(R.string.endpointSocketPath), sid); 
    Log.d("myLogs", "get stun servers"); 
    MainActivity.textClock.setVisibility(View.VISIBLE); 
    MainActivity.relativeLayout.setVisibility(View.GONE); 
} 

private void initSocket(String address, String path, String sessionId){ 
    SocketService.socket.disconnect(); 
    IO.Options opts= new IO.Options(); 
    opts.transports = new String[] {PollingXHR.NAME}; 
    try { 
     opts.path = path; 
     opts.query="sessionId="+sessionId; 
     socket = IO.socket(new URI(address), opts); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
    } 
    socket.on(Socket.EVENT_ERROR, new Emitter.Listener() { 
     @Override 
     public void call(Object... args) { 
      Log.d("myLogs","error" + args[0]); 
     } 
    }); 

    socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() { 
     @Override 
     public void call(Object... args) { 
      Log.d("myLogs", "error" + args[0]); 
     } 
    }); 
    socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { 
     @Override 
     public void call(Object... args) { 
      Log.d("myLogs", "socket connected"); 
      socket.emit("stunservers", new Ack() { 
       @Override 
       public void call(Object... args) { 
        if (args[0] == null) { 
         try { 
          JSONArray array = new JSONArray(args[1].toString()); 
          Log.d("myLogs", "array stun servers length" + array.length()); 
          for (int i = 0; i < array.length(); i++) { 
           JSONObject url = array.getJSONObject(i); 
           Log.d("myLogs", "stun " + url.getString("url")); 
           iceServers.add(new PeerConnection.IceServer(url.getString("url"))); 
          } 
         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
         SocketService.socket.emit("turnservers", new Ack() { 
          @Override 
          public void call(Object... args) { 
           if (args[0] == null) { 
            try { 
             JSONArray array = new JSONArray(args[1].toString()); 
             for (int i = 0; i < array.length(); i++) { 
              JSONObject url = array.getJSONObject(i); 
              Log.d("myLogs", "turn " + url.getString("url")); 
              iceServers.add(new PeerConnection.IceServer(url.getString("url"), url.getString("username"), url.getString("credential"))); 
             } 
             init(); 

            } catch (JSONException e) { 
             e.printStackTrace(); 
            } 
           } else { 
            Log.d("myLogs", "turn servers emit" + args[0]); 
           } 
          } 
         }); 
        } else { 
         Log.d("myLogs", "error stunservers emit" + args[0]); 
        } 
       } 
      }); 

     } 
     // this is the emit from the server 
    }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() { 

     @Override 
     public void call(Object... args) { 
      Log.d("ActivityName: ", "socket disconnected"); 
     } 
    }); 
    socket.on("message", messageHandler.onMessage); 
    socket.connect(); 
} 

private void init(){ 
    Log.d("myLogs", "init"); 
    boolean peerConnection = PeerConnectionFactory.initializeAndroidGlobals(this, true, true, 
      false); 
    Log.d("myLogs", "peerConnection android globals" + peerConnection); 
    factory = new PeerConnectionFactory(); 
    pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")); 
    pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")); 
    pcConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true")); 
    Point displaySize = new Point(); 
    getWindowManager().getDefaultDisplay().getSize(displaySize); 
    lMS = factory.createLocalMediaStream("ARDAMS"); 
    MediaConstraints videoConstraints = new MediaConstraints(); 
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxHeight",Integer.toString(displaySize.x))); 
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxWidth", Integer.toString(displaySize.y))); 
    videoSource = factory.createVideoSource(getVideoCapturer(), videoConstraints); 
    AudioSource audioSource = factory.createAudioSource(new MediaConstraints()); 
    VideoTrack localVideoTrack = factory.createVideoTrack("ARDAMSv0", videoSource); 
    AudioTrack localAudioTrack =factory.createAudioTrack("ARDAMSa0", audioSource); 
    localVideoTrack.addRenderer(new VideoRenderer(localRender)); 
    localVideoTrack.addRenderer(new VideoRenderer(remoteRender)); 
    lMS.addTrack(localAudioTrack); 
    lMS.addTrack(localVideoTrack); 
    Peer peer = new Peer(peerId.get(0)); 
    Log.d("myLogs","create offer from init"); 
    peer.pc.createOffer(peer, pcConstraints); 
    //sendMessage(); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    /*videoView.onPause(); 
    if(client != null) { 
     client.onPause(); 
    }*/ 
} 

@Override 
public void onStop() { 
    /*if(client != null) { 
     client.onDestroy(); 
    }*/ 
    unregisterReceiver(this.mBatInfoReceiver); 
    unregisterReceiver(this.mWifiInfoReceiver); 
    chronometer.stop(); 
    for (Peer peer : peers.values()) { 
     peer.pc.dispose(); 
    } 
    socket.disconnect(); 
    SocketService.socket.connect(); 
    super.onStop(); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    /*videoView.onResume(); 
    if(client != null) { 
     client.onResume(); 
    }*/ 
    registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
    registerReceiver(this.mWifiInfoReceiver, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION)); 
} 

/** 
* All class and function data fo WebRTC 
*/ 
public interface Command{ 
    void execute(String peerId, JSONObject payload) throws JSONException; 
} 

public class CreateAnswerCommand implements Command{ 
    @Override 
    public void execute(String peerId, JSONObject payload) throws JSONException { 
     Log.d("myLogs","CreateAnswerCommand"); 
     Peer peer = peers.get(peerId); 
     SessionDescription sdp = new SessionDescription(
       SessionDescription.Type.fromCanonicalForm(payload.getString("type")), 
       payload.getString("sdp") 
     ); 
     peer.pc.setRemoteDescription(peer, sdp); 
     peer.pc.createAnswer(peer, pcConstraints); 
    } 
} 

public class SetRemoteSDPCommand implements Command{ 
    public void execute(String peerId, JSONObject json) throws JSONException { 
     try { 
      Log.d("myLogs","SetRemoteSdpCommand " + json.getJSONObject("payload")); 
      json.getJSONObject("payload"); 
     }catch (JSONException e){ 
      Log.d("myLogs", "error in set remote sdp can not get payload and stacktrace "); 
      e.printStackTrace(); 
     } 
     Peer peer = peers.get(peerId); 
     SessionDescription sdp = new SessionDescription(SessionDescription.Type.fromCanonicalForm(json.getJSONObject("payload").getString("type")), 
       json.getJSONObject("payload").getString("sdp")); 
     peer.pc.setRemoteDescription(peer, sdp); 
    } 
} 

public class LeaveCommand implements Command { 
    public void execute(String peerId, JSONObject payload) throws JSONException { 
     Log.d("myLogs", "LeaveCommand"); 
     sendMessage(peerId, "leave", payload); 
    } 
} 

public class AddIceCandidateCommand implements Command{ 
    public void execute(String peerId, JSONObject json) throws JSONException { 
     Log.d("myLogs","AddIceCandidateCommand"); 
     JSONObject jsonCandidate = json.getJSONObject("payload").getJSONObject("candidate"); 
     Log.d("myLogs", "AddIceCandidateCommand"); 
     PeerConnection pc = peers.get(to).pc; 
     if (pc.getRemoteDescription() != null) { 
      IceCandidate candidate = new IceCandidate(
        jsonCandidate.getString("sdpMid"), 
        jsonCandidate.getInt("sdpMLineIndex"), 
        jsonCandidate.getString("candidate") 
      ); 
      pc.addIceCandidate(candidate); 
     } 
    } 
} 

private void sendMessage(String to, String type, JSONObject payload) throws JSONException { 
    Log.d("myLogs","sendMessage" + " " + type + " " + payload.toString()); 
    if(type.equals("leave")){ 
     SocketService.socket.emit(type); 
    } 
    JSONObject message = new JSONObject(); 
    message.put("to", to); 
    message.put("sid", sid); 
    message.put("roomType", roomType); 
    message.put("type", type); 
    message.put("payload", payload); 
    message.put("prefix",prefix); 
    /*if(type.equals("answer")){ 
     message.put("from",from); 
    }*/ 
    Log.d("myLogs","send message with type" + type); 
    SocketService.socket.emit("message", message); 
} 

private class MessageHandler { 
    private HashMap<String, Command> commandMap; 

    private MessageHandler() { 
     this.commandMap = new HashMap<>(); 
     commandMap.put("offer", new CreateAnswerCommand()); 
     commandMap.put("answer", new SetRemoteSDPCommand()); 
     commandMap.put("candidate", new AddIceCandidateCommand()); 
     commandMap.put("leave", new LeaveCommand()); 
    } 

    private Emitter.Listener onMessage = new Emitter.Listener() { 
     @Override 
     public void call(Object... args) { 
      if (args[0] != null) { 
       JSONObject data = (JSONObject) args[0]; 
       try { 
        type = data.getString("type"); 
        from = data.getString("from"); 
        Log.d("myLogs", "onMessage " + type + " " + data.toString()); 
        if (type.equalsIgnoreCase("offer")) { 
         //parseJsonOfferAnswer(data); 
         commandMap.get(type).execute(to, payload); 
         Log.d("myLogs", "command map "+ type); 
        } 
        if (type.equalsIgnoreCase("answer")) { 
         //parseJsonOfferAnswer(data); 
         Log.d("myLogs", "command map " + type + "peers " + peers + peers.containsValue(from) + peers.containsKey(from)); 
         //if peer is unknown, add him 
         if(!peers.containsValue(from)) { 
          addPeer(from); 
         } 
         commandMap.get(type).execute(from, payload); 
        } 
        if (type.equalsIgnoreCase("candidate")) { 
         Log.d("myLogs", "command map "+ type); 
         commandMap.get(type).execute(from, payload); 
         parseJsonCandidate(data.getJSONObject("payload").getJSONObject("candidate")); 
        } 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
      else { 
       Log.d("myLogs", "error " + args[0]); 
      } 
     } 
    }; 
} 

private void parseJsonOfferAnswer(JSONObject json) throws JSONException { 
    to = json.getString("to"); 
    type = json.getString("type"); 
    sid = json.getString("sid"); 
    roomType = json.getString("roomType"); 
    from = json.getString("from"); 
    payload = json.getJSONObject("payload"); 
    sdpPayload = payload.getString("sdp"); 
    typePayload = payload.getString("type"); 
    if(type.equals("answer")){ 
     from = json.getString("from"); 
    } 
} 

private void parseJsonCandidate(JSONObject candidate) throws JSONException { 
    this.candidate = candidate.getString("candidate"); 
    this.sdpMid = candidate.getString("sdpMid"); 
    this.sdpMLineIndex = candidate.getString("sdpMLineIndex"); 
} 

private class Peer implements SdpObserver, PeerConnection.Observer{ 
    private PeerConnection pc; 
    private String id; 

    @Override 
    public void onIceConnectionReceivingChange(boolean b) { 

    } 

    @Override 
    public void onCreateSuccess(final SessionDescription sdp) { 
     Log.d("myLogs","onCreateSuccess " + sdp.type.canonicalForm()); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        JSONObject message = new JSONObject(); 
        JSONObject payload = new JSONObject(); 
        payload.put("type", sdp.type.canonicalForm()); 
        payload.put("sdp", sdp.description); 
        message.put("payload", payload); 
        sendMessage(id, sdp.type.canonicalForm(), payload); 
        pc.setLocalDescription(Peer.this, sdp); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    @Override 
    public void onSetSuccess() { 
     Log.d("myLogs","onSetSuccess"); 
     runOnUiThread(new Runnable() { 
      public void run() { 
       //pc.createAnswer(Peer.this, pcConstraints); 
      } 
     }); 
    } 

    @Override 
    public void onCreateFailure(String s) { 
     Log.d("myLogs", "onCreateFailure " + s); 
    } 

    @Override 
    public void onSetFailure(String s) { 
     Log.d("myLogs", "onSetFailure " + s); 
    } 

    @Override 
    public void onSignalingChange(PeerConnection.SignalingState signalingState) { 
     Log.d("myLogs","onSignalChange " + signalingState); 
     if(signalingState == PeerConnection.SignalingState.CLOSED) { 
      removePeer(id); 
     } 

    } 

    @Override 
    public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) { 
     Log.d("myLogs","onIceConnectionChange " + iceConnectionState); 
    } 

    @Override 
    public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) { 
     Log.d("myLogs","onIceGatheringChange " + iceGatheringState); 
    } 

    @Override 
    public void onIceCandidate(final IceCandidate candidate) { 
     Log.d("myLogs","onIceCandidate "); 
     pc.addIceCandidate(candidate); 
     runOnUiThread(new Runnable() { 
      public void run() { 
       try { 
        JSONObject payload = new JSONObject(); 
        JSONObject candidateJson = new JSONObject(); 
        candidateJson.put("candidate", candidate.sdp); 
        payload.put("candidate", candidateJson); 
        payload.put("sdpMid", candidate.sdpMid); 
        payload.put("sdpMLineIndex", candidate.sdpMLineIndex); 
        sendMessage(id, "candidate", payload); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 


    @Override 
    public void onDataChannel(DataChannel dataChannel) { 
     Log.d("myLogs","onDataChannel"); 
    } 

    @Override 
    public void onRenegotiationNeeded() { 
     Log.d("myLogs","onRenegotiationNeeded"); 
    } 

    @Override 
    public void onAddStream(MediaStream mediaStream) { 
     Log.d("myLogs","onAddStream"); 
     mediaStream.videoTracks.get(0).addRenderer(new VideoRenderer(remoteRender)); 
     VideoRendererGui.update(remoteRender, 
       REMOTE_X, REMOTE_Y, 
       REMOTE_WIDTH, REMOTE_HEIGHT, scalingType,false); 
     VideoRendererGui.update(localRender, 
       LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, 
       LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED, 
       scalingType, true); 
    } 

    @Override 
    public void onRemoveStream(MediaStream mediaStream) { 
     Log.d("myLogs","onRemoveStream"); 
     removePeer(id); 
    } 

    public Peer(String id) { 
     Log.d("myLogs","initialize peer id"); 
     if(SocketService.iceServers.size()>0) 
      this.pc = factory.createPeerConnection(SocketService.iceServers, pcConstraints, this); 
     else{ 
      Log.d("myLogs","error to get turn and stun servers "); 
     } 
     pc.createOffer(this,pcConstraints); 
     this.id = id; 
    } 
} 

public VideoCapturer getVideoCapturer() { 
    Log.d("myLogs", "getVideoCapture"); 
    /*String name; 
    // Returns the number of camera devices 
    VideoCapturerAndroid.getDeviceCount(); 
    // Returns the front face device name 
    name = VideoCapturerAndroid.getNameOfFrontFacingDevice(); 
    // Creates a VideoCapturerAndroid instance for the device name*/ 
    String cameraDeviceName; 
    String frontCameraDeviceName = CameraEnumerationAndroid.getNameOfFrontFacingDevice(); 
    VideoCapturer videoCapturer; 
    cameraDeviceName = frontCameraDeviceName; 
    videoCapturer = VideoCapturerAndroid.create(cameraDeviceName); 
    return videoCapturer; 
} 

public void addPeer(String id) { 
    Log.d("myLogs","addPeer" + id); 
    Peer peer = new Peer(id); 
    peer.pc.addStream(lMS); 
    peers.put(id, peer); 
} 

public void removePeer(String id) { 
    Log.d("myLogs","removePeer" + id); 
    Peer peer = peers.get(id); 
    peer.pc.close(); 
    peer.pc.dispose(); 
    peers.remove(peer.id); 
} 

回答

1

我解决了我的问题。它的绝对工作代码)

private ProgressBar pbBatteryIndicator; 
private TextView tvPercentIndicator; 
private Button finishCall; 
private ImageView ivStrengthSignal; 
private Chronometer chronometer; 
private WifiManager mWifiManager; 
private ArrayList<Drawable> strengthWifiIcon = new ArrayList<>(); 
// Local preview screen position before call is connected. 
private static final int LOCAL_X_CONNECTING = 0; 
private static final int LOCAL_Y_CONNECTING = 0; 
private static final int LOCAL_WIDTH_CONNECTING = 100; 
private static final int LOCAL_HEIGHT_CONNECTING = 100; 
// Local preview screen position after call is connected. 
private static final int LOCAL_X_CONNECTED = 72; 
private static final int LOCAL_Y_CONNECTED = 72; 
private static final int LOCAL_WIDTH_CONNECTED = 25; 
private static final int LOCAL_HEIGHT_CONNECTED = 25; 
// Remote video screen position 
private static final int REMOTE_X = 0; 
private static final int REMOTE_Y = 0; 
private static final int REMOTE_WIDTH = 100; 
private static final int REMOTE_HEIGHT = 100; 
private RendererCommon.ScalingType scalingType = RendererCommon.ScalingType.SCALE_ASPECT_FILL; 
private VideoRenderer.Callbacks localRender; 
private VideoRenderer.Callbacks remoteRender; 
//private String mSocketAddress; 
private GLSurfaceView videoView; 
private ArrayList<String> peerId = new ArrayList<>(); 
public String roomType="video",to,from,sid,type,prefix = "webkit"; 
private JSONObject payload; 
private HashMap<String, Peer> peers = new HashMap<>(); 
private MediaConstraints pcConstraints = new MediaConstraints(); 
private MediaStream lMS; 
private PeerConnectionFactory factory; 
private final MessageHandler messageHandler = new MessageHandler(); 
private SharedPreferences sharedPreferences; 
private VideoSource videoSource; 
public LinkedList<PeerConnection.IceServer> iceServers = new LinkedList<>(); 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN 
      | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
      | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
      | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
      | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 
    mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_0)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_1)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_2)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_3)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_4)); 
    strengthWifiIcon.add(getResources().getDrawable(R.drawable.signal_5)); 
    setContentView(R.layout.video_chat_layout); 
    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 
    sid = sharedPreferences.getString("sessionId", null); 
    peerId = getIntent().getStringArrayListExtra("peerId"); 
    Log.d("myLogs", "peerId" + peerId); 
    videoView = (GLSurfaceView) findViewById(R.id.gl_surface); 
    pbBatteryIndicator = (ProgressBar) findViewById(R.id.batteryIndicator); 
    tvPercentIndicator = (TextView) findViewById(R.id.percentIndicator); 
    ivStrengthSignal = (ImageView) findViewById(R.id.wifiStrength); 
    chronometer = (Chronometer) findViewById(R.id.chronometer); 
    finishCall = (Button) findViewById(R.id.finishCall); 
    finishCall.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      /*socket.emit("leave", new Ack() { 
       @Override 
       public void call(Object... args) { 
        finish(); 
       } 
      });*/ 
      finish(); 
     } 
    }); 
    chronometer.start(); 
    videoView.setPreserveEGLContextOnPause(true); 
    videoView.setKeepScreenOn(true); 
    VideoRendererGui.setView(videoView, new Runnable() { 
     @Override 
     public void run() { 
     } 
    }); 
    try { 
     remoteRender = VideoRendererGui.create(
       REMOTE_X, REMOTE_Y, 
       REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);//for remote video 
     localRender = VideoRendererGui.create(
       LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, 
       LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);//for local video 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    Log.d("myLogs", "get stun servers"); 
    getStunTurnServers(); 
    MainActivity.textClock.setVisibility(View.VISIBLE); 
    MainActivity.relativeLayout.setVisibility(View.GONE); 
} 

private void getStunTurnServers(){ 
    SocketService.socket.on("message",messageHandler.onMessage); 
    SocketService.socket.emit("stunservers", new Ack() { 
     @Override 
     public void call(Object... args) { 
      if (args[0] == null) { 
       try { 
        JSONArray array = new JSONArray(args[1].toString()); 
        Log.d("myLogs", "array stun servers length" + array.length()); 
        for (int i = 0; i < 50; i++) { 
         JSONObject url = array.getJSONObject(i); 
         Log.d("myLogs", "stun " + url.getString("url")); 
         iceServers.add(new PeerConnection.IceServer(url.getString("url"))); 
        } 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
       SocketService.socket.emit("turnservers", new Ack() { 
        @Override 
        public void call(Object... args) { 
         if (args[0] == null) { 
          try { 
           JSONArray array = new JSONArray(args[1].toString()); 
           for (int i = 0; i < array.length(); i++) { 
            JSONObject url = array.getJSONObject(i); 
            Log.d("myLogs", "turn " + url.getString("url")); 
            iceServers.add(new PeerConnection.IceServer(url.getString("url"), url.getString("username"), url.getString("credential"))); 
           } 
           init(); 
          } catch (JSONException e) { 
           e.printStackTrace(); 
          } 
         } else { 
          Log.d("myLogs", "turn servers emit" + args[0]); 
         } 
        } 
       }); 
      } else { 
       Log.d("myLogs", "error stunservers emit" + args[0]); 
      } 
     } 
    }); 
} 

private void init(){ 
    Log.d("myLogs", "init"); 
    boolean peerConnection = PeerConnectionFactory.initializeAndroidGlobals(this, true, true, true); 
    Log.d("myLogs", "peerConnection android globals " + peerConnection); 
    factory = new PeerConnectionFactory(); 
    pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")); 
    pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")); 
    pcConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true")); 
    Point displaySize = new Point(); 
    getWindowManager().getDefaultDisplay().getSize(displaySize); 
    lMS = factory.createLocalMediaStream("ARDAMS"); 
    MediaConstraints videoConstraints = new MediaConstraints(); 
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxHeight",Integer.toString(displaySize.x))); 
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxWidth", Integer.toString(displaySize.y))); 
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxFrameRate", Integer.toString(30))); 
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("minFrameRate", Integer.toString(30))); 
    videoSource = factory.createVideoSource(getVideoCapturer(), videoConstraints); 
    AudioSource audioSource = factory.createAudioSource(new MediaConstraints()); 
    VideoTrack localVideoTrack = factory.createVideoTrack("ARDAMSv0", videoSource); 
    AudioTrack localAudioTrack =factory.createAudioTrack("ARDAMSa0", audioSource); 
    lMS.addTrack(localAudioTrack); 
    lMS.addTrack(localVideoTrack); 
    onLocalStream(lMS); 
    for(int i=0;i<peerId.size();i++){ 
     Peer peer = new Peer(peerId.get(i)); 
     peers.put(peerId.get(i), peer); 
     Log.d("myLogs", "create offer from init"); 
     peer.pc.createOffer(peer, pcConstraints); 
    } 

} 

@Override 
public void onPause() { 
    super.onPause(); 
} 

@Override 
public void onStop() { 
    unregisterReceiver(this.mBatInfoReceiver); 
    unregisterReceiver(this.mWifiInfoReceiver); 
    chronometer.stop(); 
    /*for (Peer peer : peers.values()) { 
     peer.pc.dispose(); 
    }*/ 
    //videoSource.dispose(); 
    //factory.dispose(); 
    SocketService.socket.disconnect(); 
    SocketService.socket.connect(); 
    super.onStop(); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
    registerReceiver(this.mWifiInfoReceiver, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION)); 
} 

/** 
* All class and function data for WebRTC 
*/ 
public interface Command{ 
    void execute(String peerId, JSONObject payload) throws JSONException; 
} 

public class CreateAnswerCommand implements Command{ 
    @Override 
    public void execute(String peerId, JSONObject payload) throws JSONException { 
     Log.d("myLogs", "CreateAnswerCommand"); 
     Peer peer = peers.get(peerId); 
     SessionDescription sdp = new SessionDescription(SessionDescription.Type.fromCanonicalForm(payload.getString("type")), 
       payload.getString("sdp") 
     ); 
     peer.pc.setRemoteDescription(peer, sdp); 
     peer.pc.createAnswer(peer, pcConstraints); 
    } 
} 

public class SetRemoteSDPCommand implements Command{ 
    public void execute(String peerId, JSONObject payload) throws JSONException { 
     Log.d("myLogs", "SetRemoteSdpCommand "); 
     Peer peer = peers.get(peerId); 
     SessionDescription sdp = new SessionDescription(SessionDescription.Type.fromCanonicalForm(payload.getString("type")), payload.getString("sdp")); 
     peer.pc.setRemoteDescription(peer, sdp); 
     if(payload.getString("type").equalsIgnoreCase("answer")){ 
      //peer.pc.createAnswer(peer, pcConstraints); 
     } 
    } 
} 

public class AddIceCandidateCommand implements Command{ 
    public void execute(String peerId, JSONObject payload) throws JSONException { 
     JSONObject jsonCandidate = payload.getJSONObject("candidate"); 
     Log.d("myLogs", "AddIceCandidateCommand"); 
     PeerConnection pc = peers.get(peerId).pc; 
     if (pc.getRemoteDescription() != null) { 
      Log.d("myLogs", "AddIceCandidateCommand "+jsonCandidate.toString()); 
      IceCandidate candidate = new IceCandidate(
        jsonCandidate.getString("sdpMid"), 
        jsonCandidate.getInt("sdpMLineIndex"), 
        jsonCandidate.getString("candidate") 
      ); 
      pc.addIceCandidate(candidate); 
     } 
    } 
} 

private void sendMessage(String to, String type, JSONObject payload) throws JSONException { 
    Log.d("myLogs","sendMessage" + " " + type + " " + payload.toString()); 
    if(type.equals("leave")){ 
     SocketService.socket.emit(type); 
    } 
    JSONObject message = new JSONObject(); 
    message.put("to", to); 
    message.put("sid", sid); 
    message.put("roomType", roomType); 
    message.put("type", type); 
    message.put("payload", payload); 
    message.put("prefix",prefix); 
    Log.d("myLogs", "send message with type" + type); 
    SocketService.socket.emit("message", message); 
} 

private class MessageHandler { 
    private HashMap<String, Command> commandMap; 

    private MessageHandler() { 
     this.commandMap = new HashMap<>(); 
     commandMap.put("offer", new CreateAnswerCommand()); 
     commandMap.put("answer", new SetRemoteSDPCommand()); 
     commandMap.put("candidate", new AddIceCandidateCommand()); 
    } 

    private Emitter.Listener onMessage = new Emitter.Listener() { 
     @Override 
     public void call(Object... args) { 
      Log.d("myLogs", "on message listener"); 
      if (args[0] != null) { 
       JSONObject data = (JSONObject) args[0]; 
       try { 
        type = data.getString("type"); 
        payload = data.getJSONObject("payload"); 
        Log.d("myLogs", "onMessage " + type + " " + data.toString()); 
        if(type.equalsIgnoreCase("answer")) { 
         from = data.getString("from"); 
         Log.d("myLogs", "equals ignore case answer" + from); 
        } 
        if(!peers.containsKey(from)) { 
         addPeer(from); 
         commandMap.get(type).execute(from, payload); 
        } 
        else{ 
         commandMap.get(type).execute(from, payload); 
        } 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 
} 


private class Peer implements SdpObserver, PeerConnection.Observer{ 
    private PeerConnection pc; 
    private String id; 

    @Override 
    public void onIceConnectionReceivingChange(boolean b) { 

    } 

    @Override 
    public void onCreateSuccess(final SessionDescription sdp) { 
     Log.d("myLogs","onCreateSuccess " + sdp.type.canonicalForm()); 
     try { 
      JSONObject payload = new JSONObject(); 
      payload.put("type", sdp.type.canonicalForm()); 
      payload.put("sdp", sdp.description); 
      sendMessage(id, sdp.type.canonicalForm(), payload); 
      pc.setLocalDescription(Peer.this, sdp); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onSetSuccess() { 
     Log.d("myLogs","onSetSuccess"); 
     //pc.createAnswer(this,pcConstraints); 
    } 

    @Override 
    public void onCreateFailure(String s) { 
     Log.d("myLogs", "onCreateFailure " + s); 
    } 

    @Override 
    public void onSetFailure(String s) { 
     Log.d("myLogs", "onSetFailure " + s); 
    } 

    @Override 
    public void onSignalingChange(PeerConnection.SignalingState signalingState) { 
     Log.d("myLogs", "onSignalChange " + signalingState); 
     if(signalingState == PeerConnection.SignalingState.CLOSED) { 
      removePeer(id); 
     } 
    } 

    @Override 
    public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) { 
     Log.d("myLogs", "onIceConnectionChange " + iceConnectionState); 
    } 

    @Override 
    public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) { 
     Log.d("myLogs","onIceGatheringChange " + iceGatheringState); 
    } 

    @Override 
    public void onIceCandidate(final IceCandidate candidate) { 
     Log.d("myLogs","onIceCandidate " + candidate.sdp); 
     if(candidate.sdp.isEmpty()){ 
      Log.d("myLogs","candidate is empty"); 
     } 
     try { 
      JSONObject payload = new JSONObject(); 
      JSONObject candidateJson = new JSONObject(); 
      candidateJson.put("candidate", candidate.sdp); 
      candidateJson.put("sdpMid", candidate.sdpMid); 
      candidateJson.put("sdpMLineIndex", candidate.sdpMLineIndex); 
      payload.put("candidate", candidateJson); 
      sendMessage(id, "candidate", payload); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onDataChannel(DataChannel dataChannel) { 
     Log.d("myLogs","onDataChannel"); 
    } 

    @Override 
    public void onRenegotiationNeeded() { 
     Log.d("myLogs","onRenegotiationNeeded"); 
    } 

    @Override 
    public void onAddStream(MediaStream mediaStream) { 
     Log.d("myLogs", "onAddRemoteStream " + mediaStream.label()); 
     onAddRemoteStream(mediaStream); 
    } 

    @Override 
    public void onRemoveStream(MediaStream mediaStream) { 
     Log.d("myLogs", "onRemoveStream "+mediaStream.label()); 
     removePeer(id); 
    } 

    public Peer(String id) { 
     Log.d("myLog s", "initialize peer id"); 
     if(iceServers.size()>0) 
      this.pc = factory.createPeerConnection(iceServers, pcConstraints, this); 
     else{ 
      Log.d("myLogs","error to get turn and stun servers "); 
     } 
     this.id = id; 
    } 
} 

public VideoCapturer getVideoCapturer() { 
    Log.d("myLogs", "getVideoCapture"); 
    String cameraDeviceName; 
    String frontCameraDeviceName = CameraEnumerationAndroid.getNameOfFrontFacingDevice(); 
    VideoCapturer videoCapturer; 
    cameraDeviceName = frontCameraDeviceName; 
    videoCapturer = VideoCapturerAndroid.create(cameraDeviceName); 
    return videoCapturer; 
} 

public void addPeer(String id) { 
    Log.d("myLogs","addPeer" + id); 
    Peer peer = new Peer(id); 
    peer.pc.addStream(lMS); 
    peers.put(id, peer); 
} 

public void removePeer(String id) { 
    Log.d("myLogs","removePeer" + id); 
    Peer peer = peers.get(id); 
    peer.pc.close(); 
    peer.pc.dispose(); 
    peers.remove(peer.id); 
} 

private void onLocalStream(MediaStream localStream){ 
    localStream.videoTracks.get(0).addRenderer(new VideoRenderer(localRender)); 
    VideoRendererGui.update(localRender, 
      LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, 
      LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED, 
      scalingType,true); 
} 

private void onAddRemoteStream(MediaStream remoteStream){ 
    remoteStream.videoTracks.get(0).addRenderer(new VideoRenderer(remoteRender)); 
    VideoRendererGui.update(remoteRender, 
      REMOTE_X, REMOTE_Y, 
      REMOTE_WIDTH, REMOTE_HEIGHT, scalingType,false); 
    VideoRendererGui.update(localRender, 
      LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, 
      LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED, 
      scalingType,true); 
} 
+0

你能帮我建立我自己的信令服务器和android webrtc api的完整实现吗? –

+0

我只能帮助执行android webrtc。所有信令服务器具有相同的结构并发送类似的消息。它的[示例](https://github.com/pchab/AndroidRTC)对我很有帮助 –

+0

谢谢我已经在我的应用中实现了webrtc,并通过[this](http://www.html5rocks)的帮助来理解它。 com/en/tutorials/webrtc/basics /),但在构建信号服务器时遇到了一些困难,但我也设法使用firebase做到这一点 –

相关问题