首先注册萤石
注册过程不多提,就是为了拿到key和Secret
基本上这些东西后台会提前弄好,我们只要通过接口拿来用就行
官方开发文档地址:https://open.ys7.com/doc/zh/book/4.x/android-sdk.html
项目接入:
首先安装 SDK
再build gradle中
dependencies {
/*萤石SDK核心模块,必须依赖*/
implementation 'com.ezviz.sdk:ezviz-sdk:4.15.1'
implementation 'com.ezviz.sdk:ezuikit:2.2.1'
}
为了兼容手机型号,build.gradle还要加入
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a"//自2.2版本开始支持arm64-v8a
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
添加权限
在 AndroidMainfest.xml 文件中添加:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
有的权限需要动态获取权限,动态获取权限我就不多说了,网上代码一堆,最好是兼容到当前最高版本。
现在为之 我们的第一步就已经实现
在需要显示播放的地方添加UI布局
<com.ezvizuikit.open.EZUIPlayer
android:id="@+id/player_ui"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#FF000000" />
activity中使用方法
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.ezvizuikit.open.EZUIError;
import com.ezvizuikit.open.EZUIKit;
import com.ezvizuikit.open.EZUIPlayer;
import com.videogo.util.LogUtil;
import java.util.Calendar;
/**
* 预览界面
*/
public class PlayActivity extends Activity implements View.OnClickListener, WindowSizeChangeNotifier.OnWindowSizeChangedListener, EZUIPlayer.EZUIPlayerCallBack {
private static final String TAG = "PlayActivity";
public static final String APPKEY = "AppKey";
public static final String AccessToekn = "AccessToekn";
public static final String PLAY_URL = "play_url";
public static final String Global_AreanDomain = "global_arean_domain";
private EZUIPlayer mEZUIPlayer;
private Button mBtnPlay;
/**
* onresume时是否恢复播放
*/
private boolean isResumePlay = false;
private MyOrientationDetector mOrientationDetector;
/**
* 开发者申请的Appkey
*/
private String appkey;
/**
* 授权accesstoken
*/
private String accesstoken;
/**
* 播放url:ezopen协议
*/
private String playUrl;
/**
* 海外版本areaDomin
*/
private String mGlobalAreaDomain;
/**
* 开启预览播放
* @param context
* @param appkey 开发者申请的appkey
* @param accesstoken 开发者登录授权的accesstoken
* @param url 预览url
*/
public static void startPlayActivity(Context context,String appkey,String accesstoken,String url){
Intent intent = new Intent(context, PlayActivity.class);
intent.putExtra(APPKEY,appkey);
intent.putExtra(AccessToekn,accesstoken);
intent.putExtra(PLAY_URL,url);
context.startActivity(intent);
}
/**
* 开启海外版本预览播放
* @param context
* @param appkey 开发者申请的appkey
* @param accesstoken 开发者登录授权的accesstoken
* @param url 预览url
* @param global_AreanDomain 海外版本域名
*/
public static void startPlayActivityGlobal(Context context,String appkey,String accesstoken,String url,String global_AreanDomain){
Intent intent = new Intent(context, PlayActivity.class);
intent.putExtra(APPKEY,appkey);
intent.putExtra(AccessToekn,accesstoken);
intent.putExtra(PLAY_URL,url);
intent.putExtra(Global_AreanDomain,global_AreanDomain);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
super.onCreate(savedInstanceState);
LogUtil.d(TAG,"onCreate");
setContentView(R.layout.activity_play);
Intent intent = getIntent();
appkey = intent.getStringExtra(APPKEY);
accesstoken = intent.getStringExtra(AccessToekn);
playUrl = intent.getStringExtra(PLAY_URL);
mGlobalAreaDomain = intent.getStringExtra(Global_AreanDomain);
if (TextUtils.isEmpty(appkey)
|| TextUtils.isEmpty(accesstoken)
|| TextUtils.isEmpty(playUrl)){
Toast.makeText(this,"appkey,accesstoken or playUrl is null",Toast.LENGTH_LONG).show();
finish();
return;
}
mOrientationDetector = new MyOrientationDetector(this);
new WindowSizeChangeNotifier(this, this);
mBtnPlay = (Button) findViewById(R.id.btn_play);
//获取EZUIPlayer实例
mEZUIPlayer = (EZUIPlayer) findViewById(R.id.player_ui);
//设置加载需要显示的view
mEZUIPlayer.setLoadingView(initProgressBar());
mBtnPlay.setOnClickListener(this);
mBtnPlay.setText(R.string.string_stop_play);
preparePlay();
setSurfaceSize();
}
/**
* 创建加载view
* @return
*/
private View initProgressBar() {
RelativeLayout relativeLayout = new RelativeLayout(this);
relativeLayout.setBackgroundColor(Color.parseColor("#000000"));
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
relativeLayout.setLayoutParams(lp);
RelativeLayout.LayoutParams rlp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp.addRule(RelativeLayout.CENTER_IN_PARENT);//addRule参数对应RelativeLayout XML布局的属性
ProgressBar mProgressBar = new ProgressBar(this);
mProgressBar.setIndeterminateDrawable(getResources().getDrawable(R.drawable.progress));
relativeLayout.addView(mProgressBar,rlp);
return relativeLayout;
}
/**
* 准备播放资源参数
*/
private void preparePlay(){
//设置debug模式,输出log信息
EZUIKit.setDebug(true);
if (TextUtils.isEmpty(mGlobalAreaDomain)) {
//appkey初始化
EZUIKit.initWithAppKey(this.getApplication(), appkey);
}else{
//appkey初始化 海外版本
EZUIKit.initWithAppKeyGlobal(this.getApplication(), appkey,mGlobalAreaDomain);
}
//设置授权accesstoken
EZUIKit.setAccessToken(accesstoken);
//设置播放资源参数
mEZUIPlayer.setCallBack(this);
mEZUIPlayer.setUrl(playUrl);
}
@Override
protected void onResume() {
super.onResume();
mOrientationDetector.enable();
Log.d(TAG,"onResume");
//界面stop时,如果在播放,那isResumePlay标志位置为true,resume时恢复播放
if (isResumePlay) {
isResumePlay = false;
mBtnPlay.setText(R.string.string_stop_play);
mEZUIPlayer.startPlay();
}
}
@Override
protected void onPause() {
super.onPause();
mOrientationDetector.disable();
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG,"onStop + "+mEZUIPlayer.getStatus());
//界面stop时,如果在播放,那isResumePlay标志位置为true,以便resume时恢复播放
if (mEZUIPlayer.getStatus() != EZUIPlayer.STATUS_STOP) {
isResumePlay = true;
}
//停止播放
mEZUIPlayer.stopPlay();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestroy");
//释放资源
mEZUIPlayer.releasePlayer();
}
@Override
public void onPlaySuccess() {
Log.d(TAG,"onPlaySuccess");
// TODO: 2017/2/7 播放成功处理
mBtnPlay.setText(R.string.string_pause_play);
}
@Override
public void onPlayFail(EZUIError error) {
Log.d(TAG,"onPlayFail");
// TODO: 2017/2/21 播放失败处理
if (error.getErrorString().equals(EZUIError.UE_ERROR_INNER_VERIFYCODE_ERROR)){
}else if(error.getErrorString().equalsIgnoreCase(EZUIError.UE_ERROR_NOT_FOUND_RECORD_FILES)){
// TODO: 2017/5/12
//未发现录像文件
Toast.makeText(this,getString(R.string.string_not_found_recordfile),Toast.LENGTH_LONG).show();
}
}
@Override
public void onVideoSizeChange(int width, int height) {
// TODO: 2017/2/16 播放视频分辨率回调
Log.d(TAG,"onVideoSizeChange width = "+width+" height = "+height);
}
@Override
public void onPrepared() {
Log.d(TAG,"onPrepared");
//播放
mEZUIPlayer.startPlay();
}
@Override
public void onPlayTime(Calendar calendar) {
Log.d(TAG,"onPlayTime");
if (calendar != null) {
// TODO: 2017/2/16 当前播放时间
Log.d(TAG,"onPlayTime calendar = "+calendar.getTime().toString());
}
}
@Override
public void onPlayFinish() {
// TODO: 2017/2/16 播放结束
Log.d(TAG,"onPlayFinish");
}
@Override
public void onClick(View view) {
if (view == mBtnPlay){
// TODO: 2017/2/14
if (mEZUIPlayer.getStatus() == EZUIPlayer.STATUS_PLAY) {
//播放状态,点击停止播放
mBtnPlay.setText(R.string.string_start_play);
mEZUIPlayer.stopPlay();
} else if (mEZUIPlayer.getStatus() == EZUIPlayer.STATUS_STOP) {
//停止状态,点击播放
mBtnPlay.setText(R.string.string_stop_play);
mEZUIPlayer.startPlay();
}
}
}
/**
* 屏幕旋转时调用此方法
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG,"onConfigurationChanged");
setSurfaceSize();
}
private void setSurfaceSize(){
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
boolean isWideScrren = mOrientationDetector.isWideScrren();
//竖屏
if (!isWideScrren) {
//竖屏调整播放区域大小,宽全屏,高根据视频分辨率自适应
mEZUIPlayer.setSurfaceSize(dm.widthPixels, 0);
} else {
//横屏屏调整播放区域大小,宽、高均全屏,播放区域根据视频分辨率自适应
mEZUIPlayer.setSurfaceSize(dm.widthPixels,dm.heightPixels);
}
}
@Override
public void onWindowSizeChanged(int w, int h, int oldW, int oldH) {
if (mEZUIPlayer != null) {
setSurfaceSize();
}
}
public class MyOrientationDetector extends OrientationEventListener {
private WindowManager mWindowManager;
private int mLastOrientation = 0;
public MyOrientationDetector(Context context) {
super(context);
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
public boolean isWideScrren() {
Display display = mWindowManager.getDefaultDisplay();
Point pt = new Point();
display.getSize(pt);
return pt.x > pt.y;
}
@Override
public void onOrientationChanged(int orientation) {
int value = getCurentOrientationEx(orientation);
if (value != mLastOrientation) {
mLastOrientation = value;
int current = getRequestedOrientation();
if (current == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|| current == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
}
}
private int getCurentOrientationEx(int orientation) {
int value = 0;
if (orientation >= 315 || orientation < 45) {
// 0度
value = 0;
return value;
}
if (orientation >= 45 && orientation < 135) {
// 90度
value = 90;
return value;
}
if (orientation >= 135 && orientation < 225) {
// 180度
value = 180;
return value;
}
if (orientation >= 225 && orientation < 315) {
// 270度
value = 270;
return value;
}
return value;
}
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_play"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/player_layout"
android:layout_width="match_parent"
android:background="#FFF8FF00"
android:layout_height="wrap_content">
<com.ezvizuikit.open.EZUIPlayer
android:id="@+id/player_ui"
android:layout_width="match_parent"
android:background="@color/black"
android:layout_height="wrap_content"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/player_layout"
android:background="#ff888888">
<Button
android:id="@+id/btn_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:textColor="#FFFFFFFF"
android:background="#66000000"
android:text="停止"
android:layout_marginTop="20dp"/>
</RelativeLayout>
</RelativeLayout>
到次,停止和开始播放完成。
自动旋转完成。
基本的功能都已经差不多了,其他还要的功能,文档中也有对应的提到,多查看文档和官方代码,都能找到你想要的功能。
忘记放了一个工具类:
import android.app.Activity;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
public class WindowSizeChangeNotifier {
private View mChildOfContent;
private Point mPreviousPoint = null;
private OnWindowSizeChangedListener mListener = null;
public static interface OnWindowSizeChangedListener {
void onWindowSizeChanged(int w, int h, int oldW, int oldH);
}
public WindowSizeChangeNotifier(Activity activity, OnWindowSizeChangedListener onWindowSizeChangedListener) {
mListener = onWindowSizeChangedListener;
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
}
private void possiblyResizeChildOfContent() {
Point pointNow = computeUsablePoint();
if(mPreviousPoint == null) {
mPreviousPoint = pointNow;
return;
}
if (pointNow.x != mPreviousPoint.x || pointNow.y != mPreviousPoint.y) {
if(mListener != null) {
mListener.onWindowSizeChanged(pointNow.x, pointNow.y, mPreviousPoint.x, mPreviousPoint.y);
}
mPreviousPoint = pointNow;
}
}
private Point computeUsablePoint() {
Point p = new Point();
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
p.x = r.width();
p.y = r.height();
return p;
}
}