Android-再次解读萤石云视频
### 前言
我之前写过一篇萤石云的集成文章,很多人问我有没有demo, 今天我再次总结一下, 并加个些功能。
- 集成步骤
- 视频预览播放
- 视频放大缩小
- 视频的质量切换
- 截图
- 视频加载细节
之前的文章大家可以看下面的链接:
https://mp.weixin.qq.com/s/V4F2_bkY8QFN167KY9gSDg
先看效果图:

### 集成步骤
###### 1.安装SDK
```
dependencies {
compile 'com.hikvision.ezviz:ezviz-sdk:4.8.6.2'
}
```
###### 2.配置工程
(1).权限配置
在 AndroidMainfest.xml 文件中添加:
```
//网络权限
//存储权限
//wifi 状态权限
//热点配网扫描wifi需要使用
```
(2).配置build.gradle
```
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a"//只支持v7a
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
```
(3).配置 AndroidManifest.xml
添加如下activity定义,用于sdk中间页显示,包含登录、开通云存储等。
```
```
具体可以参考官方集成网站
https://open.ys7.com/doc/zh/book/4.x/android-sdk.html
### 视频预览播放
播放与之前版本不同,**加入设备的验证码**
```
mEZPlayer.setPlayVerifyCode("验证码");
```
(1).SDK初始化(在application中初始化)
```
/** * sdk日志开关,正式发布需要去掉 */
EZOpenSDK.showSDKLog(true);
/** * 设置是否支持P2P取流,详见api */
EZOpenSDK.enableP2P(false);
/** * APP_KEY请替换成自己申请的 */
EZOpenSDK.initLib(this, APP_KEY);
```
(2).播放主要代码
设置token
```
EZOpenSDK.getInstance().setAccessToken("你的token");
```
**实现代码:**
布局主要控件是SurfaceView,SurfaceView的用法大家应该都知道吧,主要实现了implements SurfaceHolder.Callback接口,声明SurfaceView 对象,并实方法,代码如下:
```
private SurfaceView mRealPlaySv = null;
private SurfaceHolder mRealPlaySh = null;
```
```
mRealPlaySh = mRealPlaySv.getHolder();
mRealPlaySh.addCallback(VideoActivity.this);
```
```
Override
public void surfaceCreated(SurfaceHolder holder) {
if (mEZPlayer != null) {
mEZPlayer.setSurfaceHold(holder);
} else {
}
mRealPlaySh = holder;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mEZPlayer != null) {
mEZPlayer.setSurfaceHold(null);
}
mRealPlaySh = null;
}
```
```
```
实现Handler.Callback,来监听播放结果回调:
```
@Override
public boolean handleMessage(Message msg) {
switch (msg.what){
}
return false;
}
```
配置:
```
//用来存储萤石云的播放质量、序列号
mCameraInfo=new EZCameraInfo();
// 2-高清,1-标清,0-流畅
mCameraInfo.setVideoLevel(2);
//序列号
mCameraInfo.setDeviceSerial("C86398971");
mCameraInfo.setCameraNo(1);
```
开始播放:
```
private void startRealPlay() {
mEZPlayer = YourApplication.getOpenSDK().createPlayer(mCameraInfo.getDeviceSerial(), mCameraInfo.getCameraNo());
mEZPlayer.setPlayVerifyCode(mVerificationCode);
mEZPlayer.setHandler(mHandler);
mEZPlayer.setSurfaceHold(mRealPlaySh);
mEZPlayer.startRealPlay();
tvPlay.setEnabled(true);
}
```
### **视频放大,手势放大功能**
在播放成功的回调里加上 setRealPlaySvLayout();方法,方法的代码如下:
```
private void setRealPlaySvLayout() throws InnerException, PlaySDKException {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int whdth = dm.widthPixels;
int height = dm.heightPixels;
mRealPlayTouchListener.setSacaleRect(Constant.MAX_SCALE, 0, 0, whdth, height);
setPlayScaleUI(1, null, null);
}
```
```
private void setPlayScaleUI(float scale, CustomRect oRect, CustomRect curRect) {
if (scale == 1) {
try {
if (mEZPlayer != null) {
mEZPlayer.setDisplayRegion(false, null, null);
}
} catch (BaseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
if (mPlayScale == scale) {
try {
if (mEZPlayer != null) {
mEZPlayer.setDisplayRegion(true, oRect, curRect);
}
} catch (BaseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
try {
if (mEZPlayer != null) {
mEZPlayer.setDisplayRegion(true, oRect, curRect);
}
} catch (BaseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mPlayScale = scale;
}
```
### 视频质量切换
效果图:

