概述
上节完成嘟宝webrtc通信,实现嘟宝与嘟妈音视频通信。
- 嘟妈扫描二维码绑定嘟宝
- 嘟妈点击呼叫,与嘟宝建立webrtc通信
- 嘟宝将摄像头、麦克风多媒体视频流发送嘟妈
切换前后摄像头
嘟妈端下发信令指令,可远程切换嘟宝设备摄像头,全程视频流不断开,实现画面无缝切换。
- 获取相机采集工具
- 获取相机视频流
private VideoCapturer createCameraCapturer(boolean isFront) {
Camera2Enumerator enumerator = new Camera2Enumerator(context.getApplicationContext());
final String[] deviceNames = enumerator.getDeviceNames();
for (String deviceName : deviceNames) {
if (isFront ? enumerator.isFrontFacing(deviceName) : enumerator.isBackFacing(deviceName)) {
VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
mCamCapture = (CameraVideoCapturer) videoCapturer;
if (videoCapturer != null) {
return videoCapturer;
}
}
}
return null;
}
该函数枚举手机上摄像头,根据参数返回前置相机还是后置相机的采集工具。
private VideoTrack getVideoTrack(){
surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglBase.getEglBaseContext());
VideoCapturer videoCapturer = createCameraCapturer(true);
VideoSource videoSource = factory.createVideoSource(videoCapturer.isScreencast());
videoCapturer.initialize(surfaceTextureHelper, context.getApplicationContext(), videoSource.getCapturerObserver());
videoCapturer.startCapture(480, 640, 30);
VideoTrack videoTrack= factory.createVideoTrack("100", videoSource);
videoTrack.enabled();
return videoTrack;
}
该函数调用createCameraCapturer函数,选择前置摄像头,捕获摄像头的视频流videoTrack。
在createCameraCapturer函数中,mCamCapture = (CameraVideoCapturer) videoCapturer;通过强制类型转换,得到mCamCapture 变量,通过它切换相机
public void changeCam(){
if (mCamCapture != null) {
mCamCapture.switchCamera(null);
}
}
屏幕共享
嘟妈通过信令,查看嘟宝屏幕。获取桌面屏幕,需要用户同意的,在嘟宝运行之初,允许获取屏幕。
- 在后台服务中允许访问屏幕共享
- 在MainActivity中申请屏幕共享
- 用户同意,获取Intent变量,用于捕获桌面视频流 在AndroidManifest.xml设置后台服务
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="mediaProjection" />
mediaProjection运行后台捕获桌面共享
public void startprojectionManager(){
@SuppressLint({"NewApi", "LocalSuppress"}) MediaProjectionManager projectionManager = (MediaProjectionManager)getSystemService(MEDIA_PROJECTION_SERVICE);
@SuppressLint({"NewApi", "LocalSuppress"}) Intent intent = projectionManager.createScreenCaptureIntent();
ActivityResultLauncher<Intent> screenCaptureLauncher;
screenCaptureLauncher=registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == RESULT_OK) {
Intent data = result.getData();
MyWebRtc.i=data;
}
else {
}
});
screenCaptureLauncher.launch(intent);
}
申请桌面共享,Intent data = result.getData();data是要获取屏幕共享变量,将值赋予MyWebRtc.i=data;
public void getScreenVideo() {
surfaceTextureHelperscreen = SurfaceTextureHelper.create("CaptureThread1", eglBase.getEglBaseContext());
VideoCapturer screenCapturer=new ScreenCapturerAndroid(i, new MediaProjection.Callback() {
@Override
public void onStop() {
super.onStop();
}
}); // eglBaseContext 是你之前初始化的 EGL 上下文
VideoSource screenVideoSource = factory.createVideoSource(screenCapturer.isScreencast());
VideoTrack screenVideoTrack = factory.createVideoTrack("102", screenVideoSource);
// 2. 初始化并启动 ScreenCapturer
// 注意:需要提前准备好 SurfaceTextureHelper
screenCapturer.initialize(surfaceTextureHelperscreen, context.getApplicationContext(), screenVideoSource.getCapturerObserver());
screenCapturer.startCapture(/* width */ 640, /* height */ 480, /* fps */ 25);
// 3. 执行替换的关键操作
// localVideoSender.track().setEnabled(false);
localVideoSender.setTrack(screenVideoTrack, /* takeOwnership= */ true);
}
获取桌面共享的视频流。