【发布时间】:2016-04-06 17:39:33
【问题描述】:
我正在尝试开发 Android 应用程序,它将通过 webrtc 协议在设备之间发送音频和视频。此代码适用于 Android 和 Web 界面,但不适用于两个 Android。每次打开连接,弹窗提示设备已连接,但没有声音和画面。我尝试了很多东西,但没有任何帮助。依赖项和权限都可以。使用了我自己的 PubNub 的 pub 和 sub 密钥。它在两个 Android 之间打开了 20 次中的第 1 次连接,所以我认为这里有些地方不太好。
按照本教程创建应用程序:tutorial
我发现了这个错误image
相机在某处崩溃,但我真的不知道为什么。
public static final String VIDEO_TRACK_ID = "videoPN";
public static final String AUDIO_TRACK_ID = "audioPN";
public static final String LOCAL_MEDIA_STREAM_ID = "localStreamPN";
private PnRTCClient pnRTCClient;
private VideoSource localVideoSource;
private VideoRenderer.Callbacks localRender;
private VideoRenderer.Callbacks remoteRender;
private GLSurfaceView mVideoView;
private String username;
private class MyRTCListener extends PnRTCListener {
@Override
public void onLocalStream(final MediaStream localStream) {
VideoChatActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if(localStream.videoTracks.size()==0) return;
localStream.videoTracks.get(0).addRenderer(new VideoRenderer(localRender));
}
});
}
@Override
public void onAddRemoteStream(final MediaStream remoteStream, final PnPeer peer) {
VideoChatActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(VideoChatActivity.this,"Connected to " + peer.getId(), Toast.LENGTH_SHORT).show();
try {
if(remoteStream.videoTracks.size()==0) return;
remoteStream.videoTracks.get(0).addRenderer(new VideoRenderer(remoteRender));
VideoRendererGui.update(remoteRender, 0, 0, 100, 100, VideoRendererGui.ScalingType.SCALE_ASPECT_FILL, false);
VideoRendererGui.update(localRender, 72, 72, 25, 25, VideoRendererGui.ScalingType.SCALE_ASPECT_FIT, true);
}
catch (Exception e){ e.printStackTrace(); }
}
});
}
@Override
public void onPeerConnectionClosed(PnPeer peer) {
Intent intent = new Intent(VideoChatActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videochatactivity);
Bundle extras = getIntent().getExtras();
if (extras == null || !extras.containsKey(Constants.USER_NAME)) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
Toast.makeText(this, "Need to pass username to VideoChatActivity in intent extras (Constants.USER_NAME).",
Toast.LENGTH_SHORT).show();
finish();
return;
}
this.username = extras.getString(Constants.USER_NAME, "");
PeerConnectionFactory.initializeAndroidGlobals(
this, // Context
true, // Audio Enabled
true, // Video Enabled
true, // Hardware Acceleration Enabled
null); // Render EGL Context
PeerConnectionFactory pcFactory = new PeerConnectionFactory();
this.pnRTCClient = new PnRTCClient(Constants.PUB_KEY, Constants.SUB_KEY, this.username);
int camNumber = VideoCapturerAndroid.getDeviceCount();
String frontFacingCam = VideoCapturerAndroid.getNameOfFrontFacingDevice();
String backFacingCam = VideoCapturerAndroid.getNameOfBackFacingDevice();
VideoCapturerAndroid capturer = (VideoCapturerAndroid) VideoCapturerAndroid.create(frontFacingCam);
localVideoSource = pcFactory.createVideoSource(capturer, this.pnRTCClient.videoConstraints());
VideoTrack localVideoTrack = pcFactory.createVideoTrack(VIDEO_TRACK_ID, localVideoSource);
AudioSource audioSource = pcFactory.createAudioSource(this.pnRTCClient.audioConstraints());
AudioTrack localAudioTrack = pcFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource);
MediaStream mediaStream = pcFactory.createLocalMediaStream(LOCAL_MEDIA_STREAM_ID);
mediaStream.addTrack(localVideoTrack);
mediaStream.addTrack(localAudioTrack);
this.mVideoView = (GLSurfaceView) findViewById(R.id.gl_surface);
VideoRendererGui.setView(mVideoView, null);
remoteRender = VideoRendererGui.create(0, 0, 100, 100, VideoRendererGui.ScalingType.SCALE_ASPECT_FILL, false);
localRender = VideoRendererGui.create(0, 0, 100, 100, VideoRendererGui.ScalingType.SCALE_ASPECT_FILL, true);
this.pnRTCClient.attachRTCListener(new MyRTCListener());
this.pnRTCClient.attachLocalMediaStream(mediaStream);
this.pnRTCClient.listenOn(this.username);
this.pnRTCClient.setMaxConnections(1);
if (extras.containsKey(Constants.JSON_CALL_USER)) {
String callUser = extras.getString(Constants.JSON_CALL_USER, "");
connectToUser(callUser);
}
}
public void connectToUser(String user) {
this.pnRTCClient.connect(user);
}
public void hangup(View view) {
this.pnRTCClient.closeAllConnections();
startActivity(new Intent(VideoChatActivity.this, MainActivity.class));
}
@Override
protected void onDestroy() {
super.onDestroy();
if (this.localVideoSource != null) {
localVideoSource.stop();
}
if (this.pnRTCClient != null) {
this.pnRTCClient.onDestroy();
this.pnRTCClient.closeAllConnections();
}
}
如果有帮助,这里是 MainActivity:
private SharedPreferences mSharedPreferences;
private TextView mUsernameTV;
private EditText mCallNumET;
// private Pubnub mPubNub;
private String username;
private Pubnub mPubNub;
public void initPubNub() {
String stdbyChannel = this.username + Constants.STDBY_SUFFIX;
this.mPubNub = new Pubnub(Constants.PUB_KEY, Constants.SUB_KEY);
this.mPubNub.setUUID(this.username);
try {
this.mPubNub.subscribe(stdbyChannel, new Callback() {
@Override
public void successCallback(String channel, Object message) {
Log.d("MA-success", "MESSAGE: " + message.toString());
if (!(message instanceof JSONObject)) return; // Ignore if not JSONObject
JSONObject jsonMsg = (JSONObject) message;
try {
if (!jsonMsg.has(Constants.JSON_CALL_USER)) return;
String user = jsonMsg.getString(Constants.JSON_CALL_USER);
// Consider Accept/Reject call here
Intent intent = new Intent(MainActivity.this, VideoChatActivity.class);
intent.putExtra(Constants.USER_NAME, username);
intent.putExtra(Constants.JSON_CALL_USER, user);
startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
} catch (PubnubException e) {
e.printStackTrace();
}
}
public void makeCall(View view){
String callNum = mCallNumET.getText().toString();
if (callNum.isEmpty() || callNum.equals(this.username)) {
Toast.makeText(this, "Enter a valid number.", Toast.LENGTH_SHORT).show();
}
dispatchCall(callNum);
}
public void dispatchCall(final String callNum) {
final String callNumStdBy = callNum + Constants.STDBY_SUFFIX;
JSONObject jsonCall = new JSONObject();
try {
jsonCall.put(Constants.JSON_CALL_USER, this.username);
mPubNub.publish(callNumStdBy, jsonCall, new Callback() {
@Override
public void successCallback(String channel, Object message) {
Log.d("MA-dCall", "SUCCESS: " + message.toString());
Intent intent = new Intent(MainActivity.this, VideoChatActivity.class);
intent.putExtra(Constants.USER_NAME, username);
intent.putExtra(Constants.JSON_CALL_USER, callNum);
startActivity(intent);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mSharedPreferences = getSharedPreferences(Constants.SHARED_PREFS, MODE_PRIVATE);
// Return to Log In screen if no user is logged in.
if (!this.mSharedPreferences.contains(Constants.USER_NAME)){
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();
return;
}
this.username = this.mSharedPreferences.getString(Constants.USER_NAME, "");
this.mCallNumET = (EditText) findViewById(R.id.call_num);
this.mUsernameTV = (TextView) findViewById(R.id.main_username);
this.mUsernameTV.setText(this.username); // Set the username to the username text view
//TODO: Create and instance of Pubnub and subscribe to standby channel
// In pubnub subscribe callback, send user to your VideoActivity
initPubNub();
}
我将不胜感激。谢谢大家。
【问题讨论】:
-
显然你锁定了摄像头进程。重启你的手机。
-
谢谢,但没有帮助。
-
这里没有与 PubNub 相关的内容,AFAICT。如果您找到根本原因和解决方案,请告诉我们。
标签: java android webrtc pubnub