【问题标题】:Video and audio call 2 Android devices - webrtc视频和音频通话 2 Android 设备 - webrtc
【发布时间】: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


【解决方案1】:

当您运行您的应用程序时,他们会询问登录用户名 那时你写下你的名字

将该名称放入VideoChatActivity 类中

this.pnRTCClient.listenOn("your name when your wrote at signin time");
this.pnRTCClient.setMaxConnections(3);

【讨论】:

  • 你好,我试过这个但没有帮助..但感谢您的回答。也许还有其他想法?
  • 按照本教程进行操作:- link 它会为您提供帮助并确保更改您的用户名..
猜你喜欢
  • 1970-01-01
  • 2019-07-17
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-28
  • 1970-01-01
  • 2021-06-27
相关资源
最近更新 更多