核心方法
```
// 2-高清,1-标清,0-流畅
mCameraInfo.setVideoLevel
```
切换画质
```
/**
* 码流配置 清晰度 2-高清,1-标清,0-流畅
*
* @see
* @since V2.0
*/
private void setQualityMode(final EZConstants.EZVideoLevel mode) {
if (mEZPlayer != null) {
mWaitDialog.setWaitText("正在设置画面质量…");
mWaitDialog.show();
Thread thr = new Thread(new Runnable() {
@Override
public void run() {
try {
// need to modify by yudan at 08-11
APP.getOpenSDK().setVideoLevel(mCameraInfo.getDeviceSerial(), mCameraInfo.getCameraNo(), mode.getVideoLevel());
mCurrentQulityMode = mode;
Message msg = Message.obtain();
msg.what = MSG_SET_VEDIOMODE_SUCCESS;
mHandler.sendMessage(msg);
} catch (BaseException e) {
mCurrentQulityMode = EZConstants.EZVideoLevel.VIDEO_LEVEL_FLUNET;
e.printStackTrace();
Message msg = Message.obtain();
msg.what = MSG_SET_VEDIOMODE_FAIL;
mHandler.sendMessage(msg);
}
}
}) {
};
thr.start();
}
}
```
切换画质结果:
```
//切换画质成功
case EZConstants.EZRealPlayConstants.MSG_SET_VEDIOMODE_SUCCESS:
handleSetVedioModeSuccess();
break;
//切换画质失败
case EZConstants.EZRealPlayConstants.MSG_SET_VEDIOMODE_FAIL:
handleSetVedioModeFail(msg.arg1);
break;
```
### 声音与截图
1.声音
核心方法:
```
mLocalInfo.setSoundOpen(false);
```
2.截图
核心方法:
```
mEZPlayer.capturePicture()
```
需要**源码**的朋友可以加我的微信:lengquele5311

大家可以关注我的微信公众号:「秦子帅」一个有质量、有态度的公众号!

