更新时间:2024-03-04 08:55:32
本文档包含音视频相关接口、日志功能、成员管理以及临时密码相关功能。
Wi-Fi 门锁音视频能力接口支持可视门锁、拍照锁的实时视频查看、对讲等功能。
类名 | 说明 |
---|---|
ThingOptimusSdk |
初始化 SDK 入口,用来获取门锁管理类 |
IThingLockManager |
门锁管理类,可以获取不同类型的门锁类 |
IVideoLockManager |
Wi-Fi 门锁音视频功能入口 |
注册监听
监听门锁各种 DP 上报,包含实时视频请求、远程开关锁、告警等 DP 上报。
void registerLockReportListener(ILockReportListener iLockReportListener);
void unRegisterLockReportListener();
方法说明
ILockReportListener:
/**
* 主动消息推送 ,主要包含抓拍的图片存储路径信息 即dpCode:initiative_message
* @param devId 设备id
* @param dpCode
* @param fileBucketInfoBean 云存储中的图片信息
*/
void onLockMessageArrived(String devId, String dpCode, FileBucketInfoBean fileBucketInfoBean);
/**
* 实时视频请求 dpCode:video_request_realtime
* @param devId 设备id
* @param dpCode
* @param dpValue
*/
void onVideoRequestRealtime(String devId, String dpCode,String dpValue);
/**
* 远程开门请求倒计时 dpCode:unlock_request
* @param devId 设备id
* @param dpCode
* @param dpValue
*/
void unlockRequestCountdown(String devId,String dpCode,Object dpValue);
/**
* 抓拍告警确认倒计时 dpCode:alarm_request
* @param devId 设备id
* @param dpCode
* @param dpValue
*/
void alarmRequestCountdown(String devId, String dpCode,Object dpValue);
/**
* 远程开锁上报 dpCode:remote_no_dp_key
* @param devId 设备id
* @param dpCode
* @param dpValue
*/
void onRemoteUnlockReport(String devId, String dpCode,Object dpValue);
/**
* 强制反锁 dp 上报,dpCode:reverse_lock
* @param devId
* @param dpCode
*/
void onForceLockUpReport(String devId, String dpCode,Object dpValue);
/**
* 设备其他 dp 上报
* @param devId
* @param dpCode
*/
void onLockDpUpdate(String devId, Map<String,Object> dpCode);
示例代码
// 初始化 SDK,仅需要调用一次
ThingOptimusSdk.init(getApplicationContext());
// 获取 IThingLockManager
val iThingLockManager = ThingOptimusSdk.getManager(IThingLockManager::class.java)
// 获取 IVideoLockManager
iThingVideoLockManager = iThingLockManager.newVideoLockManagerInstance(mDevId)
// 注册监听
iThingVideoLockManager?.registerLockReportListener(object:ILockReportListener{
override fun onLockMessageArrived(
devId: String?,
dpCode: String?,
fileBucketInfoBean: FileBucketInfoBean?
) {
TODO("Not yet implemented")
}
override fun onVideoRequestRealtime(devId: String?, dpCode: String?, dpValue: String?) {
TODO("Not yet implemented")
}
override fun unlockRequestCountdown(devId: String?, dpCode: String?, dpValue: Any?) {
TODO("Not yet implemented")
}
override fun alarmRequestCountdown(devId: String?, dpCode: String?, dpValue: Any?) {
TODO("Not yet implemented")
}
override fun onRemoteUnlockReport(devId: String?, dpCode: String?, dpValue: Any?) {
TODO("Not yet implemented")
}
override fun onForceLockUpReport(devId: String?, dpCode: String?, dpValue: Any?) {
TODO("Not yet implemented")
}
override fun onLockDpUpdate(devId: String?, dpCode: MutableMap<String, Any>?) {
TODO("Not yet implemented")
}
})
接口说明
通过此接口可以实现远程开锁、关锁、拒绝开锁、拒绝关锁。
void remoteLock(boolean isOpen, boolean confirm, IResultCallback callback);
参数说明
参数 | 能否为空 | 说明 |
---|---|---|
isOpen | 否 | 开门还是关门,开门=true,关门=false |
confirm | 否 | 允许还是拒绝,允许=true,拒绝=false |
Callback | 是 | 调用接口回调结果 |
Callback 的 onSuccess
回调只能表示接口调用成功,不能作为门锁设备执行指令判断标准。confirm = true
时,设备状态发生变化(开锁、关锁),设备执行成功后依赖监听方法 onRemoteUnlockReport
回调结果。confirm=false
时,设备状态没有产生变化,不会上报 DP。onSuccess
表示拒绝开锁或拒绝关锁执行成功。
示例代码
fun remoteUnLock(isOpen: Boolean, confirm: Boolean) {
iThingVideoLockManager?.remoteLock(isOpen, confirm, object : IResultCallback {
override fun onError(code: String?, error: String?) {
Toast.makeText(mContext, error, Toast.LENGTH_SHORT).show()
}
override fun onSuccess() {
Toast.makeText(mContext, "publish success", Toast.LENGTH_SHORT).show()
}
})
}
接口说明
重新拍照。设备会把抓拍的图片传到云存储,并通过 onLockMessageArrived
上报图片路径信息。受设备限制,15 秒内只能下发一次。
void reTakePhoto(boolean isTakePhotoAgain, IResultCallback callback);
参数说明
参数 | 能否为空 | 说明 |
---|---|---|
isTakePhotoAgain | 否 | 是否重新拍照 |
callback | 是 | 指令发送结果 |
示例代码
iThingVideoLockManager?.reTakePhoto(true,object :IResultCallback{
override fun onError(code: String?, error: String?) {
L.e(TAG,"RetakePhoto error:$error")
}
override fun onSuccess() {
L.i(TAG,"Retake photo publish success")
}
})
接口说明
强制反锁。设备执行成功会通过 onForceLockUpReport
回调结果。
void forceLock(boolean isForceLock, IResultCallback callback);
参数说明
参数 | 能否为空 | 说明 |
---|---|---|
isForceLock | 否 | 是否强制反锁 |
callback | 是 | 指令发送结果 |
示例代码
iThingVideoLockManager?.forceLock(true,object :IResultCallback{
override fun onError(code: String?, error: String?) {
L.e(TAG,"code $code error:$error")
ToastUtil.shortToast(mContext,error)
}
override fun onSuccess() {
L.i(TAG,"force anti-lock success")
ToastUtil.shortToast(mContext,"force anti-lock success")
}
})
接口说明
获取云存储上最新的一张图片信息。需要配合使用接口 getPictureAndVideo。
void getLatestPicture(FileTypeEnum fileTypeEnum, IThingResultCallback<FileBucketInfoBean> callback);
参数说明
参数 | 能否为空 | 说明 |
---|---|---|
fileTypeEnum | 否 | 图片类型:远程解锁抓拍图片、告警抓拍图片 |
callback | 是 | 回调结果 |
FileBucketInfoBean
: 图片的云存储信息
字段 | 说明 |
---|---|
filePath | 图片在云存储的路径 |
fileKey | 解密 key |
bucket | 云存储 bucket |
示例代码
iThingVideoLockManager?.getLatestPicture(FileTypeEnum.REMOTE_UNLOCK,
object : IThingResultCallback<FileBucketInfoBean> {
override fun onSuccess(result: FileBucketInfoBean?) {
L.i(TAG, "result filePath:${result?.toString()}")
result?.let {
requestPictureAndVideo(it.bucket, it.filePath, it.fileKey)
}
}
override fun onError(errorCode: String?, errorMessage: String?) {
Toast.makeText(mContext, errorMessage, Toast.LENGTH_SHORT).show()
}
})
接口说明
设备抓拍的图片会上传到云存储,通过此接口获取图片的地址。此接口和监听回调 onLockMessageArrived
方法或 getLatestPicture
配合使用。
void getPictureAndVideo( String bucket, String filePath, IThingResultCallback<RemoteMediaBean> callback);
参数说明
参数 | 能否为空 | 说明 |
---|---|---|
bucket | 否 | 云存储 bucket |
filePath | 否 | 云存储加密 URL |
callback | 是 | 回调结果 |
RemoteMediaBean:
字段 | 说明 |
---|---|
fileUrl | 图片在云存储的路径 |
mediaUrl | 视频在云存储的路径 |
angle | 角度,在 IoT 开发平台配置的角度旋转,有效值:0 、90 、180 、270 。 |
注意
fileUrl
仍然是加密链接,需要 onLockMessageArrived
或 getLatestPicture
获取 fileKey
解密。我们提供控件 DecryptImageView
负责解密和显示图像。
示例代码
override fun onLockMessageArrived(
devId: String?,
dpCode: String?,
fileBucketInfoBean: FileBucketInfoBean?
) {
fileBucketInfoBean?.let {
requestPictureAndVideo(it.bucket,it.filePath,it.fileKey)
}
}
...
fun requestPictureAndVideo(
bucket: String?,
filePath: String?,
fileKey: String?
) {
iThingVideoLockManager?.getPictureAndVideo(
bucket,
filePath,
object : IThingResultCallback<RemoteMediaBean> {
override fun onSuccess(result: RemoteMediaBean?) {
L.i(TAG, result?.toString())
if (fileKey != null) {
refreshImage(result?.fileUrl, fileKey)
}
}
override fun onError(errorCode: String?, errorMessage: String?) {
Toast.makeText(mContext, errorMessage, Toast.LENGTH_SHORT).show()
}
})
}
...
fun refreshImage(fileUrl:String?,fileKey:String){
fileUrl?.let{
val imageView:DecryptImageView = findViewById(R.id.div_picture)
imageView.setImageURI(it,fileKey.toByteArray())
}
}
接口说明
IIPCManager getIPCManager();
该接口包含 P2P 连接、视频渲染、对讲等功能,整体流程如下:
ThingCameraView
是 SDK 提供的视频渲染视图。
<com.thingclips.smart.camera.middleware.widget.ThingCameraView
android:id="@+id/camera_video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
接口说明
public void setViewCallback(AbsVideoViewCallback callback);
参数说明
参数 | 说明 |
---|---|
callback | 回调接口 |
示例代码
ThingCameraView mVideoView = findViewById(R.id.camera_video_view);
mVideoView.setViewCallback(new AbsVideoViewCallback() {
@Override
public void onCreated(Object view) {
super.onCreated(view);
// 渲染视图构造完成时回调
}
});
AbsVideoViewCallback
渲染视图回调抽象类。开发者只需要重写自己关心的回调,一般只需要重写 onCreated
方法。
接口说明
public void createVideoView(String devId);
参数说明
参数 | 说明 |
---|---|
devId | 设备 ID |
示例代码
ThingCameraView mVideoView = findViewById(R.id.camera_video_view);
mVideoView.createVideoView(devId);
接口说明
void generateCameraView(T view);
示例代码
iIPCManager?.generateCameraView(mVideoView.createdView())
注册监听器,否则无法正常显示画面。
关于监听的详细解释,请参考 裸流数据。
接口说明
void registerP2PCameraListener(AbsP2pCameraListener listener);
示例代码
// 1. 获取 IIPCManager
iIPCManager = iThingVideoLockManager?.ipcManager
ThingCameraView cameraView = findViewById(R.id.camera_video_view)
// 2. 为渲染视图容器设置回调
cameraView.setViewCallback(object : AbsVideoViewCallback() {
override fun onCreated(p0: Any?) {
super.onCreated(p0)
iIpcManager?.generateCameraView(p0)
}
})
// 3. 构造渲染视图
cameraView.createVideoView(devId)
// 4. 注册 P2P 监听
if (null != iIPCManager){
iIPCManager.registerP2PCameraListener(object: AbsP2pCameraListener() {
override fun onReceiveAudioBufferData(
nSampleRate: Int,
nChannelNum: Int,
nBitWidth: Int,
nTimeStamp: Long,
progress: Long,
duration: Long
) {
super.onReceiveAudioBufferData(
nSampleRate,
nChannelNum,
nBitWidth,
nTimeStamp,
progress,
duration
)
}
override fun onReceiveFrameYUVData(
sessionId: Int,
y: ByteBuffer?,
u: ByteBuffer?,
v: ByteBuffer?,
videoFrameInfo: ThingVideoFrameInfo?,
camera: Any?
) {
super.onReceiveFrameYUVData(sessionId, y, u, v, videoFrameInfo, camera)
}
override fun onReceiveFrameYUVData(
sessionId: Int,
y: ByteBuffer?,
u: ByteBuffer?,
v: ByteBuffer?,
width: Int,
height: Int,
nFrameRate: Int,
nIsKeyFrame: Int,
timestamp: Long,
nProgress: Long,
nDuration: Long,
camera: Any?
) {
super.onReceiveFrameYUVData(
sessionId,
y,
u,
v,
width,
height,
nFrameRate,
nIsKeyFrame,
timestamp,
nProgress,
nDuration,
camera
)
}
override fun onReceiveSpeakerEchoData(pcm: ByteBuffer?, sampleRate: Int) {
super.onReceiveSpeakerEchoData(pcm, sampleRate)
}
override fun onSessionStatusChanged(camera: Any?, sessionId: Int, sessionStatus: Int) {
super.onSessionStatusChanged(camera, sessionId, sessionStatus)
}
})
});
}
onReceiveFrameYUVData 裸流数据
参数 | 说明 |
---|---|
sessionId | 会话 ID |
Y | 视频 Y 数据 |
u | 视频 U 数据 |
v | 视频 V 数据 |
width | 视频画面的宽度 |
height | 视频画面的高度 |
nFrameRate | 帧率 |
nIsKeyFrame | 是否 I 帧 |
timestamp | 时间戳 |
nProgress | 时间进度,即消息中心视频播放的进度 |
nDuration | 时长,即消息中心视频播放时长 |
onSessionStatusChanged P2P 链接状态回调
参数 | 说明 |
---|---|
sessionId | 会话 ID |
sessionStatus | 会话状态 |
session 状态码 | 说明 |
---|---|
0 | 连接成功 |
-3 | 连接超时 |
-12 | 连接被设备关闭 |
-13 | 连接无响应超时关闭 |
在开始视频播放之前,需要先连接 P2P 通道。P2P 状态需要使用者自己维护,SDK 只负责下发指令和接收摄像机响应结果。
接口说明
void connect(IResultCallback callBack);
void disconnect(IResultCallback callBack);
参数说明
参数 | 说明 |
---|---|
callBack | 操作结果回调 |
boolean isConnected();
boolean isConnecting();
P2P 连接成功之后,即可进行实时视频播放。
接口说明
void startPreview(int clarity, IResultCallback callBack);
int stopPreview(IResultCallback callBack);
参数说明
参数 | 说明 |
---|---|
clarity | 清晰度模式 |
callBack | 操作结果回调 |
清晰度模式
模式 | 值 |
---|---|
标清 | 2 |
高清 | 4 |
示例代码
iIPCManager.startPreview(new IResultCallback() {
@Override
public void onSuccess() {
// 开始播放实时视频成功
}
@Override
public void onError(String code, String error) {
// 开始播放实时视频失败
}
});
startPreview
成功回调之后,onReceiveFrameYUVData
回调会开始接收视频数据,并抛给业务层。
当视频成功开始播放以后(可以是视频直播,也可以是录像回放),可以将当前正在播放的视频录制到手机中。
在视频录制的过程中,请不要再切换视频清晰度,开关声音及对讲。
如果需要将录制的视频保存至系统相册,需要开发者自己实现。注意 Android10 开始采用 分区存储 机制(可禁用,但 Android11 强制使用),保存媒体文件至系统相册需使用 MediaStore API。
接口说明
void startRecord(String folderPath, Context context, RotateModeEnum rotateMode, IResultCallback callback);
录制视频需要写存储卡权限。
参数说明
参数 | 说明 |
---|---|
folderPath | 保存视频的文件目录路径 |
context | 上下文 |
rotateMode | 旋转模式 |
callBack | 操作回调 |
接口说明
void stopRecord(IThingResultCallback<Map<String, String>> callback);
回调参数说明
停止录制会回调两条数据:视频路径和封面图路径,分别通过 key video
、coverImage
获取对应 value。
接口说明
boolean isRecording();
示例代码
if(iIpcManager?.isRecording == true){
stopRecorder()
}else{
startRecord()
}
...
fun startRecord(){
iIpcManager?.startRecord(
path,
mContext,
rotateMode ?: RotateModeEnum.NORMAL,
object : IResultCallback {
override fun onError(code: String?, error: String?) {
}
override fun onSuccess() {
L.i(TAG, "recorder success")
}
})
}
fun stopRecord(){
iIpcManager?.stopRecord(object : IThingResultCallback<Map<String, String>> {
override fun onSuccess(result: Map<String, String>?) {
result?.let {
val videoPath = it.get("video")
val coverImagePath = it.get("coverImage")
}
}
override fun onError(errorCode: String?, errorMessage: String?) {
}
})
}
截取实时视频的影像图片存储到手机 SD 卡上。
如果需要将截图保存至系统相册,需要开发者自己实现。注意,Android10 开始采用 分区存储 机制(可禁用,但 Android11 强制使用),保存媒体文件至系统相册需使用 MediaStore API。
接口说明
void snapshot(String folderPath, Context context, ICameraP2P.PLAYMODE playmode, RotateModeEnum rotateMode, IThingResultCallback<String> callback);
参数说明
参数 | 说明 |
---|---|
folderPath | 图片存储路径 |
context | 上下文 |
playmode | 视频播放模式,当前仅支持 PLAYMODE.LIVE |
rotateMode | 旋转模式,支持的角度:0 、90 、180 、270 |
callBack | 操作回调。onSuccess 返回截图完整路径 |
示例代码
iIpcManager?.snapshot(
path,
mContext,
ICameraP2P.PLAYMODE.LIVE,
rotateMode ?: RotateModeEnum.NORMAL,
object : IThingResultCallback<String> {
override fun onSuccess(result: String?) {
L.i(TAG, "snapshot success :$result")
}
override fun onError(errorCode: String?, errorMessage: String?) {
}
})
当视频成功开始播放以后,可以开启视频声音。声音默认是关闭状态。
接口说明
开启、关闭视频声音。
void enableMute(boolean isMute,IResultCallback callback);
音频模式 | 值 |
---|---|
静音 | true |
非静音 | false |
boolean isMuting();
示例代码
iIpcManager?.enableMute(mute, object : IResultCallback {
override fun onError(code: String?, error: String?) {
}
override fun onSuccess() {
L.i(TAG, "set mute $mute success ")
}
})
在 P2P 连接成功后,可以开启与设备的实时通话功能。在开始对讲前,需要确保 App 已获得手机麦克风的访问权限。
打开、关闭手机声音传输给摄像机操作。
void startTalk(IResultCallback callback);
void stopTalk(IResultCallback callback);
boolean isSupportTalk();
boolean isTalkBacking();
示例代码
iIpcManager?.startTalk(object : IResultCallback {
override fun onError(code: String?, error: String?) {
}
override fun onSuccess() {
L.i(TAG, "startTalk success")
}
})
iIpcManager?.stopTalk(object : IResultCallback {
override fun onError(code: String?, error: String?) {
}
override fun onSuccess() {
}
})
接口说明
设备是否有拾音器。若设备配置有拾音器,表示设备的视频有声音。
boolean isSupportSound();
接口说明
获取默认的对讲方式。
int supportAudioMode();
不再使用 camera 功能时,必须注销 P2P 监听器、销毁 P2P 对象。
void onDestroy();
不再使用可视门锁、拍照锁相关功能时,销毁整个 IVideoLockManger
对象,IIPCManager
对象也会同步销毁。
void onDestroy();
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