涂鸦智能安卓版摄像机(IP Camera,简称 IPC)SDK 是基于智能生活 App SDK 开发而成。

通过移动应用控制物理网设备是常见的使用场景,但由于设备的品类丰富,增大了应用开发难度。因此 智能生活 App SDK 提供了常见的垂直品类 SDK,例如 IPC SDK,将网络摄像机设备特有的功能抽离,提供了与其通讯的接口封装,加速应用开发过程。

大家可以通过本教程,在一小时内快速开发一款自己的 IoT App,并实现如下功能:

  • 通过 App 连接一个智能摄像头。
  • 预览摄像机实时采集的影像。
  • 播放摄像机存储卡中录制的视频。
  • 手机端录制摄像机采集的影像。

大家可以 前往App工作台 下载 Sample 查看本教程中的示例代码。本次教程按功能模块进行分类,大家可以快速找到对应的代码参考学习。

效果展示

学习完本教程,结合一定的面板开发可以创建一个类似以下安卓 App 的 Demo。

准备工作

在开始本教程前,请先确保完成一下工作 :

  1. 在涂鸦 IoT 平台,注册账号并创建 App 应用,拿到 SDK 的 AppKey,AppSecret。

    由于 IPC SDK 依赖于 智能生活 App SDK,需要先实现如创建账号、添加家庭的操作后才能借助 IPC SDK 实现摄像机相关功能。具体操作流程可参考我上一篇文章《智能生活 App SDK 开发入门教程》。

  2. 准备一个涂鸦赋能的智能摄像机产品,本教程以摄像头为例。
  3. 使用 Android Studio 将涂鸦安卓智能生活 App SDK 集成到项目中 。 具体教程可参考我之前文章《 IPC SDK 架构及快速集成配置》。

设备配网

由涂鸦赋能的智能摄像机支持智能生活 App SDK 中的所有配网方式,例如 Wi-Fi 热点配网蓝牙配网等。

此外,涂鸦为 IPC 设备提供了独有的扫描二维码配网功能,但如果 IP 摄像机设备无法扫码,可以优先尝试 Wi-Fi 快连方式。本篇教程文档主要讲解扫描二维码配网。

获取 Token

和 Wi-Fi 快连和 Wi-Fi 热点模式类似,开始配网之前,SDK 需要在手机已联网的状态下从涂鸦获取配网 Token,然后才可以开始配网。

配网 Token 的有效期为 10 分钟,且配置成功后就会失效,再次配网需要重新获取。获取 Token 需要上传当前的 homeId,因此我们需要确保用户处于登录状态,并至少创建了一个家庭。

TuyaHomeSdk.getActivatorInstance().getActivatorToken(homeId,new ITuyaActivatorGetToken() {@Overridepublic void onSuccess(String token) {}@Overridepublic void onFailure(String s, String s1) {}});

生成配网二维码

获取到配网 Token 后,我们还需要当前 Wi-Fi 的名称(SSID)和密码,通过初始化配网参数的回调 onQRCodeSuccess,拿到二维码的 URL 字符串生成一个二维码图片。

相关依赖为 zxingimplementation ‘com.google.zxing:core:3.2.1’)。

// Get Network Configuration TokenTuyaHomeSdk.getActivatorInstance().getActivatorToken(homeId,new ITuyaActivatorGetToken() {@Overridepublic void onSuccess(String token) {//Create and show qrCodeTuyaCameraActivatorBuilder builder = new TuyaCameraActivatorBuilder().setToken(token).setPassword(wifiPwd).setTimeOut(100).setContext(QrCodeConfigActivity.this).setSsid(wifiSSId).setListener(new ITuyaSmartCameraActivatorListener() {@Overridepublic void onQRCodeSuccess(String qrcodeUrl) {final Bitmap bitmap;try {bitmap = QRCodeUtil.createQRCode(qrcodeUrl, 300);QrCodeConfigActivity.this.runOnUiThread(new Runnable() {@Overridepublic void run() {mIvQr.setImageBitmap(bitmap);mLlInputWifi.setVisibility(View.GONE);mIvQr.setVisibility(View.VISIBLE);}});} catch (WriterException e) {e.printStackTrace();}}@Overridepublic void onError(String errorCode, String errorMsg) {}@Overridepublic void onActiveSuccess(DeviceBean devResp) {Toast.makeText(QrCodeConfigActivity.this,"config success!",Toast.LENGTH_LONG).show();}});}

