Android手把手编写儿童手机远程监控App之WebRtc切换摄像头与桌面共享

概述

上节完成嘟宝webrtc通信,实现嘟宝与嘟妈音视频通信。

  • 嘟妈扫描二维码绑定嘟宝
  • 嘟妈点击呼叫,与嘟宝建立webrtc通信
  • 嘟宝将摄像头、麦克风多媒体视频流发送嘟妈

切换前后摄像头

嘟妈端下发信令指令,可远程切换嘟宝设备摄像头,全程视频流不断开,实现画面无缝切换。

  • 获取相机采集工具
  • 获取相机视频流
clike 复制代码
   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;
    }

该函数枚举手机上摄像头,根据参数返回前置相机还是后置相机的采集工具。

clike 复制代码
    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 变量,通过它切换相机

clike 复制代码
   public void changeCam(){
        if (mCamCapture != null) {
            mCamCapture.switchCamera(null);
        }

    }

屏幕共享

嘟妈通过信令,查看嘟宝屏幕。获取桌面屏幕,需要用户同意的,在嘟宝运行之初,允许获取屏幕。

  • 在后台服务中允许访问屏幕共享
  • 在MainActivity中申请屏幕共享
  • 用户同意,获取Intent变量,用于捕获桌面视频流 在AndroidManifest.xml设置后台服务
clike 复制代码
<service
   android:name=".MyService"
     android:enabled="true"
     android:exported="true"
     android:foregroundServiceType="mediaProjection" />

mediaProjection运行后台捕获桌面共享

clike 复制代码
 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;

clike 复制代码
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);
    }

获取桌面共享的视频流。

运行视频查看效果

相关推荐
DarkLONGLOVE20 小时前
快速上手 Pinia!Vue3 极简状态管理使用教程
javascript·vue.js
宸翰21 小时前
解决 uni-app App 端 vue-i18n 占位符丢失:封装跨端可用的 tf 格式化方法
前端·vue.js·uni-app
用户2136610035721 天前
VueRouter进阶-动态路由与嵌套路由
前端·vue.js
暴走的小呆2 天前
Vue 2 中 Object 的变化侦测:从 getter/setter 到 Dep、Watcher、Observer
vue.js
英勇无比的消炎药2 天前
TinyVue v-auto-tip: 文本超长自动提示的优雅方案
vue.js
时光足迹2 天前
腾讯云 TRTC UniApp SDK 从入门到上线
前端·vue.js·uni-app
时光足迹2 天前
uni-app 里把加密视频嵌入页面播放?我分析了 4 种方案,只有 1 种接近完美
前端·vue.js·uni-app
时光足迹2 天前
JPush UniApp UTS 插件完全参考手册:API、事件与厂商通道一网打尽
vue.js·ios·uni-app
时光足迹2 天前
极光推送全攻略(下):uni-app 代码实现与 iOS 排查实战
vue.js·ios·uni-app
疯狂的魔鬼2 天前
一个"懂分寸"的文本省略组件是怎样炼成的
前端·vue.js·设计