
1. 概述
随着各互联网业务玩法的不断创新,上层业务APP往往需要控制音视频输入输出。同时开启多个音视频模块也是常见需求,但手机或PC设备往往只有一个录音或者摄像头,并只允许一个APP访问,因此为了协调模块间的设备使用情况,我们将设备管理模块单独提供给用户,以提供更好的用户体验,比如模块间切换时(从连麦模式切换到通话模式)不需要关闭摄像头再开启摄像头。
Device Manager与Render Manager是整个框架系统中两个通用模块,通话或者直播都需要这两个模块。Device Manager主要用于设备管理,而Render Manager主要用于管理与控制视频渲染View。
同时Device Manager还提供一些混音、混响、美颜、调节音量/音效、设置曝光策略等接口,用户可以通过这些接口操作设备数据源。
Render Manager主要用于管理用户设置的视频渲染View,用户创建视频渲染View以后,可以将View放到UI特定位置上,并通过Render Manager将某个View绑定到特定用户的视频流上完成对视频layout的控制。
注:对于Device Manager以及Render Manager对象,每个APP中只应维持一个单独的实例。
2. Device Manager基本功能代码示例
2.1 初始化并开启设备
xxxxxxxxxx
// DeviceManager设备管理类初始化
DeviceManager deviceManager = new DeviceManager(self.getApplicationContext());
// 开启媒体设备, 开启设备将比较耗时,建议在加入会议之前开启设备
deviceManager.startAudioDevice();//开启音频
deviceManager.startCamera();//开启视频
// 将Device manager传入room对象,
// room对象将从device manager获取摄像头以及Microphone数据
Room room = new Room(self.getApplicationContext(), deviceManager.getNativeInstance());
2.2 关闭媒体设备并析构
xxxxxxxxxx
// 关闭音视频设备,其它模块将不能收到数据
deviceManager.stopAudioDevice();
deviceManager.stopCamera();
// 注意:room对象会引用并使用device manager对象,因此析构deviceManager前需要先析构room
room.destroy();
deviceManager.destroy();
3. Render Manager功能代码示例
xxxxxxxxxx
// Android platform
Point size = new Point(layout.getLayoutParams().width, layout.getLayoutParams().height);
// VideoView 继承于GLSurfaceView,可以设置Visibility等属性
// APP可以将其放于UI layout中,视频输出位置
VideoView render = rm.createRender(size);
render.setVisibility(View.VISIBLE);
render.setZOrderMediaOverlay(true);
// 将render绑定到本地用户预览视频流
rm.bindRenderWithStream(render, ""/*空字符串代表本地用户摄像头*/,
true /*对于本地视频关闭纯音同步功能*/);
// 将render与本地预览视频流解绑
rm.unbindRenderWithStream(render);
// 将render绑定到远端用户视频流
rm.bindRenderWithStream(render,
//remoteStreamId可以从onRemoteVidStreamCreated回调中得到
remoteStreamId,
false /*对于远端视频开启纯音同步功能*/);
4. Device Manager混音功能调用框图
以MP3背景音乐混流为例,用户可以做到以下事情:
- 控制混音背景/前景音量;
- 音乐耳返、Mic数据耳返(Mic 数据耳返只在iOS上支持);
- 循环播放同一音乐;
- 暂停、恢复混音;
- 在混音结束得到通知;
目前除MP3外还支持M4A以及WAVE文件格式。
5. DeviceManager基本代码示例
- 构造并初始化DeviceManager
xxxxxxxxxx
// Android platform
DeviceManager dm = new DeviceManager(self.getApplicationContext());
- 添加删除逻辑
xxxxxxxxxx
// Android platform
DeviceManager dm = new DeviceManager(self.getApplicationContext());
... ...
dm.destroy();
- 添加混音逻辑以及音量控制
xxxxxxxxxx
// 初始化DeviceManager并开启音频设备和混音
DeviceManager dm = new DeviceManager(self.getApplicationContext());
dm.startAudioDevice();
// 调用startMixMusic以后,如果此时系统正处于通话或者直播状态,
// 则远端用户能听到音乐声音,并且本地用户也能从耳机中听到音乐声音
dm.stratMixMusic("slow.mp3", true/*循环播放*/)
// 设置发送出去的背景音乐音量
dm.setBackgroundVolume(80); // 音量的值为0-100,值越大音量越大
// 设置发送音频中本地人声的音量
dm.setForegroundVolume(70); // 音量的值为0-100,值越大音量越大
// 开启本地人声混响,设置混响级数
int level = 4;
dm.startReverberation(level); /* level的范围为1-4,值越大混响越强*/
// App层业务逻辑结束后关闭设备
dm.stopAudioDevice();
dm.destroy();
- 静音麦克风以及扬声器
xxxxxxxxxx
// 初始化DeviceManager并开启音频设备
DeviceManager dm = new DeviceManager(self.getApplicationContext());
dm.startAudioDevice();
// 静音扬声器,混音后的Speaker数据将被重置
dm.muteSpeaker();
// 切换到扬声器、耳机模式手动切换
// enable为true,使用扬声器模式;为false使用耳机模式;
boolean enable = true;
dm.setSpeaker(enable)
// 静音麦克风,远端将听不到本地人声
dm.muteMicrophone()
// App层业务逻辑结束后关闭设备
dm.stopAudioDevice();
dm.destroy();
6. 监听Device Manager事件
xxxxxxxxxx
public interface DeviceCallback {
// 摄像头开启成功
public void onCameraStarted();
// 摄像头关闭完成
public void onCameraStopped();
// 麦克风开启失败, 1S钟内没有检测到音频数据则认为打开失败
// 常见的原因:1. 没有权限 2. 硬件失败 3.Mic被占用
public void onMicStartFailed();
// 摄像头开启失败,常见原因:1. 没有权限 2. 摄像头硬件故障
public void onCameraStartFailed();
// 音频文件混音结束事件,此事件意味着音频文件已经播放到文件尾
public void onAudioMixedMusicFinished();
}
xxxxxxxxxx
// Android platform
DeviceCallback deviceListener = new DeviceCallback() {
//事件响应函数回调实现
... ...
};
// 监听device manager相关事件,注:最多只能挂载一个事件监听者
dm.attachCallback(deviceListener);
// 开启摄像头,此函数调用后,如摄像头正常开启,用户将收到onStartCamera回调
dm.startCamera();
// 业务逻辑
... ...
dm.stopCamera();
// 移除已经挂载的事件监听者
dm.disattachCallback();
7. 摄像头基本代码示例
切换摄像头代码示例
xxxxxxxxxx
// 初始化DeviceManager并开启摄像头
DeviceManager dm = new DeviceManager(self.getApplicationContext());
// 默认将打开前置摄像头
dm.startCamera();
// 切换到后置摄像头
dm.switchCamera();
bool isFrontCamera = dm.isUsingFrontCamera();
8. 视频美化代码示例
// 初始化DeviceManager并开启摄像头
DeviceManager dm = new DeviceManager(self.getApplicationContext());
dm.startCamera();
// 开启Video前处理后,下面的美化效果才能生效
dm.enableVideoPreprocess(true);
// 设置视频美白程度
int whiteLevel = 80;
dm.setWhiteLevel(whiteLevel); // whiteLevel范围为[0-100]
int currentWhiteLevel = dm.getWhiteLevel();
// ASSERT(currentWhiteLevel == 80);
// 设置磨皮程度
int smoothLevel = 90;
dm.setSmoothLevel(90); // smoothLevel范围为[0-100]
int currentSmoothLevel = dm.getSmoothLevel();
// ASSERT(currentSmoothLevel == 90);
// 打开滤镜功能,目前支持的滤镜总类
// "com.videofilter.gray" --> GRAY
// "com.videofilter.nashville" --> NASHVILLE
// "com.videofilter.clarendon" --> CLARENDON
// "com.videofilter.juno" --> JUNO
// "com.videofilter.gingham" --> GINGHAM
// "com.videofilter.sweet" --> SWEET
// "com.videofilter.dogpatch" --> DOGPATCH
// "com.videofilter.crema" --> CREMA
// "com.videofilter.aden" --> ADEN
// "com.videofilter.stinson" --> STINSON
// "com.videofilter.basic" --> None video filter
String videoFilter = "com.videofilter.gray"; // 黑白滤镜
dm.setVideoFilter(videoFilter);
float value = 1.0;
dm.setVideoFilterIntensity(value); // value 范围为[0-1]