Android-再次解读萤石云视频的更多相关文章
- vue接入萤石云视频
在萤石云开放平台注册开发者账号,网址:https://open.ys7.com/guide.html 在“开发者服务”-->“我的设备”里添加已有设备或者申请一个试用设备 然后点击“我的应用”里 ...
- 基于EasyDarwin云视频平台的幼儿园视频直播(手机直播/微信直播)解决方案
一.方案介绍 1.1.方案背景 在2016年10月25日至28日的安博会上,我们看到了不少的幼教平台厂商,我们注意到大部分的幼教平台,为了追求极佳的用户体验,在微信或者APP端能够做到极快的打开速度, ...
- Atitit.android播放smb 网络邻居视频文件解决方案
Atitit.android播放smb 网络邻居视频文件解决方案 Android4.4 1.1. Android4视频播放器不能直接地支持smb协议..子好先转换成个http流 1.2. ES文件浏览 ...
- 本人讲课时录制的Android应用开发技术教学视频
网盘地址:http://yun.baidu.com/pcloud/album/info?query_uk=1963923831&album_id=3523786484935252365 本人讲 ...
- ZEALER背后的乐视云视频
ZEALER是我非常喜欢的一个测评网站,经常访问看看手机.电动牙刷及机械键盘的测试视频,非常欣赏王自如的数据化测评理念.敬畏之心,以及不祛痘的视频. 刚好最近对网络视频应用比较感兴趣,觉得ZEALER ...
- Android SurfaceView + MediaPlayer实现分段视频无缝播放
Android当中实现视频播放的方式有两种,即:通过VideoView实现或者通过SurfaceView + MediaPlayer实现. 由浅至深,首先来看下想要在Android上播放一段视频,我们 ...
- PC电脑运行Android模拟器总是弹出“视频源”窗体的原因和解决方案
原因: PC电脑运行Android模拟器时弹出“视频源”窗体,会让你"选择视频设备",如:HP TruevIsion HD,而这个视频设备就是你电脑中的内置摄像头,这个内置摄像头在 ...
- android 播放assets文件里视频文件的问题
今天做了一个功能,就是播放项目工程里面的视频文件,不是播放SD卡视频文件. 因为之前写webview加载assets文件夹时,是这样写的: webView = new WebView(this); w ...
- 阿里云视频直播PHP-SDK
阿里云 视频直播 配置 及 PHP-SDK 接入教程准备工作域名管理配置鉴权地址生成器及DEMO演示-熟悉鉴权接入SDK推流回调的配置阿里云 视频直播 配置 及 PHP-SDK 接入教程 个人感觉,阿 ...
随机推荐
- Kafka 安装配置 及 简单实验记录
1. 下载二进制文件并解压,并修改 broker.id 的值 wget http://apache.fayea.com/kafka/0.10.0.0/kafka_2.10-0.10.0.0.tgz - ...
- luogu P4462 [CQOI2018]异或序列 |莫队
题目描述 已知一个长度为n的整数数列a1,a2,...,an,给定查询参数l.r,问在al,al+1,...,ar区间内,有多少子序列满足异或和等于k.也就是说,对于所有的x,y (I ≤ x ≤ ...
- 记录我的 python 学习历程-Day03 列表/元组/rang
一.列表初识 列表是 Python 的基础数据类型之一,它是以''[ ]''的形式括起来的,每个元素用","隔开,属于容器型数据类型,他可以存放大量的.各种类型的数据. 基本格式 ...
- 数据库Oracle数字函数
数字函数不多: ROUND(arg1):四舍五入保留整数. arg1:数字类型.原数字. arg2:整数类型.小数点保留的位数. SQL> select round(1256.564,2) fr ...
- 【原创】(十三)Linux内存管理之vma/malloc/mmap
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- 贝壳2020——Java校招笔试题
算法题4道: 题目描述: 给出n个正整数,要求找出相邻两个数字中差的绝对值最小的一对数字,如果有差的绝对值相同的,则输出最前面的一对数.(2<n<=100,正整数都在10^16范围内) 输 ...
- 【CSS】340- 常用九宫格布局的几大方法汇总
对,就是类似这样的布局~ 目录 1 margin负值实现 2 祖父和亲爹的里应外合 3 换个思路 - li生个儿子帮大忙 4 借助absolute方位值,实现自适应的网格布局 5 cloumn多 ...
- 《JavaScript 模式》知识点小抄本(上)
介绍 最近开始给自己每周订个学习任务,学习结果反馈为一篇文章的输出,做好学习记录. 这一周(02.25-03.03)我定的目标是<JavaScript 模式>的第七章学习一遍,学习结果的反 ...
- redis(3)--redis原理分析
过期时间设置 在Redis中提供了Expire命令设置一个键的过期时间,到期以后Redis会自动删除它.这个在我们实际使用过程中用得非常多.EXPIRE命令的使用方法为EXPIRE key secon ...
- 代码检查又一利器:ArchUnit
Code Review总是让人又爱又恨,它可以帮助我们在提测之前发现很多代码中比较"丢人"的问题,但是,Code Review通常会比写代码更加耗费精力,因为你需要理解别人的代码, ...