其中生成二维码图片示例代码如下:

public static Bitmap createQRCode(String url, int widthAndHeight)throws WriterException {Hashtable hints = new Hashtable();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");hints.put(EncodeHintType.MARGIN,0);BitMatrix matrix = new MultiFormatWriter().encode(url,BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight, hints);int width = matrix.getWidth();int height = matrix.getHeight();int[] pixels = new int[width * height];for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {if (matrix.get(x, y)) {pixels[y * width + x] = BLACK; //0xff000000}}}Bitmap bitmap = Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888);bitmap.setPixels(pixels, 0, width, 0, 0, width, height);return bitmap;}

开始配网

开始配网前,请确保设备处于待配网状态。操作方法可参考设备的使用说明书。

在成功生成二维码后,引导用户将二维码对准摄像头,捕捉到二维码信息后会发出提示音。开始配网操作后,SDK 会持续广播配网信息,直到配网成功或是超时才停止。

调用 配网接口。目前已经创建好 TuyaCameraActivatorBuilder 对象 builder,只需进行下面几行代码调用即可。

mTuyaActivator = TuyaHomeSdk.getActivatorInstance().newCameraDevActivator(builder);mTuyaActivator.createQRCode();mTuyaActivator.start();

监听配网结果

在上面构建配网参数时候,我们通过 TuyaCameraActivatorBuilder 对象 builder 设置监听,通过 ITuyaSmartCameraActivatorListener 回调监听配网结果。

public interface ITuyaSmartCameraActivatorListener {void onQRCodeSuccess(String qrcodeUrl);void onError(String errorCode, String errorMsg);void onActiveSuccess(DeviceBean devResp);
}

停止配网

如果需要中途取消配网,如离开配网页面,或配网完成,请调【停止配网】接口。

mTuyaActivator.stop();

视频实时预览(视频直播)

IPC SDK 提供智能摄像机的实时视频播放、设备存储卡录像播放、对当前正在播放的视频截图、录制视频、与摄像机实时通话等基础能力。

第一步:初始化

我们需要首先初始化一个 ITuyaSmartCameraP2P 对象。该对象用于读取智能摄像机设备的相关属性和方法。

TuyaCameraView 是 IPC SDK 提供的视频渲染视图,通过它可以快速的搭建渲染出视频预览画面。

// 1. 创建 ITuyaSmartCameraP2P
ITuyaSmartCameraP2P mCameraP2P = null;
ITuyaIPCCore cameraInstance = TuyaIPCSdk.getCameraInstance();
if (cameraInstance != null) {mCameraP2P = cameraInstance.createCameraP2P(devId));
}
TuyaCameraView mVideoView = findViewById(R.id.camera_video_view);
// 2. 为渲染视图容器设置回调
mVideoView.setViewCallback(new AbsVideoViewCallback() {@Overridepublic void onCreated(Object view) {super.onCreated(view);//4. 渲染视图构造完成时,为 ITuyaSmartCameraP2P 绑定渲染视图if (null != mCameraP2P){mCameraP2P.generateCameraView(view);}}
});
// 3. 构造渲染视图
mVideoView.createVideoView(p2pType);
// 4. 注册 P2P 监听
if (null != mCameraP2P){mCameraP2P.registerP2PCameraListener(new AbsP2pCameraListener() {@Overridepublic void onSessionStatusChanged(Object camera, int sessionId, int sessionStatus) {super.onSessionStatusChanged(o, i, i1);}});
}

第二步:连接 P2P 通道

一系列初始化动作完成后,需要先连接 P2P 通道。P2P 的连接状态需要我们自行维护。

开始连接 P2P 通道,参数 mode 可以指定优先选择的连接模式,是通过局域网还是公网来连接。如果指定局域网连接优先,但是 App 和设备没有在同一个局域网内建立 TCP 连接,或者设备不支持局域网连接优先,SDK 会自动使用公网连接模式。

  • 建立指定通道

    void connect(String devId, int mode, OperationDelegateCallBack callBack);
    
  • 断开通道

    在关闭通道或离开当前页面时,我们需要调用接口关闭通道。

    void disconnect(String devId, OperationDelegateCallBack callBack);
    
  • 状态监听

    若需要在过程中监听通道的连接和断开,可通过 OperationDelegateCallBack 来实现监听。

    mCameraP2P.connect(devId, new OperationDelegateCallBack() {@Overridepublic void onSuccess(int sessionId, int requestId, String data) {//连接成功}@Overridepublic void onFailure(int sessionId, int requestId, int errCode) {//连接失败}
    });
    }
    

第三步:预览实时视频

在建立 P2P 通道后,用户就可以预览在线视频了。

  • 开始预览

    以下代码中,clarity 是清晰度模式,2 代表标清、4 代表高清。

    void startPreview(int clarity, OperationDelegateCallBack callBack);
    
  • 结束预览

    int stopPreview(OperationDelegateCallBack callBack);
    
  • 状态监听

    实现如下代码可以监听视频开始预览的状态变化,stopPreview 同理。

    mCameraP2P.startPreview(new OperationDelegateCallBack() {@Overridepublic void onSuccess(int sessionId, int requestId, String data) {//开始播放实时视频成功}@Overridepublic void onFailure(int sessionId, int requestId, int errCode) {//开始播放实时视频失败}
    });
    

第四步:注销进程

不再使用摄像机视频功能的时候,请务必注销 P2P 监听器和删除 P2P 对象。

@Override
public void onDestroy() {if (null != mCameraP2P) {mCameraP2P.removeOnP2PCameraListener();mCameraP2P.destroyP2P();}
}

视频录制与实时对讲

在预览实时视频的同时,还可以对录制在线视频或通过摄像机实时对讲。

  • 开始录制或对讲

    int startRecordLocalMp4(String folderPath, Context context, OperationDelegateCallBack callBack);
    void startAudioTalk(OperationDelegateCallBack callBack);
    
  • 结束录制/对讲

    int stopRecordLocalMp4(OperationDelegateCallBack callBack);
    void stopAudioTalk(OperationDelegateCallBack callBack);
    
  • 监听状态

    我们可以通过监听回调事件 OperationDelegateCallBack 来监听录制和实时对讲的状态。

    public interface OperationDelegateCallBack {void onSuccess(int sessionId, int requestId, String data);void onFailure(int sessionId, int requestId, String data);
    }
    

回放历史视频

设备在存储卡中保存视频录像后,可以通过 IPC SDK 在 App 端播放视频录像。

和视频预览一样,在开始回放前,需要先连接上 P2P 通道。

IPC SDK 支持以天为单位查看和播放视频录像,并且提供查询某年某月中,哪几天保存有视频录像,以便于用户查看,查询结果通过 OperationDelegateCallBack 监听回调返回。

查询视频列表

创建 ITuyaSmartCameraP2P 对象,连接上 P2P 通道。P2P 通道连接成功后,可以获取到设备端存储卡中录制的视频片段时间信息。

第一步:查询特定月份保存过视频的日期

int year = Integer.parseInt(substring[0]);
int mouth = Integer.parseInt(substring[1]);
queryDay = Integer.parseInt(substring[2]);
mCameraP2P.queryRecordDaysByMonth(year, mouth, new OperationDelegateCallBack() {@Overridepublic void onSuccess(int sessionId, int requestId, String data) {//data 是获取到的月份数据MonthDays monthDays = JSONObject.parseObject(data, MonthDays.class);mBackDataMonthCache.put(mCameraP2P.getMonthKey(), monthDays.getDataDays());mHandler.sendMessage(MessageUtil.getMessage(MSG_DATA_DATE, ARG1_OPERATE_SUCCESS, data));}@Overridepublic void onFailure(int sessionId, int requestId, int errCode) {mHandler.sendMessage(MessageUtil.getMessage(MSG_DATA_DATE, ARG1_OPERATE_FAIL));}
});

第二步:获取特定日期的视频列表

我们可以根据上一步返回的日期查询当天的视频信息列表。

int year = Integer.parseInt(substring[0]);
int mouth = Integer.parseInt(substring[1]);
int day = Integer.parseInt(substring[2]);
mCameraP2P.queryRecordTimeSliceByDay(year, mouth, day, new OperationDelegateCallBack() {@Overridepublic void onSuccess(int sessionId, int requestId, String data) {//data 是获取到指定日期的视频片段数据parsePlaybackData(data);}@Overridepublic void onFailure(int sessionId, int requestId, int errCode) {mHandler.sendEmptyMessage(MSG_DATA_DATE_BY_DAY_FAIL);}
});

private void parsePlaybackData(Object obj) {RecordInfoBean recordInfoBean = JSONObject.parseObject(obj.toString(), RecordInfoBean.class);if (recordInfoBean.getCount() != 0) {List<TimePieceBean> timePieceBeanList = recordInfoBean.getItems();if (timePieceBeanList != null && timePieceBeanList.size() != 0) {mBackDataDayCache.put(mCameraP2P.getDayKey(), timePieceBeanList);}mHandler.sendMessage(MessageUtil.getMessage(MSG_DATA_DATE_BY_DAY_SUCC, ARG1_OPERATE_SUCCESS));} else {mHandler.sendMessage(MessageUtil.getMessage(MSG_DATA_DATE_BY_DAY_FAIL, ARG1_OPERATE_FAIL));}}

以上代码涉及了以下 2 个实体对象类:

  • RecordInfoBean 数据模型:

    参数 说明
    count 片段个数
    List 视频片段集合
  • TimePieceBean 数据模型:

    参数 说明
    startTime 视频片段开始时间
    endTime 视频片段结束时间
    playTime 视频片段播放时间

完成以上步骤,我们就可以获取到有回放的视频片段。

播放视频

成功查询到某天中的视频录像片段后,就可以开始播放录像视频了。

  • 开始播放

    mCameraP2P.startPlayBack(timePieceBean.getStartTime(),timePieceBean.getEndTime(),timePieceBean.getStartTime(), new OperationDelegateCallBack() {@Overridepublic void onSuccess(int sessionId, int requestId, String data){isPlayback = true;}@Overridepublic void onFailure(int sessionId, int requestId, int errCode){isPlayback = false;}}, new OperationDelegateCallBack() {@Overridepublic void onSuccess(int sessionId, int requestId, String data){isPlayback = false;}@Overridepublic void onFailure(int sessionId, int requestId, int errCode){isPlayback = false;}});
    

    该方法的三个参数均为时间戳:

    • PlayTime 为播放的初始帧时间,可以与 startTime 设置为同一值。
    • StartTime 为播放的开始时间,为 TimePieceBean 数据模型中 startTime 相对应的值。
    • EndTime 为播放的结束时间,为 TimePieceBean ​​​​​​​数据模型中 endTime 相对应的值。
  • 暂停回放

    void pausePlayBack(OperationDelegateCallBack callBack);
    
  • 继续回放

    void resumePlayBack(OperationDelegateCallBack callBack);
    
  • 停止回放

    void stopPlayBack(OperationDelegateCallBack callBack);
    
  • 监听回调(OperationDelegateCallBack)

    public interface OperationDelegateCallBack {void onSuccess(int sessionId, int requestId, String data);void onFailure(int sessionId, int requestId, String data);
    }
    

相关概念

涂鸦智能摄像机的视频录像分为 连续录像 和 事件录像

  • 连续录像:视频录像会是 10 分钟一个片段,且所有视频片段是连续的,但是如果中间有停止过视频录像,那么连续录像模式下的视频片段间也可能会有间隔。

    如果某天的视频录像片段是连续的,那么播放录像时,会自动播放下一段。也就是说,即使调用开始播放接口,传入的是当天第一个视频片段的时间点,视频也会一直播放到当天最后一个视频片段的最后一帧视频,才会回调视频播放结束的代理方法。

  • 事件录像:每个录像片段长度不等,且片段间的间隔时间也长短不一。

    如果某天的视频录像片段是不连续的,即视频录像片段 A 结束后隔了一段时间才有视频录像片段 B,在播放到断开的地方(即播放到视频片段 A 的最后一帧),视频流会自动停止。

下一步

IPC SDK 还提供了更多功能,大家可以登录涂鸦 IoT 开发平台​​​​​​​,根据 Sample 工程和 IPC SDK 文档了解如何构建 App。

IP 摄像机移动应用 SDK 开发入门教程(安卓版)相关推荐

  1. 微信公众平台开发入门教程[2019版]

    关键字:微信公众平台开发 作者:方倍工作室 在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/JS等基础. 我们将使用微信公 ...

  2. 微信公众平台开发入门教程[2020版]

    在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/JS等基础. 我们将使用微信公众账号方倍工作室作为讲解的例子,二维码见左侧 ...

  3. zybo的linux开发教程,Zybo全栈开发入门教程——连载三:创建Linux设备驱动和应用程序...

    作者:Commanderfranz,编译: kenshin 通过前面两篇文章我们不仅创建的自定义IP模块还移植了Linux操作系统,今天这篇文章的内容是将这两部分联系起来,其实我们创建的myLed I ...

  4. IntelliJ IDEA开发入门教程

    IntelliJ IDEA开发入门教程 本系列教程从 IntelliJ IDEA 的安装.卸载.软件设置.项目配置等各个方面进行讲解.通过本系列教程的学习,也希望你能爱上 IntelliJ IDEA, ...

  5. Android百度地图开发入门教程

    Android百度地图开发入门教程 1.平台注册登录 2.创建应用 3.Android studio配置 4.代码编写 5.最终效果(建议真机) 1.平台注册登录 登录百度地图开放平台网站注册并登录 ...

  6. Kinect for Windows SDK开发入门

    Kinect for Windows SDK开发入门(一):开发环境配置 首先来看一下Kinect设备: 1. Kinect设备 黑色的Kinect设备如下图:基座和感应器之间有一个电动的马达,通过程 ...

  7. 傻瓜式Android APP开发入门教程

    这篇文章主要介绍了Android APP开发入门教程,从SDK下载.开发环境搭建.代码编写.APP打包等步骤一一讲解,非常简明的一个Android APP开发入门教程,android各种机子和rom的 ...

  8. 简易的服务器接口开发入门教程

    前沿 谷丝小说网 https://www.wayi.info 为了解决服务器接口开发的问题,因此学习了关于Spring Boot的知识,然后再自己摸索总结后台的开发经验.所以这篇文章就是面向搞移动开发 ...

  9. 2012 android开发工具,2012最新完整版Android开发入门教程

    此文档为2012年最新完整版的Android开发入门教程,免费分享给大家,希望大家喜欢! 点击索取: android开发者资料大全 第一篇:安装SDK 这里主要介绍如何安装Android的SDK开发包 ...

最新文章

  1. firefox推荐插件
  2. python flask 部署_python flask 部署
  3. PP模块常用事务代码清单
  4. HikariCP连接池配置
  5. 拖动卡顿_四招教你解决PS软件卡顿问题!
  6. php 字符串固定长度,不够补充其他字符串
  7. 慕课软件质量保证与测试(总目录)
  8. 自然语言处理之语料库
  9. 暑期作息时间表模板_2015中学生暑假作息时间表模板
  10. win10关机慢!windows10关机慢
  11. pr导入无法打开磁盘上的文件_为什么用pr导入视频显示文件导入失败?
  12. 苹果xr如何关机_苹果新系统让这些 iPhone 电量满血复活
  13. Java 五子棋(一)绘制棋盘、棋子
  14. 呵呵,GET2017教育科技大会VIP门票,你要不要啊?
  15. 《沈剑架构师训练营》第7章 - 架构解耦
  16. 教你用python在excel中“画画”
  17. Github的wiki编写
  18. [论文速览] Probing Neural Network Comprehension of Natural Language Arguments
  19. CISA考试通过了!!
  20. 【总结】 ---ACM为什么这么难

热门文章

  1. N32G031系列安全启动应用笔记
  2. 免费的绘图工具DrowIO下载及安装
  3. 使用cv2和PIL实现图片格式转换,以png转jpg为例
  4. ASP.NET 创建、发布、使用Web服务的详细方法
  5. [转]地球坐标 火星坐标 百度坐标 相互转换
  6. leaflet地图联动的简单实现
  7. IBM笔记本驱动安装顺序
  8. jni学习实例(二)-a7105模块驱动之jni
  9. 计算机设备管理器系统设备,win7系统计算机管理中没有“设备管理器”的操作方法...
  10. 安装APK时显示“已安装了签名冲突的应用”,但是手机上又没有该软件的解决办法