作为一个小白,刚看萤石云的sdk是有点云里雾里的。在接入文档中,它给你讲解了如何登陆入平台,但是到了播放那边却开始一笔带过。甚至于官方的视频教程居然还用的是eclipse的。这就很离谱了。好在使用萤石云的大神也有很多。今天集成成功的功劳来自于这两位。
sunshine_0707 -- 这位提供了一个简洁的代码块,可以直接顺利地调用摄像头播放。
秦子帅 -- 这位很详细地讲解了如何配置该sdk。奈何本人略小白,眼睛看懂了,脑子还是没跟上,手就更没有跟上了。
于是决定先记录下来,等晚一些时候将集成步骤写出来,留做笔记。
本文基于Android Studio开发。
首先按照文档来,没什么好说的。
使用 Gradle 获得
如果是之前采用过直接下载方式的需要删除之前拷贝进来的所有so库文件以及jar包
dependencies {
compile 'com.ezviz.sdk:ezviz-sdk:4.9.0.6'
}
配置 Android 权限
在 AndroidMainfest.xml 文件中添加:
//网络权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
//存储权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//wifi 状态权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
//热点配网扫描wifi需要使用
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
配置build.gradle
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a" //自4.8.8版本开始支持arm64-v8a
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
配置 AndroidManifest.xml
添加如下activity定义,用于sdk中间页显示,包含登录、开通云存储等。
<activity
android:name="com.videogo.main.EzvizWebViewActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
添加如下广播接收器,用于接收中间页登录成功消息启动其他界面。将you_BroadcastReceiver替换为自己代码中定义的BroadcastReceiver。
(Android8.0及以上系统,由于静态注册广播的限制,很可能会收不到登录成功的广播,因此建议改用在代码中动态注册的方式注册BroadcastReceiver)
<receiver
android:name="you_BroadcastReceiver"
android:exported="false" >
<intent-filter>
<action android:name="com.videogo.action.OAUTH_SUCCESS_ACTION" />
</intent-filter>
</receiver>
这里的广播要做实例,例如 android:name=".thisBroadcastReceiver"的话,新建一个类thisBroadcastReceiver,extends BroadcastReceiver
public class thisBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(),"com.videogo.action.OAUTH_SUCCESS_ACTION")){
EZAccessToken accessToken = EZOpenSDK.getInstance().getEZAccessToken();
// begin your work
}
}
}
然后在AndroidManifest里的Application里添加name
<application
android:allowBackup="true"
android:name=".thisApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
然后新建类thisApplication
public class thisApplication extends Application {
private static String APP_KEY = "你懂的";
@Override
public void onCreate() {
super.onCreate();
//初始化sdk
/** * sdk日志开关,正式发布需要去掉 */
EZOpenSDK.showSDKLog(true);
/** * 设置是否支持P2P取流,详见api */
EZOpenSDK.enableP2P(false);
EZOpenSDK.initLib(this,APP_KEY);
}
}
这样前期工作就做完了。
然后在要播放视频的页面xml里添加一个SurfaceView
<SurfaceView
android:id="@+id/remoteplayback_sv"
android:layout_width="match_parent"
android:layout_height="500dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
随便写,demo用的。需要做调整的可以自己调整一下位置大小。
然后。。。就是将sunshine_0707的代码拿过来用上去,就可以了。
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{
private SurfaceView mRealPlaySv;
private SurfaceHolder mRealPlaySh;
private EZPlayer mEZPlayer = null;
private List<EZDeviceInfo> mDeviceInfoList;
//摄像头底部的序列号
private final int serialNo='6***********5';
//摄像头底部的验证码
private final String code='G***********J';
private static final int MSG_ON_DEVICE_RESPONSE= 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* 这里的AccessToken取个值,用来写Demo的
* 写项目的时候要注意AccessToken每隔一个星期就会改变一次
* */
String accessToken="at.d*******************************3mn";
EZOpenSDK.getInstance().setAccessToken(accessToken);
mRealPlaySv=(SurfaceView)findViewById(R.id.remoteplayback_sv);
mRealPlaySh = mRealPlaySv.getHolder();
mRealPlaySh.addCallback(this);
new Thread() {
@Override
public void run() {
super.run();
try {
mDeviceInfoList = EZOpenSDK.getInstance().getDeviceList(0, 20);
mHandler.sendEmptyMessage(MSG_ON_DEVICE_RESPONSE);
} catch (BaseException e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 通过ezdevice 得到其中通道信息
* @param deviceInfo
* @return
*/
public static EZCameraInfo getCameraInfoFromDevice(EZDeviceInfo deviceInfo, int camera_index) {
if (deviceInfo == null) {
return null;
}
if (deviceInfo.getCameraNum() > 0 && deviceInfo.getCameraInfoList() != null && deviceInfo.getCameraInfoList().size() > camera_index) {
return deviceInfo.getCameraInfoList().get(camera_index);
}
return null;
}
private void startPlay() {
EZDeviceInfo deviceInfo = null;
for (EZDeviceInfo ezDeviceInfo : mDeviceInfoList) {
Log.d("EZDeviceInfo", ezDeviceInfo.getDeviceName() + ";;SN=" + ezDeviceInfo.getDeviceSerial() + ";; type=" + ezDeviceInfo.getDeviceType());
//比较的自己的摄像头底部上写的序列号
if (serialNo.equals(ezDeviceInfo.getDeviceSerial())) {
deviceInfo = ezDeviceInfo;
break;
}
}
if(deviceInfo == null){
return;
}
//获取使用的摄像头信息
EZCameraInfo cameraInfo = getCameraInfoFromDevice(deviceInfo,0);
//创建播放器对象
mEZPlayer = EZOpenSDK.getInstance().createPlayer(cameraInfo.getDeviceSerial(), cameraInfo.getCameraNo());
if (mEZPlayer == null)
return;
if (cameraInfo == null) {
return;
}
//设置handler,该handler被用于从播放器向handler传递消息
mEZPlayer.setHandler(mHandler);
//设置播放器显示的surface
mEZPlayer.setSurfaceHold(mRealPlaySh);
//开始播放
mEZPlayer.startRealPlay();
//视频的加密密码,默认为摄像头的验证码
mEZPlayer.setPlayVerifyCode(code);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mEZPlayer != null) {
mEZPlayer.setSurfaceHold(holder);
}
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;
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MSG_ON_DEVICE_RESPONSE:
//开始播放
startPlay();
break;
}
}
};
}
————————————————
版权声明:本文为CSDN博主「sunshine_0707」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sunshine_0707/article/details/88546606
至此,你已经可以完美播放了。然后分析一下自己的需求。
序列号和验证码那边。
因为我不止一个设备需要播放,所以需要使用list将设备列表列出来。
大神写的demo中,是指定了序列号,然后通过对比之后取出相应的设备信息,然后进行播放。
for (EZDeviceInfo ezDeviceInfo : mDeviceInfoList) {
Log.d("EZDeviceInfo", ezDeviceInfo.getDeviceName() + ";;SN=" + ezDeviceInfo.getDeviceSerial() + ";; type=" + ezDeviceInfo.getDeviceType());
//比较的自己的摄像头底部上写的序列号
if (serialNo.equals(ezDeviceInfo.getDeviceSerial())) {
deviceInfo = ezDeviceInfo;
break;
}
}
只要将这段改动一下,就可以得到一个设备列表。然后通过序列码-验证码的map一一对应,做到选择播放。