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);
}
你能帮我建立我自己的信令服务器和android webrtc api的完整实现吗? –
我只能帮助执行android webrtc。所有信令服务器具有相同的结构并发送类似的消息。它的[示例](https://github.com/pchab/AndroidRTC)对我很有帮助 –
谢谢我已经在我的应用中实现了webrtc,并通过[this](http://www.html5rocks)的帮助来理解它。 com/en/tutorials/webrtc/basics /),但在构建信号服务器时遇到了一些困难,但我也设法使用firebase做到这一点 –