WebRTC Android推流至网页示例:摄像头切换功能实现求助
我之前正好在WebRTC项目里处理过基于VideoCapturerAndroid的摄像头切换需求,给你一套经过验证的可行方案,一步步来操作:
基于VideoCapturerAndroid实现WebRTC摄像头切换方案
1. 先保存核心对象引用
在你的Activity类中,声明全局变量来存储摄像头捕获、视频源、轨道等关键实例,这样切换时能方便地操作旧资源:
private VideoCapturerAndroid videoCapturer; private VideoSource videoSource; private VideoTrack localVideoTrack; private PeerConnectionFactory peerConnectionFactory; private PeerConnection peerConnection; // 如果已经建立了连接,需要这个对象 private boolean isUsingFrontCamera = true; // 默认使用前置摄像头
注意:你需要在初始化摄像头的代码中,把这些变量赋值(比如原来创建VideoCapturerAndroid、VideoSource的地方),举个初始化示例:
// 初始化摄像头的参考代码(替换你原有逻辑) private void initCamera() { // 假设peerConnectionFactory已经完成初始化 String frontCameraId = VideoCapturerAndroid.getNameOfFrontFacingDevice(); try { videoCapturer = VideoCapturerAndroid.create(frontCameraId); videoSource = peerConnectionFactory.createVideoSource(videoCapturer); localVideoTrack = peerConnectionFactory.createVideoTrack("localVideoTrack", videoSource); // 绑定到本地预览(假设你用的是SurfaceViewRenderer) localVideoTrack.addSink(localSurfaceViewRenderer); // 启动捕获 videoCapturer.startCapture(640, 480, 30); // 可根据需求调整分辨率、帧率 isUsingFrontCamera = true; } catch (IOException e) { e.printStackTrace(); } }
2. 实现摄像头切换核心方法
编写切换逻辑,核心是停止旧捕获→释放资源→创建新捕获→更新轨道和预览:
private void switchCamera() { // 1. 停止并释放旧的摄像头资源 if (videoCapturer != null) { videoCapturer.stopCapture(); videoCapturer.dispose(); } if (videoSource != null) { videoSource.dispose(); } // 2. 切换摄像头标识,获取新摄像头ID isUsingFrontCamera = !isUsingFrontCamera; String targetCameraId = isUsingFrontCamera ? VideoCapturerAndroid.getNameOfFrontFacingDevice() : VideoCapturerAndroid.getNameOfBackFacingDevice(); // 3. 创建新的VideoCapturer实例 try { videoCapturer = VideoCapturerAndroid.create(targetCameraId); } catch (IOException e) { e.printStackTrace(); return; } // 4. 重新创建视频源和轨道 videoSource = peerConnectionFactory.createVideoSource(videoCapturer); localVideoTrack = peerConnectionFactory.createVideoTrack("localVideoTrack", videoSource); // 5. 更新本地预览 localVideoTrack.addSink(localSurfaceViewRenderer); // 6. 如果已经和远端建立连接,替换PeerConnection中的本地轨道 if (peerConnection != null) { // 找到旧的视频轨道Sender并移除 peerConnection.getSenders().stream() .filter(sender -> sender.track() != null && sender.track().id().equals("localVideoTrack")) .findFirst() .ifPresent(peerConnection::removeTrack); // 添加新的视频轨道 peerConnection.addTrack(localVideoTrack, MediaStream.DEFAULT_MEDIA_STREAM_ID); } // 7. 启动新摄像头的捕获 try { videoCapturer.startCapture(640, 480, 30); } catch (IOException e) { e.printStackTrace(); } }
3. 绑定UI触发切换
给你的切换按钮添加点击事件,直接调用上面的方法即可:
@OnClick(R.id.btn_switch_camera) public void onSwitchCameraClicked() { switchCamera(); }
关键注意事项
- 确保已申请
CAMERA权限,切换时无需重新申请,但首次启动必须有权限 - 切换前务必停止旧的捕获,否则会出现摄像头被占用的错误
- 如果你的预览组件不是
SurfaceViewRenderer,替换成你实际使用的组件即可
内容的提问来源于stack exchange,提问作者Jaan
相关产品推荐
相关产品推荐

