跳到主要内容

双向对讲

更新时间:2025-01-17 20:16:55

双向通话请在直播时可用

申请权限

语音通话仅需声音录制权限,带屏设备视频通话需要视频录制权限

/**
* withVideo 带屏设备通话
*/
private int accessTalkPermission(boolean withVideo) {
int audioCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);

List<String> reqPermission = new ArrayList<>();
if (audioCheck != PackageManager.PERMISSION_GRANTED) {
reqPermission.add(Manifest.permission.RECORD_AUDIO);
}

if (withVideo) {
int videoCheck = ActivityCompat.checkSelfPermission(LivePlayActivity.this, Manifest.permission.CAMERA);
if (videoCheck != PackageManager.PERMISSION_GRANTED) {
reqPermission.add(Manifest.permission.CAMERA);
}
}
if (!reqPermission.isEmpty()) {
if (!shouldShowRequestPermissionRationale(reqPermission.get(0))) {
showToast("请打开通话所需录制权限");
ActivityCompat.requestPermissions(this, reqPermission.toArray(new String[0]), REQUEST_PERMISSION);
} else {
showLongToast("您已禁止通话所需录制权限,,请前往系统设置手动打开");
}
return PackageManager.PERMISSION_DENIED;
}

return PackageManager.PERMISSION_GRANTED;
}

初始化

/**
* 双向通话
*
* @property mContext 上下文件
* @property mIoTDeviceInfo 设备信息
* @property mVideoWrapper 视频容器
* @constructor Create empty Io t media pusher
*/
@MainThread
class IoTMediaPusher(
private val mContext: Context,
private val mIoTDeviceInfo: IoTDeviceInfo,
private val mVideoWrapper: ViewGroup?
){
/**
* 双向通话
* @property mContext 上下文件
* @property mIoTDeviceInfo 设备信息
*/
@MainThread
constructor(
mContext: Context,
mIoTDeviceInfo: IoTDeviceInfo,
) : this(mContext, mIoTDeviceInfo, null)
}

示例

//视频通话
FrameLayout flLocalWrapper = findViewById(R.id.flLocalWrapper);
new IoTMediaPusher(LivePlayActivity.this, mPlayDeviceInfo, flLocalWrapper);

//语音通话
new IoTMediaPusher(LivePlayActivity.this, mPlayDeviceInfo);

开始通话

开始通话请申请声音录制权限,带屏设备视频通话需要视频录制权限

/**
* 视频通话开始推送
*
* @param videoWidth 采集视频宽度
* @param videoHeight 采集视频高度
* @param videoFPS 采集视频帧率
* @param videoMaxBitrate 采集视频最大码率,单位kbpS
*/
fun startPush(videoWidth: Int, videoHeight: Int, videoFPS: Int, videoMaxBitrate: Int)
/**
* 语音通话开始推送
*/
fun startPush()

示例

import com.polaris.iot.appsdk.libplayer.IoTMediaPusher;

private IoTMediaPusher mIoTMediaPusher;
private boolean mIsTalking = false;
/**
* withVideo 带屏设备通话
*/
private boolean startTalk(boolean withVideo) {
if (accessTalkPermission(withVideo) != PackageManager.PERMISSION_GRANTED) {
runOnUiThread(() -> showToast(" 请打开通话所需录制权限"));
return false;
}
IoTLogger.d(TAG, "talk start ");
//视频通话时,本地视频窗口容器,
FrameLayout flLocalWrapper = findViewById(R.id.flLocalWrapper);

if (mIoTMediaPusher == null) {
mIoTMediaPusher = new IoTMediaPusher(LivePlayActivity.this, mPlayDeviceInfo, flLocalWrapper);
mIoTMediaPusher.setPushStatusListener(mIoTPushStatusListener);
}
if (withVideo) {
mIoTMediaPusher.startPush(240, 320, 10, 200);
} else {
mIoTMediaPusher.startPush();
startUpdateTalkTime(liveBtn);
}
if (mIsMuted) {
callLiveBtn(LiveBtnTypeEnum.Sound);
}
mIsTalking = true;
return true;
}

结束通话


private void stopTalk() {
mIoTMediaPusher.stopPush();
mIsTalking = false;
}

释放

private void onDestroy() {
if(mIsTalking) stopTalk()
if(mIoTMediaPusher!=null) mIoTMediaPusher.release();
}

监听通话

/**
* 监听通话状态
*/
override fun setPushStatusListener(listener: IoTPushStatusListener)

示例

private IoTPushStatusListener mIoTPushStatusListener = new IoTPushStatusListener() {
@Override
public void onStatusChange(@NonNull PushStateEnum status, int code) {
switch (status) {
case STATE_ERROR -> {
if (code == PushErrorEnum.ERROR_TALK_BUSY.getValue()) {
showToast("有人正在通话,请稍后再试");
} else {
showToast("通话失败,请稍后再试");
}
stopTalk();
}
}
}
};
mIoTMediaPusher.setPushStatusListener(mIoTPushStatusListener);

设置手机麦克风状态

/**
* 设置手机麦克风状态
*
* @param status true 启用 false 关闭
*/
fun setMicStatus(status: Boolean)

设置手机扬声器状态

/**
* 设置手机扬声器状态
*
* @param status true 启用 false 关闭
*/
fun setSpeakerStatus(status: Boolean)

设置手机摄像头状态

带屏设备视频通话使用

/**
* 设置手机摄像头状态
*
* @param status true 启用 false 关闭
*/
fun setCameraStatus(status: Boolean)

切换手机前置/后置摄像头

带屏设备视频通话使用

/**
* 切换手机前置/后置摄像头 默认前置
*/
override fun exchangeVideoSource()