更新时间:2023-06-27 08:42:47
本文档包含音视频相关接口、日志功能、成员管理以及临时密码相关功能。
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)
}
})
});
}
在开始视频播放之前,需要先连接 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();
SDK 提供访问视频裸流数据的回调方法。此方法返回视频帧的 YUV 数据,颜色编码格式为 YUV 420SP。
接口说明
接收视频帧回调需要注册监听器,开发者只需要重写自己关心的回调。
void registerP2PCameraListener(AbsP2pCameraListener listener);
AbsP2pCameraListener 主要方法:
接口说明
回调视频 YUV 数据。
public void onReceiveFrameYUVData(int sessionId, ByteBuffer y, ByteBuffer u, ByteBuffer v, int width, int height, int nFrameRate, int nIsKeyFrame, long timestamp, long nProgress, long nDuration, Object camera)
参数说明
参数 | 说明 |
---|---|
sessionId | session ID |
Y | 视频 Y 数据 |
u | 视频 U 数据 |
v | 视频 V 数据 |
width | 视频画面的宽 |
height | 视频画面的高 |
nFrameRate | 帧率 |
nIsKeyFrame | 是否 I 帧 |
timestamp | 时间戳 |
nProgress | 时间进度,即 消息中心视频播放的进度 |
nDuration | 时长,即 消息中心视频播放时长 |
接口说明
P2P 的链接状态回调。
public void onSessionStatusChanged(Object camera, int sessionId, int sessionStatus)
参数说明
参数 | 说明 |
---|---|
sessionId | session ID |
sessionStatus | session 状态 |
session 状态码 | 说明 |
---|---|
0 | 连接成功 |
-3 | 连接超时 |
-12 | 连接被设备关闭 |
-13 | 连接无响应超时关闭 |
不再使用 camera 功能时,必须注销 P2P 监听器、销毁 P2P 对象。
void onDestroy();
不再使用可视门锁、拍照锁相关功能时,销毁整个 IVideoLockManger
对象,IIPCManager
对象也会同步销毁。
void onDestroy();
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