package com.views.opengl;
import java.io.File;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import P2P.SDK;
import P2P.ViESurfaceRenderer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.media.AudioManager;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.basic.APP;
import com.basic.XMSG;
import com.bean.DeviceParcel;
import com.ctrl.XImageBtn;
import com.views.BaseApplication;
import com.views.Dlg_WaitForActivity;
import com.views.Login;
import com.views.Fun_Cloud;
import com.views.NewMsgDetail;
import com.views.opengl.ScaleScrollView.OnValueChangeListener;
import com.views.opengl.yuv.GLFrameRenderer;
import com.views.setting.SETMainActivity;
import com.manniu.laviewpano.R;
import com.utils.BitmapUtils;
import com.utils.Constants;
import com.utils.DateUtil;
import com.utils.ExceptionsOperator;
import com.utils.FileUtil;
import com.utils.LogUtil;
import com.utils.SdCardUtils;
import com.views.analog.camera.audio.AudioQueue;
import com.views.analog.camera.audio.AudioRecorder;
import com.views.analog.camera.encode.DecoderDebugger;
import com.views.analog.camera.encode.DecoderQueueOpengl;
/**
* @author: li_jianhua Date: 2016-5-23 上午10:48:22
* To change this template use File | Settings | File Templates.
* Description://设备-实时视频-opengl实现
*/
@SuppressLint({ "WrongCall", "NewApi", "ClickableViewAccessibility", "SimpleDateFormat" })
public class Fun_RealPlayerOpenGL extends Activity implements OnClickListener,OnTouchListener, SurfaceTexture.OnFrameAvailableListener,SensorEventListener{
private String TAG = Fun_RealPlayerOpenGL.class.getSimpleName();
public static Fun_RealPlayerOpenGL instance = null;
private FrameLayout framelayout;
private FrameLayout _hreadframeLayout;
private LinearLayout.LayoutParams params;
public GLSurfaceView glView;
public GLFrameRenderer renderer;
private int[] pixels;
private LinearLayout footer;//菜单layout
/** 菜单按钮 */
private Button _btnBack,_btnSetting;
/** 云端录像、报警回放*/
private Button _streamSet,_streamSet2;//_streamSet2 全屏的码流选择
private XImageBtn _audio,_cut,_btnTalk,_video,_btnGpu;
private XImageBtn _audio2,_cut2,_btnTalk2,_video2;//横屏处理
private TextView _devName, _result,_currentText;//_result时间轴滑动返回值
public static boolean isPlay = false; //视频播放状态
public boolean isPlayBack = false; //回放的视频播放状态
public static boolean isGpu = false;//软硬切换
Handler handler = new Handler();
private MyHandler _handler = null;
public static int _playId = 0; //播放ID
public boolean isResume = false;
private Dlg_WaitForActivity _dlgWait = null;
private final int MAX_IMG_BUFFER_SIZE = 2560 * 1600 * 3;
/** Image数据 */
private byte[] m_imageData = null;
/** 绘图源数据 */
private Bitmap m_imageBitmap = null;
public DecoderDebugger _decoderDebugger = null;//视频硬解码 ok
public DecoderQueueOpengl _decoderQueue;//解码队列
public AudioQueue _sQueue; //音频软解码 AAC 卡
public AudioRecorder _talkPlayer; //音频采集
private int channelNo = 0,channels = 0;//channels:通道数
private int isowner = 0,isNvr = 0;//是否是辅用户isowner:1-主用户 0-辅用户 isnvr:1-true 0-false
private int _subUserState = 0;//子用户对设备的权限状态
private boolean _isRightsTalk = false;//子用户:语音对讲权限
private boolean _isRightsRecord = false;//子用户:录像回放
private String devName = "",devSid = "";
private DeviceParcel device;//设备对象
/** 添加录像回放 .....start*/
public static int _paly =0;//0 P2P 1.回放
public VideoBackHandler videoHandler;
private BaseApplication baseApp = null;
/** 当前播放的视频在视频列表中的序号 */
private int current_position = -1;
/** 是否滚动 */
private boolean isScroll = false;
/** 当前设备的录像信息 */
private RecordTimeBean m_dirInfo = null;
/** 添加录像回放.... end*/
private static String yyyyMMdd, startTime, endTime;
private RelativeLayout _linearTimeLine;
public SurfaceTexture mSurfaceTexture;//硬解码SurfaceTexture
private Surface mSurface;
//private int mTextureID = -1;
/** 码流统计 */
private TextView m_dataFlowView = null;
/** 码流相关 总流量 */
long m_totalDataFlow = 0;
//时间轴
private ScaleScrollView scrollView;
private List<RecordTimeBean> dirInfoList = new ArrayList<RecordTimeBean>();
private Calendar calendar;
private ImageView mQrLineView;//时间轴动画、对讲动画,talkView,talkAnimation
private ScaleAnimation animation;
private LinearLayout talk_record;
private ImageView iv_volume;
private boolean mQrLineIsShow = true;//时间轴动画是否显示
//读取码流设置
private SharedPreferences _preferences;
private Editor _editor;
private final String STREAM = "STREAM";
private int _stream = 1;//0:主码流(高清),1:流畅(默认值辅码流) 2:标清(辅码流)
private int _StreamDefinition = 2;//1:流畅 2:流畅、标准 3:更新码流暂时不管
public boolean _isBack = false;//是否有回放时间轴
private boolean _isScreen = false;//是否全屏显示
private MyOnTouchListener myOnTouch = new MyOnTouchListener();
/**
* 1.输入、输出都有 支持对讲
* 2.只有输入 支持伴音
* 3.2个都没有 都不支持
*/
private int devAudioInput = 0;//音频输入、输出
private int devAudioOutput = 0;
//新加功能
private ImageView iv_fullscreen;//全屏
//重力感应 以后要做移动时画面移到(暂时不做)
//private SensorManager sensorManager;
/**
* 以数组形式返回 尺寸 [0] = width, [1] = height
* @return
*/
//今天
private GridView gridViewToday = null;
private HorizontalScrollView hs = null ;
private LinearLayout gridfooter = null;
//昨天
private LinearLayout linear_Yesterday;
private int[] getSize(){
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int[] pixels = new int[2];
pixels[0] = dm.widthPixels;
pixels[1] = dm.heightPixels;
return pixels;
}
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.realplay_opengl);
instance = this;
device = getIntent().getParcelableExtra("device");
devName = device.devname;
devSid = device.sid;
channelNo = device.channelNo;
isowner = device.isowner;
channels = device.channels;
if(_paly == 0) yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
framelayout = (FrameLayout)findViewById(R.id.frame);
_hreadframeLayout = (FrameLayout) this.findViewById(R.id.hhheader);
params = (LinearLayout.LayoutParams)framelayout.getLayoutParams();
m_dataFlowView = (TextView) findViewById(R.id.realplayer_dataflow_txt);
iv_fullscreen = (ImageView) findViewById(R.id.realplayer_flow_fullscreen);
_streamSet = (Button) findViewById(R.id.stream_setting);
_streamSet.setOnClickListener(this);
_streamSet2 = (Button) findViewById(R.id.stream_setting2);
_streamSet2.setOnClickListener(this);
glView = (GLSurfaceView) findViewById(R.id.gl_SurfaceViewPlay1);
// 获取屏幕分辨率
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
renderer = new GLFrameRenderer(glView);
glView.setEGLContextClientVersion(2);
glView.setRenderer(renderer);
//注释之后onDrawFrame一直执行,打开就是手动渲染
glView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);//RENDERMODE_WHEN_DIRTY方式,这样不会让CPU一直处于高速运转状态
glView.setOnTouchListener(this);
ViESurfaceRenderer.ResetSurfaceHolder(this);
footer = (LinearLayout)findViewById(R.id.menu_pagefooter);
_audio = (XImageBtn)findViewById(R.id.btn_play_audio);
_cut = (XImageBtn)findViewById(R.id.btn_play_cut);
_video = (XImageBtn)findViewById(R.id.btn_play_video);
_btnGpu = (XImageBtn) findViewById(R.id.btn_play_gpu);
_btnTalk = (XImageBtn) findViewById(R.id.btn_play_talk);
//全屏的菜单
_audio2 = (XImageBtn)findViewById(R.id.btn_play_audio2);
_cut2 = (XImageBtn)findViewById(R.id.btn_play_cut2);
_video2 = (XImageBtn)findViewById(R.id.btn_play_video2);
_btnTalk2 = (XImageBtn) findViewById(R.id.btn_play_talk2);
_devName = (TextView)findViewById(R.id.dev_name);
_linearTimeLine = (RelativeLayout) findViewById(R.id.linear_timeline);
_currentText = (TextView) findViewById(R.id.cur_tv);
_btnSetting = (Button) findViewById(R.id.btn_setting_video);
if(channels > 1){
_devName.setText(devName +" channel:"+ (channelNo+1));
isNvr = 1;
_btnSetting.setVisibility(View.GONE);
}else{
_devName.setText(devName);
}
// 获取时间
calendar = Calendar.getInstance();
/** 添加录像回放 .....*/
baseApp = (BaseApplication)getApplication();
videoHandler = new VideoBackHandler();
_talkPlayer = new AudioRecorder();
_sQueue = new AudioQueue();
_result = (TextView) findViewById(R.id.result_text);
scrollView = (ScaleScrollView) findViewById(R.id.scalePanel);
if(isowner == 0){//辅用户
_btnSetting.setVisibility(View.GONE);
//辅用户要判断权限
getSubUserRights();
if(!_isRightsRecord){
_linearTimeLine.setVisibility(View.GONE);
_currentText.setVisibility(View.INVISIBLE);
_result.setVisibility(View.INVISIBLE);
}
}
if(isowner == 1 || _isRightsRecord){//主用户和子用户有权限
_result.setText(DateUtil.getCurrentStringDate("yyyy-MM-dd HH:mm:ss"));
scrollView.setCalendar(calendar);
}
mQrLineView = (ImageView) findViewById(R.id.scale_data_line);
animation = new ScaleAnimation(0.0f, 2.0f, 1.0f, 1.0f);
animation.setRepeatCount(-1);
animation.setRepeatMode(Animation.RESTART);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(1200);
talk_record = (LinearLayout) findViewById(R.id.ll_record);
iv_volume = (ImageView) findViewById(R.id.iv_volume);
/** 添加录像回放 .....*/
_audio.setOnClickListener(this);
_cut.setOnClickListener(this);
_video.setOnClickListener(this);
_btnGpu.setOnClickListener(this);
_btnSetting.setOnClickListener(this);
_btnTalk.setOnTouchListener(myOnTouch);
_btnTalk2.setOnTouchListener(myOnTouch);
_audio2.setOnClickListener(this);
_cut2.setOnClickListener(this);
_video2.setOnClickListener(this);
iv_fullscreen.setOnClickListener(this);
_btnBack = (Button) this.findViewById(R.id.btn_back_video);
_btnBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(isPlayBack){
realFlag = 0;
backFlag = 0;
if(isGpu){//如果当前是硬解,停止并切换图片默认走软解
SDK.SetDecoderModel(1,SDK._sessionIdContext);
_btnGpu.SetImages(R.drawable.gpu_false, R.drawable.gpu_false);
isGpu = false;
}
startRealPlayer();
}else{
stop();
}
}
});
pixels = getSize();
layout();
if(_dlgWait == null){
_dlgWait = new Dlg_WaitForActivity(this,R.style.dialog);
_dlgWait.setCancelable(true);
}
Fun_Cloud._isOpen = true;//打开视频标志位
_handler = new MyHandler();
_btnGpu.setClickable(true);
_cut.setClickable(true);
_preferences = getSharedPreferences(STREAM, MODE_PRIVATE);
_stream = _preferences.getInt("streamCode", 1);
if(_stream == 0){
_streamSet.setText(getText(R.string.Video_pop_high).toString());
_streamSet2.setText(getText(R.string.Video_pop_high).toString());
}else if(_stream == 1){
_streamSet.setText(getText(R.string.Video_pop_low).toString());
_streamSet2.setText(getText(R.string.Video_pop_low).toString());
}else if(_stream == 2){
_streamSet.setText(getText(R.string.Video_pop_center).toString());
_streamSet2.setText(getText(R.string.Video_pop_center).toString());
}
_StreamDefinition = _preferences.getInt(devSid, 0);
if(_StreamDefinition == 0 && isNvr == 0){//NVR暂时不去查
//查询支持码流路数
getStreams();
}else if(_StreamDefinition == 1){
updateStream();
}
SharedPreferences preferences = getSharedPreferences(Fun_Cloud.NEWMAIN, MODE_PRIVATE);
devAudioInput = preferences.getInt(devSid+202, 0);
devAudioOutput = preferences.getInt(devSid+203, 0);
// Get the SensorManager instance
// sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
//OnTouch监听器
private class MyOnTouchListener implements OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event){
try {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
//子用户判断对讲权限
if (isowner == 0 && !_isRightsTalk) break;
//回放和NVR只支持伴音
if(isPlayBack || isNvr == 1) break;
if(devAudioInput == 0) break;
//结束录音,打开播放声音
Constants.isOpenTalk = false;
Constants.isOpenSound = true;
talk_record.setVisibility(View.GONE);
handler.removeCallbacks(mPollTask);
if(!_bSound) _bSound = true;
if(_isScreen){
_btnTalk2.SetImages(R.drawable.talk1, R.drawable.talk1);
_audio2.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
}else{
_btnTalk.SetImages(R.drawable.talk1, R.drawable.talk1);
_audio.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
}
if(_talkFlag == 1){
_talkFlag = 0;
SDK.TalkCtrl(SDK._sessionIdContextTalk, 2);
}
break;
case MotionEvent.ACTION_DOWN:
//子用户判断对讲权限
if (isowner == 0 && !_isRightsTalk){
APP.ShowToast(getText(R.string.Err_NoRight).toString());
break;
}
//回放和NVR只支持伴音
if(isPlayBack || isNvr == 1){
APP.ShowToast(getText(R.string.Video_realPlayer_tip).toString());
break;
}
if(devAudioInput == 0 && devAudioOutput == 0){
APP.ShowToast(getText(R.string.Video_realPlayer_tip).toString());
break;
}
//开始录音,关闭播放声音
Constants.isOpenTalk = true;
Constants.isOpenSound = false;
if(_isScreen){
_btnTalk2.SetImages(R.drawable.talk2, R.drawable.talk2);
_audio2.SetImages(R.drawable.real_audio2, R.drawable.real_audio2);
}else{
_btnTalk.SetImages(R.drawable.talk2, R.drawable.talk2);
_audio.SetImages(R.drawable.real_audio2, R.drawable.real_audio2);
}
if(_talkFlag == 0){
_talkFlag = 1;
SDK.TalkCtrl(SDK._sessionIdContextTalk, 1);
}
if(!_isTalking){
//开启对讲线程
_isTalking = true;
_handler.sendEmptyMessage(XMSG.P2PConnect);
}
//获取音量
talk_record.setVisibility(View.VISIBLE);
Thread t = new Thread(mPollTask);
t.start();
break;
default:
break;
}
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
return true;
}
}
private Runnable mPollTask = new Runnable() {
public void run() {
try {
int mVolume = _talkPlayer.volume;
updateVolume(mVolume);
handler.postDelayed(mPollTask, 100);
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
};
// 更新音量图
private void updateVolume(int volume) {
try {
if(volume <= 33){
iv_volume.setImageResource(R.drawable.p1);
}else if(volume > 40){
iv_volume.setImageResource(R.drawable.p5);
}else if(volume > 35){
iv_volume.setImageResource(R.drawable.p4);
}else if(volume > 34){
iv_volume.setImageResource(R.drawable.p3);
}else if(volume > 33){
iv_volume.setImageResource(R.drawable.p2);
}
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
/** 定时刷新码流线程 */
public Timer _dataTimer = null;
@SuppressLint("DefaultLocale")
public void startRefreshDataSpeedInfoThread() {
if(_dataTimer != null){
_dataTimer.cancel();
_dataTimer = null;
}
if(_dataTimer == null){
_dataTimer = new Timer();
}
_dataTimer.schedule(new TimerTask() {
@Override
public void run() {
// 计算每秒当前通道的流量
if(SDK._sessionIdContext != 0){
long dataFlowEachSecond = SDK.P2PGetBitrate(SDK._sessionIdContext);
if(dataFlowEachSecond >= 0){
// 计算总流量
double curVideoBPS = dataFlowEachSecond;
final String dataStr = String.format(
"%2.2fKB/s", curVideoBPS * 8 / 1024/8);
Message msg = new Message();
msg.what = 0;
Bundle bundle = new Bundle();
bundle.putString("dataStr", dataStr);
msg.setData(bundle);
refreshSpeedHandler.sendMessage(msg);
}
}
}
}, 40,1000);
}
/** 定时刷新码流信息 */
public void stopRefreshDataSpeedInfoThread(){
if(_dataTimer != null){
_dataTimer.cancel();
_dataTimer = null;
}
}
@SuppressLint("HandlerLeak")
Handler refreshSpeedHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg != null){
if(msg.getData().containsKey("dataStr")){
String dataStr = msg.getData().getString("dataStr");
if(m_dataFlowView!=null)
m_dataFlowView.setText(dataStr);
}
}
}
};
private PopupWindow _pWindow;
/**创建PopupWindow对话框*/
@SuppressLint("InflateParams")
private void showPopwindow() {
LayoutInflater inflater = (LayoutInflater) getSystemService(NewMsgDetail.LAYOUT_INFLATER_SERVICE);
final View vPopupWindow=inflater.inflate(R.layout.realplayer_stream_pop, null, false);
_pWindow= new PopupWindow(this);
_pWindow.setContentView(vPopupWindow);
_pWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
_pWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
vPopupWindow.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
_pWindow.setFocusable(true);
_pWindow.setOutsideTouchable(true);
/*设置PopupWindow显示位置*/
//_pWindow.showAtLocation(_streamSet, Gravity.RIGHT, 0, 120);
int popupWidth = vPopupWindow.getMeasuredWidth();
int popupHeight = vPopupWindow.getMeasuredHeight();
int[] location = new int[2];
if(_isScreen){
_streamSet2.getLocationOnScreen(location);
_pWindow.showAtLocation(_streamSet2, Gravity.NO_GRAVITY, (location[0]+_streamSet2.getWidth()/2)-popupWidth/2,location[1]-popupHeight-10);
}else{
_streamSet.getLocationOnScreen(location);
_pWindow.showAtLocation(_streamSet, Gravity.NO_GRAVITY, (location[0]+_streamSet.getWidth()/2)-popupWidth/2,location[1]-popupHeight-10);
}
vPopupWindow.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View view, int keycode, KeyEvent arg2) {
if(keycode == KeyEvent.KEYCODE_BACK){
_pWindow.dismiss();
}
return true;
}
});
vPopupWindow.findViewById(R.id.stream_high).setOnClickListener(this);
vPopupWindow.findViewById(R.id.stream_center).setOnClickListener(this);
vPopupWindow.findViewById(R.id.stream_fluent).setOnClickListener(this);
}
//初始化窗口打洞
public void glViewCreated(int textureID) {
try {
if(_decoderDebugger == null){
mSurfaceTexture = new SurfaceTexture(textureID);
mSurface = new Surface(mSurfaceTexture);
_decoderDebugger = new DecoderDebugger(mSurface,Fun_RealPlayerOpenGL.this);
mSurfaceTexture.setOnFrameAvailableListener(this);
}
//this.mTextureID = textureID;
if(_paly == 1){
_handler.sendEmptyMessage(1002);
init(yyyyMMdd);//主用户才有回放 目前回放只支持一路
_isBack = true;
_i = 8;
startRefreshDataSpeedInfoThread();
}else{
_handler.sendEmptyMessage(XMSG.P2PConnect);
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
// 新增时间轴
private static int index = -1; //文件位置
int isFileFlag = 0;//同一个文件标识,同一个文件内前后拖动也需要重新打洞
private int backFlag = 0;//第一次切到回放的标识
long t1 = 0;
private void findView() {
//设置时间块数据
scrollView.setTimeData(dirInfoList);
scrollView.setValueChangeListener(new OnValueChangeListener() {
@Override
public void onValueChangeEnd(Calendar mCalendar) {
try {
isScroll = true;
// 判断是否在录像中
if (_isRecording) {
APP.ShowToast(getText(R.string.alertMsg39).toString());
//时间轴定位
return;
}
long current_time = DateUtil.convertString2Date(_result.getText().toString(),"yyyy-MM-dd HH:mm:ss").getTime();
for (int i = 0; i < dirInfoList.size(); i++) {
RecordTimeBean dirInfo = dirInfoList.get(i);
long start = dirInfo.startTime.getTimeInMillis();
long end = dirInfo.endTime.getTimeInMillis();
if (current_time >= start && current_time < end) {
index = i;
isFileFlag = 1;
break;
}
}
// 在同一录像中
if (index == current_position) {
isScroll = false;
if(isFileFlag == 1){
isScroll = true;
}
}
// 不存在
else if (index == -1) {
isPlay = false;
isScroll = false;
}
// 跨录像文件
if(isScroll && isFileFlag == 1){
long t2 = System.currentTimeMillis();
if(t2 != t1 && (t2-t1) < 1000 ){
t1 = t2;
return;
}
t1 = t2;
// 滑动时间轴后,首先停止之前的播放录像
current_position = index;
m_dirInfo = dirInfoList.get(current_position);
startTime = _result.getText().toString();
//startTime = DateUtil.convertDate2String(m_dirInfo.startTime.getTime(),"yyyy-MM-dd HH:mm:ss");
//endTime = DateUtil.convertDate2String(m_dirInfo.endTime.getTime(),"yyyy-MM-dd HH:mm:ss");
LogUtil.d(TAG, m_dirInfo+"|"+startTime+"|"+endTime);
if(isGpu && backFlag == 0){//如果当前是硬解,停止并切换图片默认走软解
backFlag = 1;
_btnGpu.SetImages(R.drawable.gpu_false, R.drawable.gpu_false);
isGpu = false;
}
isUpdateView = true;
stopPause();
ViESurfaceRenderer._flag = 0;
_i = 0;
isFileFlag = 0;
_paly = 1;
_handler.sendEmptyMessage(1002);
}
} catch (Exception e) {
}
}
@Override
public void onValueChange(float value) {
_result.setText(scrollView.getTime());
// 判断是否在录像中
if (_isRecording) {
APP.ShowToast(getText(R.string.alertMsg39).toString());
return;
}
// 判断视频是否在加载中
if(_dlgWait != null && _dlgWait.isShowing()){
//APP.ShowToast(getText(R.string.alertMsg1).toString());
return;
}
}
});
//设置当前时间
Date date1 = m_dirInfo.startTime.getTime();
Calendar startTime = Calendar.getInstance();
startTime.setTime(date1);
if(startTime.get(Calendar.HOUR_OF_DAY) == 0){
scrollView.flag = 1;
}
scrollView.postInvalidate();
}
//切换在实时视频
private int realFlag = 0;//滑动到当天(改成当前时间 跳转到时间视频)23.59.59时标识
public void startRealPlayer(){
try {
if(realFlag == 0 && isPlayBack){
realFlag = 1;
_backFlag = 0;
isUpdateView = true;
if(isPlayBack){
isPlayBack = false;
SDK.PlaybackCtrl(SDK._sessionIdContext, 0, "", startTime, endTime, channelNo, 2);
LogUtil.i(TAG, "切换到时实视频...PlaybackCtrl()...contextId="+SDK._sessionIdContext);
}
SDK.P2PClose(SDK._sessionIdContext);
SDK.RemoveChannelPlayContext(SDK.GetChannelIDByContext(SDK._sessionIdContext));
SDK._sessionIdContext = 0;
stopPause();
_i = 8;
_paly = 0;
//如果是前一天的回放 返回 实时需要查询一下当天的录像
String currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
yyyyMMdd = currentDate;
dirInfoList.clear();
SDK.endFlag = 0;
_handler.sendEmptyMessage(XMSG.P2PConnect);
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
//加载前一天数据 大于当天时间返回
private boolean isUpdateView = true;//是否更新时间轴
public void getBeforeDayList(String day){
//如果查询上一天数据 则要关闭实时时间轴刷新 此时应该定位在前一天中
if(!day.equals(yyyyMMdd)){
_backFlag = 0;
isUpdateView = false;
LogUtil.i(TAG,"startTime== getBeforeDayList yyyymmdd="+yyyyMMdd+" day="+day);
yyyyMMdd = day;
dirInfoList.clear();
_handler.sendEmptyMessage(XMSG.SDCARD_VEDIO_LIST);
}else{
scrollView._isLoad = 0;
}
}
//全屏btn
private void orientation(){
Configuration cfg = getResources().getConfiguration();
if(cfg.orientation == 1){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}else if(cfg.orientation == 2){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
}
@SuppressWarnings("static-access")
public void isScreenChange() {
Configuration mConfiguration = this.getResources().getConfiguration(); //获取设置的配置信息
int ori = mConfiguration.orientation ; //获取屏幕方向
if(ori == mConfiguration.ORIENTATION_LANDSCAPE){//横屏
m_dataFlowView.setVisibility(View.GONE);
_hreadframeLayout.setVisibility(View.GONE);
_isScreen = true;
}else if(ori == mConfiguration.ORIENTATION_PORTRAIT){//竖屏
_hreadframeLayout.setVisibility(View.VISIBLE);
m_dataFlowView.setVisibility(View.VISIBLE);
footer.setVisibility(View.GONE);
_isScreen = false;
//设置取消全屏
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
pixels = getSize();
layout();
isScreenChange();
}
private void layout(){
if(pixels[0] > pixels[1]){
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
params.height = pixels[1];
params.width = pixels[0];
framelayout.setLayoutParams(params);
renderer.scaleBase = 0.4f;
if(Constants.deviceType == -1 && renderer._is180Open != 1){
renderer._is180Open = 1;
renderer.changeMatrix();
}
}else{
params.height = pixels[1]/2 - 100;
params.width = pixels[0];
framelayout.setLayoutParams(params);
if(Constants.deviceType == -1){//180全景摄像机
renderer.scaleBase = 0.3f;
if(renderer._is180Open != 1){
renderer._is180Open = 1;
renderer.changeMatrix();
}
}else{
renderer.scaleBase = 0.13f;
}
}
}
private int screenCount = 0; //截图失败总次数
private int i_flag = 0;//I帧标志位
//硬解时截图
public void h264DecoderSnapImg(final byte[] data,final int len){
try {
if(_snapImg){
screenCount++;
if(screenCount < 10){
if(m_imageData == null) m_imageData = new byte[MAX_IMG_BUFFER_SIZE];
m_imageBitmap = BitmapUtils.getScreenBitmap(data, m_imageData, len,SDK._width,SDK._height,SDK._sessionIdContext);
if(m_imageBitmap != null){
long fileLong = snapPic(m_imageBitmap, _fileName);
if(fileLong >= 51200){
_snapImg = false;
screenCount=0;
m_imageBitmap = null;
_cut.setClickable(true);
}
}
}else{
_snapImg = false;
screenCount=0;
_handler.sendEmptyMessage(100);
_cut.setClickable(true);
}
}
} catch (Exception e) {
}
}
public void setBitmap() {
if(isStop){
glView.requestRender();
}
}
//软解码方法
public void h264Decoder(byte[] data,int len,int isIFrame){
try {
if(_decoderDebugger.canDecode){//硬解
if(i_flag == 0 && isIFrame == 1){
i_flag = 1;
closeWait();
}
if(i_flag == 1){//硬解第一帧保证I帧
//截图
if(_snapImg && isIFrame == 1){
h264DecoderSnapImg(data, len);
}
// if(Fun_Cloud.devType == 1 && SDK._manufactorType == 0){//IPC,智诺设备 去头
// int exHead = (int)data[22];
// if(exHead < 0) return;
// int realHead = 24 + exHead;
// int realLen = len - realHead - 8;
// byte[] newbuf = new byte[realLen];
// System.arraycopy(data, realHead, newbuf, 0, realLen);
// _decoderDebugger.decoder(newbuf, realLen);
// }else{ //模拟、海康设备不用去头
if(_decoderDebugger.decoder(data, len) == -1) i_flag = 0;
// }
glView.requestRender();
}
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
public boolean isStop = true;//stop 标志位
public void stop(){
if(isStop){
try {
isGpu = false;//置成软解
isStop = false;
_paly = 0;
index = -1;//回放文件位置
backFlag = 0;
if (_isRecording) {//如果正在录像关闭录像 _decoderQueue != null && _decoderQueue.
stopRecordingVideo();
}
if(_sQueue != null){//音频队列
_sQueue.closeAudio();
_sQueue = null;
}
if(_decoderDebugger != null){
if(_decoderDebugger.isCanDecode()) _decoderDebugger.close();
_decoderDebugger = null;
}
if(_decoderQueue != null){
_decoderQueue.Stop();
_decoderQueue = null;
}
//如果打开了对讲 就关闭
if(_isTalking){
stopTalk();
}
stopRefreshDataSpeedInfoThread();
SDK.isInitDecoder = false;
if(isPlay){
isPlay = false;
LogUtil.i("MNetSDK2","...stop()...MapSize = "+SDK._ChannelPlayContext.size());
for (Map.Entry<String, Object> entry : SDK._ChannelPlayContext.entrySet()) {
String strValue = entry.getValue().toString();
long contextId = FileUtil.ConvertStringToLong(strValue, -1);
LogUtil.i(TAG, "...stop()...P2PCloseChannel sessionId:"+contextId+" devSid:"+devSid);
if(isPlayBack){
isPlayBack = false;
SDK.PlaybackCtrl(contextId, 0, "", startTime, endTime, channelNo, 2);
LogUtil.i(TAG, "stopConnent()...PlaybackCtrl()...contextId="+contextId);
}else{
SDK.P2PCloseChannel(contextId, channelNo,_stream);
}
SDK.P2PClose(contextId);
LogUtil.i(TAG, "...stop()...P2PClose sessionId:"+contextId+" lConnectID="+entry.getKey());
}
SDK._sessionIdContext = 0;
SDK._ChannelPlayContext.clear();
Log.i("MNetSDK2","...stop()...mapsize22="+SDK._ChannelPlayContext.size());
//NVR、子用户、踢出账号、点击消息通知时关闭不用刷新封面
if(isNvr != 1 && isowner == 1 && SDK._isLogout && !Constants._isOnclickOpened) refreshCover();
}
finish();
System.gc();
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
}
//刷新封面(主用户才可以)
private void refreshCover(){
String json = SDK.getJson(devSid, channelNo);
SDK.SendJsonPck(0, json);
}
long[] _sessionId = new long[1];
private int p2p_Count= 0;//P2P连接失败次数标识
private int videoWindowIndex = 1;//窗口ID
private int _type = 0;//判断是否重连 收到-5000时用
//type 0-初始化要开 1-断线打开(现在对讲要求同时打开此type没用了)
public synchronized void doPlay(int type){
try{
_type = type;
SDK.DataSourceDeviceType(Fun_Cloud.devType);
LogUtil.d(TAG, "SDK.P2PConnect start.....SDK._connectId="+SDK._connectId+" SDK._connectId="+SDK._connectId);
long t1 = System.currentTimeMillis();
int nRet = SDK.connectChannelP2P_device(devSid,videoWindowIndex -1,connectChannelP2PHandler);
_handler.sendEmptyMessageDelayed(XMSG.PLAY_P2PConnect,12000);//12秒收打洞不成功,返回网络超时
long t2 = System.currentTimeMillis();
LogUtil.d(TAG, "SDK.P2PConnect 实时 return= "+nRet+" time= "+(t2-t1)+" devSid = "+devSid +" devName = "+devName +" channelNo = "+channelNo);
if(nRet == 0){
//获取onstata 里面的状度 然后创建通道
stopTimer();
}else if(nRet == SDK.GW_ERRCODE_DEV_UNSUPORT || nRet == SDK.GW_ERRCODE_UPGRADE_PROGRAM){//-1997、-1998直接退出
errorP2PConnect(nRet);
}else{
//连接3次不成功关闭
p2p_Count ++;
if(p2p_Count == 3){
errorP2PConnect(nRet);
return;
}
}
}catch(Exception e){
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
public long talkConnectID = 0;
//打洞返回值的消息处理
@SuppressLint("HandlerLeak")
private Handler connectChannelP2PHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
try {
Bundle bdData = msg.getData();
// 创建通道
long lContext = bdData.getLong("Context");
int nStatus = bdData.getInt("Status");
long lConnectID = bdData.getLong("connectID");
boolean isTalking = bdData.getBoolean("isTalking");
if(isTalking){//打开对讲
if(nStatus == 0){
SDK._sessionIdContextTalk = lContext;
//SDK.TalkCtrl(SDK._sessionIdContextTalk, 1);
_talkPlayer.Start();
//_sQueue.Start();//打开声音
closeWait();
_btnTalk.setClickable(true);
talkConnectID = lConnectID;
Log.i(TAG,"对讲lConnectID="+lConnectID);
//对讲的connectID不用添加进来
//SDK._ChannelPlayContext.remove("" + lConnectID);
}
}else{
if (nStatus == 0){// p2pConnect成功
if(_handler != null) _handler.removeMessages(XMSG.PLAY_P2PConnect);//实时打洞成功移除此消息
SDK._isP2pSuccess = false;
LogUtil.i(TAG,"SDK.P2PCreateChannel start.....");
SDK._sessionIdContext = lContext;
if(!isGpu) SDK.SetDecoderModel(1,SDK._sessionIdContext);
_playId = SDK.P2PCreateChannel(SDK._sessionIdContext, channelNo,_stream,20,10000, 352,288);
LogUtil.i(TAG,"SDK.P2PCreateChannel 实时return="+_playId+" time="+1+" _sessionIdContext="+SDK._sessionIdContext+" SDK._connectId="+SDK._connectId);
if(_playId >= 0){
if(_type == 0){
isPlay = true;
isPlayBack = false;
if(_sQueue == null) _sQueue = new AudioQueue();
//模拟目前不要发消息
if(Fun_Cloud.devType == 1)
_handler.sendEmptyMessageDelayed(XMSG.ON_PLAY,12000);//12秒收不到数据 提示打开视频失败!
if(_decoderDebugger != null) _decoderDebugger.flag = 0;
if(!isGpu){
closeWait();
}else{
_decoderDebugger.canDecode = true;
}
if(_decoderQueue == null){
_decoderQueue = new DecoderQueueOpengl(renderer);
_decoderQueue.Start();
}
_flag5000 = 0;//成功之后标志置0
//打洞成功之后开启对讲(NVR暂不支持)
if(isNvr == 1){
_sQueue.Start();//NVR默认打开伴音
_bSound = true;//改成一打播放伴音,按住对讲时 只采集不播放对端传过来的声音,松开时播放声音
_audio.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
_audio2.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
devAudioInput = 1;//暂时NVR手动设置成1
}else{
if(devAudioInput == 1 && devAudioOutput == 1){
//子用户判断对讲权限
if ((isowner == 1) || (isowner == 0 && _isRightsTalk)){
_sQueue.Start();//打开伴音
_bSound = true;
_isTalking = true;
_handler.sendEmptyMessage(XMSG.P2PConnect);//对讲打洞
_audio.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
_audio2.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
}
}
}
}else if(_type == 1){
closeWait();
}
realFlag = 0;
startRefreshDataSpeedInfoThread();
}else{//创建通道失败不用重试直接退出
Message err_msg = new Message();
err_msg.what = XMSG.CREATECHANLL;
err_msg.obj = _playId;
_handler.sendMessage(err_msg);
}
} else {
LogUtil.d(TAG, "收到 -5000 nStatus:"+nStatus);
//收到 -5000 要关闭连接
if (nStatus == -5000) {
closeNewSurface(SDK._sessionIdContext,-5000);
}else if(nStatus == -4996 || nStatus == -4997){
APP.ShowToast(SDK.GetErrorStr(nStatus));
stop();
}
}
}
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
};
//type 0-初始化要开 1-断线打开 录像回放
public synchronized void doBackPlay(String startTime, String endTime){
try{
stopConnentBack();
SDK.DataSourceDeviceType(Fun_Cloud.devType);
int nRet = SDK.connectChannelP2P_device(devSid,videoWindowIndex -1,alarmConnectChannelP2PHandler);
LogUtil.i(TAG, "SDK.P2PConnect [doBackPlay] return= "+nRet+" devSid = "+devSid +" devName = "+devName +" channelNo = "+channelNo+" SDK._connectId="+SDK._connectId);
if(nRet == 0){
}else{//连接失败消息处理
//连接3次不成功关闭
p2p_Count ++;
if(p2p_Count == 3){
errorP2PConnect(nRet);
}else{
_handler.sendEmptyMessage(1002);
}
}
}catch(Exception e){
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
//远程回放打洞返回值的消息处理
@SuppressLint("HandlerLeak")
private Handler alarmConnectChannelP2PHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
try {
Bundle bdData = msg.getData();
// 创建通道
long lContext = bdData.getLong("Context");
int nStatus = bdData.getInt("Status");
if (nStatus == 0){// p2pConnect成功
//检查有没有多的连接
checkConnent();
SDK._sessionIdContext = lContext;
if(!isGpu){
SDK.SetDecoderModel(1,SDK._sessionIdContext);
}else{
SDK.SetDecoderModel(0,SDK._sessionIdContext);
_decoderDebugger.canDecode = true;
}
_playId = SDK.PlaybackCtrl(SDK._sessionIdContext, 0, "", startTime, endTime, channelNo, 1);
LogUtil.i(TAG," SDK [PlaybackCtrl] return="+_playId+" sessionID="+SDK._sessionIdContext+" SDK._connectId="+SDK._connectId);
if(_playId >= 0){
isPlay = true;
isPlayBack = true;
if(_decoderQueue == null){
_decoderQueue = new DecoderQueueOpengl(renderer);
_decoderQueue.Start();
}
if(_sQueue == null) _sQueue = new AudioQueue();
_sQueue.Start();//默认打开伴音
_bSound = true;
_audio.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
closeWait();
}else{//创建通道失败不用重试直接退出
Message msg1 = new Message();
msg1.what = XMSG.CREATECHANLL;
msg1.obj = _playId;
_handler.sendMessage(msg1);
}
} else {
LogUtil.d(TAG, "[PlaybackCtrl]收到 -5000 nStatus:"+nStatus);
//收到 -5000 要关闭连接
if (nStatus == -5000) {
closeNewSurface(SDK._sessionIdContext,-5000);
}else if(nStatus == -4996 || nStatus == -4997){
APP.ShowToast(SDK.GetErrorStr(nStatus));
stop();
}
}
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
};
private void errorP2PConnect(int nRet){
try {
if(_decoderQueue != null){
_decoderQueue.Stop();
_decoderQueue = null;
}
SDK.SendJsonPck(1,SDK.getJsonString(devSid));
closeWait();
Message msg = new Message();
msg.what = XMSG.SMS_P2PConnect;
msg.obj = nRet;
if(_handler != null) _handler.sendMessage(msg);
SDK._sessionIdContext = 0;
_runFlag = false;
p2p_Count = 0;
this.finish();
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
public void closeWait(){
if(_dlgWait != null && _dlgWait.isShowing()) _dlgWait.dismiss();
}
public void showGpu(){
//判断一下 如果支持硬解把图片换一下
if(_decoderDebugger.isCanDecode()){
_handler.sendEmptyMessage(XMSG.PLAY_GPU_OK);
}else{
_handler.sendEmptyMessage(XMSG.PLAY_GPU);
}
}
//网络断开打开提示框
public void openWait(){
_dlgWait.show();
_dlgWait.UpdateText(getText(R.string.Video_NetWork_reload).toString());
}
public java.util.Timer _timer = null;
public static boolean _runFlag = true; //判断是否打洞
//定时器 管理 P2PConnect 连接
public void startTimer(final int type) {
try {
if (_timer != null) {
_timer.cancel();
_timer = null;
}
if(_timer == null){
_timer = new java.util.Timer();
}
_timer.schedule(new TimerTask() {
@Override
public void run() {
if(_runFlag){
//每次打开定时器之前清空消息队列
if(_handler != null) _handler.removeMessages(XMSG.ON_PLAY);
doPlay(type);
}
}
}, 0, 5000);
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
void stopTimer() {
try {
if (_timer != null) {
_timer.cancel();
_timer = null;
_runFlag = false;
}
} catch (Exception e) {
}
}
//sdk 收到异常情况关闭 1设备忙 -5000连接异常
public void closeNewSurface(long sessionID,int error){
try {
if(_handler != null){
Message msg = new Message();
msg.what = error;
msg.obj = sessionID;
_handler.sendMessage(msg);
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
int _backFlag = 0;
//获取sdcard录像回放数据
public void getVideoBlack(){
try {
if((isowner == 1 || _isRightsRecord) && !isPlayBack){
SharedPreferences preferences = getSharedPreferences(Login.SAVEFILE, MODE_PRIVATE);
int ret = preferences.getInt(devSid, 0);
//NVR不需要查询存储卡 直接查询
if(isNvr == 1) ret = 1;
//0.未配置 1.true 2.false
if(ret == 0){
// 获取能力级,支持插卡,才查询存储卡容量
String getC0 = "{\"id\":201,\"method\":\"magicBox.getProductDefinition\",\"params\":{\"name\":\"IsLocalStore\"}}";
SDK.ExtCommandReq(1, devSid, getC0.getBytes(), getC0.getBytes().length);
}else if(ret == 1){
if(_backFlag == 0){
_backFlag = 1;
dirInfoList.clear();
init(yyyyMMdd);//主用户才有回放 目前回放只支持一路
_isBack = true;
}
}else if(ret == 2){//没有SD卡
_handler.sendEmptyMessage(1003);
}
}
} catch (Exception e) {
System.out.println(11);
}
}
//0.未配置 1.true 2.false
@SuppressLint("UseValueOf")
public void setIsLocalStore(String str){
try {
//如果当前设备不支持标准 要把缓存里面的stream 值改掉
if(str != null && !str.equals("")){
SharedPreferences preferences = getSharedPreferences(Login.SAVEFILE, MODE_PRIVATE);
boolean localStore = JSON.parseObject(str).getBoolean("definition");
Editor editor = preferences.edit();
if (localStore == true) {
editor.putInt(devSid, 1);
init(yyyyMMdd);//主用户才有回放 目前回放只支持一路
_isBack = true;
}else{
editor.putInt(devSid, 2);
_handler.sendEmptyMessage(1003);
}
editor.commit();
}
} catch (Exception e) {
}
}
//更新时间轴 实时和回放都要跳
int _i = 0;//10秒/次
public void updateTimeView(int yy,int ym,int dd,int hh,int mm,int ss){
if(isUpdateView){
_i ++;
if(_i == 10){
calendar.set(Calendar.DAY_OF_MONTH,dd);
calendar.set(Calendar.HOUR_OF_DAY, hh);
calendar.set(Calendar.MINUTE, mm);
calendar.set(Calendar.SECOND, ss);
_handler.sendEmptyMessage(XMSG.UPDATE_VEDIO_TIME);
_i = 0;
}
}
}
//截图功能
@SuppressLint("SimpleDateFormat")
public long snapPic(Bitmap bitmap,String fileName) {
File file = null;
if(fileName.indexOf("records") != -1){//录像30%压缩
BitmapUtils.saveBitmapQuality(bitmap, fileName,30);
file = new File(fileName);
if(file.isFile() && file.exists()) return 51200;
}else{
BitmapUtils.saveBitmap(bitmap, fileName);
file = new File(fileName);
if(file.isFile() && file.exists() && file.length() >= 51200){// && file.length() >= 204800 夜间抓图会小于200K
_handler.sendEmptyMessage(XMSG.PLAY_SNAP);
}
}
return file.length();
}
@SuppressLint("SimpleDateFormat")
public String getFileName(){
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String strDate = sdf.format(date);
String month = (calendar.get(Calendar.MONTH)+1) < 10 ?"0"+(calendar.get(Calendar.MONTH)+1):""+(calendar.get(Calendar.MONTH)+1);
String path = Constants.ImagePath +File.separator+ calendar.get(Calendar.YEAR)+ month + File.separator;
File dir = new File(path);
if(!dir.exists()) dir.mkdirs();
String fileName = path + strDate + devName + ".bmp";
fileName = fileName.replace(" ", "");
fileName = fileName.replace("-", "");
fileName = fileName.replace(":", "");
return fileName;
}
public void screenshot(Bitmap bitmap){
long fileLong = snapPic(bitmap, _fileName);
if(fileLong >= 51200){// || NewMain.devType == 4
_snapImg = false;
if(_isScreen)
_cut2.setClickable(true);
else
_cut.setClickable(true);
}
}
public String _fileName = "";//截图文件名
public String _recordfileName = "";//录像文件名
public boolean _snapImg = false;//软解截图
private boolean _isRecording = false;//录像
public boolean _isTalking = false;//对讲
public boolean _bSound = false;//伴音
private int _talkFlag = 0;//是否对讲
@Override
public void onClick(View v) {
try {
switch (v.getId()) {
//伴音(关闭伴音时不用关对讲连接)
case R.id.btn_play_audio:
if(devAudioInput == 0){
APP.ShowToast(getText(R.string.Video_realPlayer_tip).toString());
return;
}
if(_bSound){//停止伴音
_bSound = false;
_audio2.SetImages(R.drawable.real_audio2, R.drawable.real_audio2);
_audio.SetImages(R.drawable.real_audio2, R.drawable.real_audio2);
}else{
//模拟打开音频队列,IPC目前没有音频
_audio2.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
_audio.SetImages(R.drawable.real_audio1, R.drawable.real_audio1);
_bSound = true;
}
break;
case R.id.btn_play_cut:
//截图
if(_isScreen)
_cut2.setClickable(true);
else
_cut.setClickable(false);
_fileName = getFileName();
_snapImg = true;
break;
case R.id.btn_play_video:
//如果H265录像暂时不支持
if(ViESurfaceRenderer._isH265){
APP.ShowToast(getText(R.string.alertMsg56).toString());
return;
}
// 如果正在录像,则停止
if (_isRecording && isPlay) {
APP.ShowToast(getText(R.string.Video_record_end).toString());
stopRecordingVideo();
} else { // 开始录像
if(_isScreen)
_video2.SetImages(R.drawable.control_icon_small_video_p, R.drawable.control_icon_small_video_p);
else
_video.SetImages(R.drawable.control_icon_small_video_p, R.drawable.control_icon_small_video_p);
String strDate = DateUtil.getCurrentStringDate(DateUtil.DEFAULT_DATE_TIME_FORMAT);
_recordfileName = Constants.RecordPath + strDate + devName;
File dir = new File(Constants.RecordPath.substring(0,Constants.RecordPath.length()-1));
if(!dir.exists()) dir.mkdirs();
if((int)SdCardUtils.getSurplusStorageSize(Constants.RecordPath) > 20){
_fileName = _recordfileName + ".bmp";
_snapImg = true;
SDK.PlayStartSnap(SDK._sessionIdContext);
_dlgWait.show();
_dlgWait.UpdateText(getText(R.string.set_pwd).toString());
startNotify(XMSG.GetNotify);
}else{
if(_isScreen)
_video2.SetImages(R.drawable.control_icon_small_video_n, R.drawable.control_icon_small_video_n);
else
_video.SetImages(R.drawable.control_icon_small_video_n, R.drawable.control_icon_small_video_n);
APP.ShowToast(getText(R.string.Video_Storage_space_err).toString());
}
}
break;
case R.id.btn_play_gpu://软硬解切换
if(isGpu){
SDK.SetDecoderModel(1,SDK._sessionIdContext);
_btnGpu.setClickable(false);
i_flag = -1;
isGpu = false;
_decoderDebugger.canDecode = false;
if(_decoderQueue == null){
_decoderQueue = new DecoderQueueOpengl(renderer);
_decoderQueue.Start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
_btnGpu.SetImages(R.drawable.gpu_false, R.drawable.gpu_false);
i_flag = 1;
APP.ShowToast(getText(R.string.Video_stop_gpu).toString());
_btnGpu.setClickable(true);
}else{
//180暂时不支持硬解
if(Constants.deviceType == -1 || ViESurfaceRenderer._isH265){
APP.ShowToast(getText(R.string.Video_err_gpu).toString());
break;
}
SDK.SetDecoderModel(0,SDK._sessionIdContext);
_btnGpu.setClickable(false);
i_flag = 0;
isGpu = true;
if(_decoderDebugger != null){
_decoderDebugger.canDecode = true;
showGpu();
}
if(_decoderQueue != null){
_decoderQueue.Stop();
_decoderQueue = null;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
APP.ShowToast(getText(R.string.Video_start_gpu).toString());
_btnGpu.setClickable(true);
}
break;
case R.id.btn_play_talk://语音对讲
if(devAudioInput == 1 && devAudioOutput == 1){
if(_bSound){
_bSound = false;
_audio.SetImages(R.drawable.real_audio2, R.drawable.real_audio2);
_sQueue.Stop();
}
if(_isTalking){
stopTalk();
//停止对讲后要开启伴音
onClick(_audio);
}else{
//开启对讲线程
_isTalking = true;
_btnTalk.setClickable(false);
_btnTalk.SetImages(R.drawable.talk2, R.drawable.talk2);
_dlgWait.show();
_dlgWait.UpdateText(getText(R.string.Video_P2PConnect).toString());
_handler.sendEmptyMessage(XMSG.P2PConnect);
}
}else{
APP.ShowToast(getText(R.string.Video_realPlayer_tip).toString());
}
break;
case R.id.stream_setting:
//录像回放的时候 不支持码流切换
if(isPlayBack) break;
if (_isRecording){
APP.ShowToast(getText(R.string.alertMsg39).toString());
break;
}
showPopwindow();
break;
case R.id.stream_high://高清 //0:主码流(高清),1:流畅(默认值辅码流) 2:标清
_pWindow.dismiss();
if(_stream == 0) return;
if(isPlay){
isPlay = false;
SDK.P2PCloseChannel(SDK._sessionIdContext, channelNo,_stream);
_handler.removeMessages(XMSG.ON_PLAY);
}else{
return;
}
_decoderQueue.clearQueue();
_streamSet2.setText(getText(R.string.Video_pop_high).toString());
_streamSet.setText(getText(R.string.Video_pop_high).toString());
_editor = _preferences.edit();
_editor.putInt("streamCode", 0);
_editor.commit();
_stream = 0;
changeStream();
break;
case R.id.stream_center://标准 ==0?0:1
_pWindow.dismiss();
if(_stream == 2) return;
if(_StreamDefinition == 1){
APP.ShowToast(getText(R.string.Video_stream_center_error).toString());
return;
}
if(isPlay){
isPlay = false;
SDK.P2PCloseChannel(SDK._sessionIdContext, channelNo,_stream);
_handler.removeMessages(XMSG.ON_PLAY);
}else{
return;
}
_decoderQueue.clearQueue();
_streamSet2.setText(getText(R.string.Video_pop_center).toString());
_streamSet.setText(getText(R.string.Video_pop_center).toString());
_editor = _preferences.edit();
_editor.putInt("streamCode", 2);
_editor.commit();
_stream = 2;
changeStream();
break;
case R.id.stream_fluent://流畅
_pWindow.dismiss();
if(_stream == 1) return;
if(isPlay){
isPlay = false;
SDK.P2PCloseChannel(SDK._sessionIdContext, channelNo,_stream);
_handler.removeMessages(XMSG.ON_PLAY);
}else{
return;
}
_decoderQueue.clearQueue();
_streamSet2.setText(getText(R.string.Video_pop_low).toString());
_streamSet.setText(getText(R.string.Video_pop_low).toString());
_editor = _preferences.edit();
_editor.putInt("streamCode", 1);
_editor.commit();
_stream = 1;
changeStream();
break;
case R.id.btn_setting_video://设置
startTime = _result.getText().toString();
stopRefreshDataSpeedInfoThread();
Intent intent = new Intent(this, SETMainActivity.class);
intent.putExtra("device", (Serializable) device);
startActivity(intent);
break;
//全屏处理
case R.id.btn_play_audio2:
onClick(_audio);
break;
case R.id.btn_play_cut2:
onClick(_cut);
break;
case R.id.btn_play_video2:
onClick(_video);
break;
case R.id.stream_setting2:
onClick(_streamSet);
break;
case R.id.realplayer_flow_fullscreen:
orientation();
break;
default:
break;
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
public void changeStream(){
try {
if(!isGpu) SDK.SetDecoderModel(1,SDK._sessionIdContext);
_playId = SDK.P2PCreateChannel(SDK._sessionIdContext, channelNo,_stream,20,10000, 352,288);
LogUtil.i(TAG,"SDK.P2PCreateChannel return="+_playId+" time="+1+" sessionID="+SDK._sessionIdContext+" _stream:"+_stream);
if(_playId >= 0){
if(_type == 0){
isPlay = true;
isPlayBack = false;
//模拟目前不要发消息
if(Fun_Cloud.devType ==1)
_handler.sendEmptyMessageDelayed(XMSG.ON_PLAY,12000);//12秒收不到数据 提示打开视频失败!
if(!isGpu){
closeWait();
}else{
_decoderDebugger.canDecode = true;
}
}else if(_type == 1){
closeWait();
}
realFlag = 0;
}else{//创建通道失败不用重试直接退出
Message err_msg = new Message();
err_msg.what = XMSG.CREATECHANLL;
err_msg.obj = _playId;
_handler.sendMessage(err_msg);
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
//停止录像
private void stopRecordingVideo(){
try {
if(_isScreen)
_video2.SetImages(R.drawable.control_icon_small_video_n, R.drawable.control_icon_small_video_n);
else
_video.SetImages(R.drawable.control_icon_small_video_n, R.drawable.control_icon_small_video_n);
_isRecording = false;
SDK.SetFinishVideo(_recordfileName + ".mp4",SDK._sessionIdContext);
} catch (Exception e) {
}
}
//停止对讲
private void stopTalk(){
try {
_isTalking = false;
if(_sQueue != null) _sQueue.Stop();//停止伴音
if(_talkPlayer != null) _talkPlayer.Stop();//停止发送音频线程
//SDK.TalkCtrl(SDK._sessionIdContextTalk, 2);
SDK.P2PClose(SDK._sessionIdContextTalk);
SDK.RemoveChannelPlayContext(talkConnectID);
LogUtil.i(TAG, "stopTalk() remove connectid end..._sessionIdContextTalk="+SDK._sessionIdContextTalk+" == "+talkConnectID);
SDK._sessionIdContextTalk = 0;
_btnTalk.setClickable(true);
} catch (Exception e) {
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:// 处理返回按键
//录像回放过程中,按了返回键 ,则返回实时播放,再按则退出 实时。
if(isPlayBack){
realFlag = 0;
backFlag = 0;
if(isGpu){//如果当前是硬解,停止并切换图片默认走软解
SDK.SetDecoderModel(1,SDK._sessionIdContext);
_btnGpu.SetImages(R.drawable.gpu_false, R.drawable.gpu_false);
isGpu = false;
}
startRealPlayer();
}else{
stop();
}
break;
case KeyEvent.KEYCODE_VOLUME_UP:// 音量增大
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,currentVolume + 1, 1);
break;
case KeyEvent.KEYCODE_VOLUME_DOWN:// 音量减小
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,currentVolume - 1, 1);
break;
default:
break;
}
return true;
}
public void stopPause(){
try {
if (_isRecording) {//如果正在录像关闭录像 _decoderQueue != null && _decoderQueue.
stopRecordingVideo();
}
if(_sQueue != null){
_sQueue.closeAudio();
_sQueue = null;
}
if(_decoderQueue != null){
_decoderQueue.Stop();
_decoderQueue = null;
}
//如果打开了对讲 就关闭
if(_isTalking){
stopTalk();
}
//回放支持硬解
/*if(_decoderDebugger != null && _paly == 0){
_decoderDebugger.release();
//_decoderDebugger = null;
}*/
SDK.isInitDecoder = false;
//关闭实时视频
if(_paly == 0 && isPlay){
//LogUtil.i(TAG, "start...stopPause()..关闭实时视频._sessionIdContext="+SDK._sessionIdContext+" mapsize="+SDK._ChannelPlayContext.size());
SDK.P2PCloseChannel(SDK._sessionIdContext, channelNo,_stream);
SDK.P2PClose(SDK._sessionIdContext);
SDK.RemoveChannelPlayContext(SDK.GetChannelIDByContext(SDK._sessionIdContext));
SDK._sessionIdContext = 0;
isPlay = false;
}else{
//stopConnent();
}
ViESurfaceRenderer.instance.clearData();
} catch (Exception e) {
LogUtil.e(TAG, "stopPause.."+ExceptionsOperator.getExceptionInfo(e));
}
}
//关闭回放连接
public void stopBackConnent(){
try {
SDK.PlaybackCtrl(SDK._sessionIdContext, 0, "", startTime, endTime, channelNo, 2);
LogUtil.i(TAG, "切换到时实视频...PlaybackCtrl()...contextId="+SDK._sessionIdContext);
SDK.P2PClose(SDK._sessionIdContext);
SDK.RemoveChannelPlayContext(SDK.GetChannelIDByContext(SDK._sessionIdContext));
SDK._sessionIdContext = 0;
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
public void stopConnentBack(){
try {
if(SDK._sessionIdContext != 0 && _paly == 1){
SDK.PlaybackCtrl(SDK._sessionIdContext, 0, "", startTime, endTime, channelNo, 2);
SDK._sessionIdContext = 0;
Log.i(TAG, "stopConnent()...PlaybackCtrl()...contextId="+SDK._sessionIdContext);
}
SDK.CloseP2PConnectBack();
} catch (Exception e) {
LogUtil.e(TAG,ExceptionsOperator.getExceptionInfo(e));
}
}
public void checkConnent(){
try {
if(SDK._ChannelPlayContext.size() > 1){
for (Map.Entry<String, Object> entry : SDK._ChannelPlayContext.entrySet()) {
String strValue = entry.getValue().toString();
String strKey = entry.getKey();
long contextId = FileUtil.ConvertStringToLong(strValue, -1);
long lConnectID = FileUtil.ConvertStringToLong(strKey, -1);
Log.i("MNetSDK2", ".........checkConnent..._sessionIdContext="+contextId+" lConnectID="+lConnectID);
if (SDK._connectId != lConnectID) {
SDK.PlaybackCtrl(contextId, 0, "", startTime, endTime, channelNo, 2);
int ret = SDK.P2PClose(contextId);
if(ret == 0){
SDK._ChannelPlayContext.remove("" + lConnectID);
}
}
}
}
} catch (Exception e) {
}
}
//添加回放结束处理
public void backClose(){
try {
SDK.PlaybackCtrl(SDK._sessionIdContext, 0, "", startTime, endTime, channelNo, 2);
//找到下一个录像的起始时间
index += 1;
LogUtil.i(TAG,"startTime[下载新的录像start]===index="+index+" size="+dirInfoList.size()+" oldtime= "+startTime);
if(index < dirInfoList.size()){
RecordTimeBean dirInfo = dirInfoList.get(index);
startTime = DateUtil.convertDate2String(dirInfo.startTime.getTime(),"yyyy-MM-dd HH:mm:ss");
SDK.PlaybackCtrl(SDK._sessionIdContext, 0, "", startTime, endTime, channelNo, 1);
LogUtil.i(TAG,"startTime[下载新的录像end]==== newstartTime="+startTime+"----endTime = "+endTime);
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
public void backCloseToRealPlayer(){
if(index == dirInfoList.size()){
LogUtil.i(TAG,"startTime== [跳到实时视频] yyyymmdd="+yyyyMMdd);
//跳到实时视频
startRealPlayer();
}
}
//暂停/恢复
public void playPause(int bPause){
if(bPause == 0){
Fun_RealPlayerOpenGL.this.recreate();
}
if(bPause == 1 && isPlay){
stopPause();
if(isPlayBack){
stopBackConnent();
isPlayBack = false;
}
isResume = true;
}
}
// 参数 延迟时间
// SensorManager.SENSOR_DELAY_FASTEST 0ms
// SensorManager.SENSOR_DELAY_GAME 20ms
// SensorManager.SENSOR_DELAY_UI 60ms
// SensorManager.SENSOR_DELAY_NORMAL 200ms
// Sensor.TYPE_ACCELEROMETER 加速度感应检测 Sensor.TYPE_GYROSCOPE 回转仪感应检测
@Override
protected void onResume() {
super.onResume();
if(isResume){
playPause(0);
isResume = false;
}
// sensorManager.registerListener(this,
// sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
// SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
playPause(1);
// sensorManager.unregisterListener(this);
}
@Override
protected void onStop() {
try {
SDK._flag = 0;
isStop = true;
SDK._isP2pSuccess = false;
closeWait();
stopTimer();
_handler.removeMessages(XMSG.ON_PLAY);
_handler.removeMessages(XMSG.PLAY_P2PConnect);
ViESurfaceRenderer.instance.clearData();
} catch (Exception e) {
}
super.onStop();
}
@Override
protected void onDestroy(){
super.onDestroy();
try {
devSid = "";
instance = null;
m_imageData = null;
ViESurfaceRenderer._nWidth = 0;
ViESurfaceRenderer._isH265 = false;
m_imageBitmap = null;
_decoderDebugger = null;
_handler = null;
_sessionId = null;
_dlgWait = null;
_talkPlayer = null;
mSurface.release();
mSurface = null;
mSurfaceTexture.release();
mSurfaceTexture = null;
glView = null;
renderer.clear();
renderer = null;
SDK._sessionIdContext = 0;
mQrLineView = null;
animation = null;
iv_volume = null;
scrollView = null;
device = null;
videoHandler = null;
baseApp = null;
mPollTask = null;
handler = null;
} catch (Exception e) {
System.out.println("ondestroy");
}
}
private int recordCount = 0;
private int _flag5000 = 0;//收到2次-5000时限制
//2.接受消息
@SuppressLint("HandlerLeak")
class MyHandler extends Handler {
// 子类必须重写此方法,接受数据
@Override
public void handleMessage(Message msg) {
try {
switch (msg.what) {
case XMSG.CREATECHANLL://创建通道失败
closeWait();
APP.ShowToast(SDK.GetErrorStr(_playId));
SDK.P2PCloseChannel(SDK._sessionIdContext, channelNo,_stream);
SDK.P2PClose(SDK._sessionIdContext);
SDK._sessionIdContext = 0;
Fun_RealPlayerOpenGL.this.finish();
break;
case XMSG.SMS_P2PConnect:
int ret = (Integer) msg.obj;
APP.ShowToast(SDK.GetErrorStr(ret));
break;
case XMSG.P2PConnect:
if(!_isTalking){
_dlgWait.show();
_dlgWait.UpdateText(getText(R.string.Video_P2PConnect).toString());
}
startTimer(0);
_runFlag = true;
if(!_isTalking)
_dlgWait.UpdateText(getText(R.string.Video_reopen_stream).toString());
LogUtil.d(TAG, "收到 打洞消息。...");
break;
case 1002://远程回放
_dlgWait.show();
_dlgWait.UpdateText(getText(R.string.Video_P2PConnect).toString());
doBackPlay(startTime, endTime);
break;
case 1003://没有SD卡
_linearTimeLine.setVisibility(View.GONE);
_currentText.setVisibility(View.INVISIBLE);
_result.setVisibility(View.INVISIBLE);
_isBack = false;
break;
case 1004://加载时间轴动画
if(mQrLineView != null){
mQrLineView.setVisibility(View.VISIBLE);
mQrLineView.startAnimation(animation);
}
break;
case -5000:
LogUtil.i(TAG, " 收到 -5000 start...sessionId="+SDK._sessionIdContext);
//如果打开了对讲 就关闭
if(_isTalking){
stopTalk();
}
if(isPlayBack){
stopPause();
doBackPlay(startTime, endTime);
}else{
if(_flag5000 == 0){
_flag5000 = 1;
}else{
System.out.println("test222 ---------------------");
break;
}
SDK.P2PClose(SDK._sessionIdContext);
_backFlag = 0;
if(isPlay){
openWait();
if(_sQueue != null){//音频队列
_sQueue.closeAudio();
_sQueue = null;
}
if(_decoderQueue != null){
_decoderQueue.Stop();
_decoderQueue = null;
}
startTimer(0);
_runFlag = true;
//关闭时间轴动画
if(mQrLineIsShow && mQrLineView != null){
mQrLineView.clearAnimation();
mQrLineView.setVisibility(View.GONE);
}
}
}
LogUtil.i(TAG, " 收到 -5000 end...");
break;
case 0://设备忙(未知状态)
APP.ShowToast(getText(R.string.Video_Device_BUSY).toString());
stop();
break;
case 1://设备忙
long sessionIdContext = (Long) msg.obj;
LogUtil.i(TAG, "设备忙 sessionIdContext = "+sessionIdContext +" SDK._sessionIdContextTalk= "+SDK._sessionIdContextTalk);
String str = getText(R.string.Video_Device_BUSY).toString();
APP.ShowToast(str);
//如果是对讲忙 关闭对讲打开伴单 不关视频
if(_isTalking && sessionIdContext == SDK._sessionIdContextTalk){
onClick(_audio);
}else{
stop();
}
break;
case XMSG.PLAY_SNAP:
APP.ShowToast(getText(R.string.Video_snap_success).toString());
break;
case XMSG.ON_PLAY:
if(!SDK.isInitDecoder && _playId > 0 && isPlay){
APP.ShowToast(getText(R.string.Video_failopen).toString());
LogUtil.d(TAG, "12秒未收到数据调 stop()....");
stop();
}
if(Constants.deviceType == -1 && mQrLineIsShow && mQrLineView != null){
mQrLineView.clearAnimation();
mQrLineView.setVisibility(View.GONE);
}
break;
case XMSG.PLAY_P2PConnect:
if(!SDK._isP2pSuccess){
APP.ShowToast(SDK.GetErrorStr(SDK.GW_ERRCODE_P2P_TIMEOUT));
stop();
LogUtil.i(TAG, "打洞失败,网络超时 -894 stop()....");
}
if(mQrLineIsShow && mQrLineView != null){
mQrLineView.clearAnimation();
mQrLineView.setVisibility(View.GONE);
}
break;
case 100:
APP.ShowToast(getText(R.string.Video_snap_error).toString());//截图失败
File temFile = new File(_fileName);
if(temFile.exists()) temFile.delete();
break;
case XMSG.PLAY_GPU:
isGpu = false;
_btnGpu.SetImages(R.drawable.gpu_false, R.drawable.gpu_false);
APP.ShowToast(getText(R.string.Video_err_gpu).toString());
_btnGpu.setClickable(false);
break;
case XMSG.PLAY_GPU_OK:
isGpu = true;
_btnGpu.SetImages(R.drawable.gpu_true, R.drawable.gpu_true);
break;
case XMSG.GetNotify://定时判断截图成功
recordCount ++;
File efile = new File(_recordfileName + ".bmp");
if(recordCount < 10){
if(efile.exists() && efile.length() >= 5000){
SDK.SetVideoPath(_recordfileName + ".h264",_recordfileName + ".aac",SDK._sessionIdContext);
_isRecording = true;
stopNotify();
closeWait();
recordCount = 0;
}
}else{
recordCount = 0;
if(_isScreen)
_video2.SetImages(R.drawable.control_icon_small_video_n, R.drawable.control_icon_small_video_n);
else
_video.SetImages(R.drawable.control_icon_small_video_n, R.drawable.control_icon_small_video_n);
efile.delete();
stopNotify();
closeWait();
APP.ShowToast(getText(R.string.Video_record_error).toString());
break;
}
if (_bNotify) {
_handler.sendEmptyMessageDelayed(XMSG.GetNotify, 500); //延迟发送
}
break;
case XMSG.PLAY_AUDIO:
recordCount ++;
if(recordCount < 3){
if(AudioQueue._talkAudio != null){
_bSound = true;
stopNotify();
AudioQueue._talkAudio.play();//音频开始
_audio.setClickable(true);
}
}else{
recordCount = 0;
stopNotify();
_bSound = false;
_audio.SetImages(R.drawable.real_audio2, R.drawable.real_audio2);
_audio.setClickable(true);
}
if (_bNotify) {
_handler.sendEmptyMessageDelayed(XMSG.PLAY_AUDIO, 400); //延迟发送
}
break;
case XMSG.SDCARD_VEDIO_LIST://SD卡录像列表sdcard
_dlgWait.show();
_dlgWait.UpdateText(getText(R.string.openning_ReloadData).toString());
//停止回放
if(isPlayBack){
stopPause();
stopBackConnent();
isPlayBack = false;
}
init(yyyyMMdd);
break;
case XMSG.UPDATE_VEDIO_TIME:
_result.setText(DateUtil.convertDate2String(calendar.getTime(),"yyyy-MM-dd HH:mm:ss"));
scrollView.setCalendar(calendar);
break;
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
}
private boolean _bNotify = false;
private void startNotify(int type) {
if (!_bNotify) {
_handler.sendEmptyMessage(type);
_bNotify = true;
}
}
private void stopNotify() {
_bNotify = false;
}
@SuppressLint("HandlerLeak")
public final class VideoBackHandler extends Handler {
public void handleMessage(Message msg) {
try {
switch (msg.what) {
case 1:
Bundle data = msg.getData();
int _result = data.getInt("_result");
JSONArray array = JSONArray.parseArray(data.getString("file_list"));
JSONObject obj = null;
for (Iterator<Object> iter = array.listIterator(); iter
.hasNext();) {
obj = (JSONObject) iter.next();
startTime = obj.getString("start_time");
endTime = obj.getString("stop_time");
int type = obj.getInteger("type");
if(!startTime.equals(endTime)){
RecordTimeBean bean = new RecordTimeBean();
Date date1 = DateUtil.convertString2Date(startTime,"yyyy-MM-dd HH:mm:ss");
Date date2 = DateUtil.convertString2Date(endTime,"yyyy-MM-dd HH:mm:ss");
Calendar startTime = Calendar.getInstance();
startTime.setTime(date1);
bean.startTime = startTime;
Calendar endTime = Calendar.getInstance();
endTime.setTime(date2);
bean.endTime = endTime;
bean.type = type;
dirInfoList.add(bean);
}
}
if(_result == 0){
m_dirInfo = dirInfoList.get(0);
LogUtil.i(TAG, "===== _result = 0[dirInfoList size] = "+dirInfoList.size()+" isload="+scrollView._isLoad);
RecordTimeBean b = dirInfoList.get(dirInfoList.size()-1);
endTime = DateUtil.convertDate2String(b.endTime.getTime(),"yyyy-MM-dd HH:mm:ss");
findView();
closeWait();
if(scrollView._isLoad != 0){
scrollView._isLoad = 0;
}
if(mQrLineView != null){
mQrLineIsShow = false;
mQrLineView.clearAnimation();
mQrLineView.setVisibility(View.GONE);
}
}
break;
case 2://没有前端录像(隐藏时间BTN和时间轴)
closeWait();
if(scrollView != null && scrollView._isLoad != 0){
scrollView._isLoad = 0;
}
if(mQrLineView != null){
mQrLineView.clearAnimation();
mQrLineView.setVisibility(View.GONE);
mQrLineIsShow = false;
}
break;
default:
break;
}
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
super.handleMessage(msg);
}
}
void init(String yyyyMMdd){
try {
dirInfoList.clear();
_handler.sendEmptyMessage(1004);
baseApp.setVideoHandler(videoHandler);
String sid = devSid;
Map<String, Object> maps = new HashMap<String, Object>();
maps.put("type", 1);
maps.put("action", 106);
maps.put("channel", channelNo);
maps.put("sid", sid);
maps.put("start_time", yyyyMMdd + " 00:00:00");
maps.put("stop_time", yyyyMMdd + " 23:59:59");
maps.put("video_type", 0);
String jsonString = new JSONObject(maps).toString();
int result = SDK.SendJsonPck(0, sid+"|"+jsonString);
LogUtil.d(TAG, "return value:" + result);
} catch (Exception e) {
LogUtil.e(TAG, ExceptionsOperator.getExceptionInfo(e));
}
}
private void getStreams(){
String setBreath = "{\"id\":200,\"method\":\"magicBox.getProductDefinition\",\"params\":{\"name\":\"MaxExtraStream\"}}";
SDK.ExtCommandReq(1, devSid, setBreath.getBytes(), setBreath.getBytes().length);
}
//返回值代码辅码流路数 1:流畅 2:流畅、标准 3:不管
@SuppressLint("UseValueOf")
public void setDevStream(String str){
try {
//如果当前设备不支持标准 要把缓存里面的stream 值改掉
if(str != null && !str.equals("")){
_StreamDefinition = Integer.parseInt(JSON.parseObject(str).getString("definition"));
_editor = _preferences.edit();
_editor.putInt(devSid, _StreamDefinition);
_editor.commit();
updateStream();
}
} catch (Exception e) {
}
}
private void updateStream(){
if(_stream == 2 && _StreamDefinition == 1){
_editor = _preferences.edit();
_editor.putInt("streamCode", 1);
_editor.commit();
_stream = 1;
_streamSet.setText(getText(R.string.Video_pop_low).toString());
}
}
private int mode = 0; // 触控点的个数
float oldDist = 0;
/**
* 放缩比例/移动比例
*/
public static float change = 0.1f;
static final int NONE = 0;
static final int DRAG = 1; //拖动中
static final int ZOOM = 2; //缩放中
float base = 1.5f;//缩放基数
float tempX;//滑动到最左边:缩小时直接到原始值
private float mPreviousY;//拖动中---记录触控笔位置
private float mPreviousX;
private float mDownX;//初始状态 向上-缩放 坐标点信息
private float mDownY;
private float mCurrentPosX;//初始状态 向上-缩放 坐标点信息
private float mCurrentPosY;
private int flag = 0;//初始状态 标识
private float mDownX2;
//private float mDownY2;
private int MaxZomm = 4;//缩放最大值
@Override
public boolean onTouch(View v, MotionEvent event) {
try {
float y = event.getY();
float x = event.getX();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = 1;
mDownX = event.getX();
mDownY = event.getY();
if(event.getPointerCount()==2){
mode = ZOOM;
}else if(event.getPointerCount()==1){
mode = DRAG;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (caluDist(event) > 10f) {
mode = ZOOM;
oldDist = caluDist(event);
}
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_UP:
if(mode == DRAG){
mDownX2 = event.getX();
if (Math.abs(mDownX - mDownX2) < 6) {
//if(Constants.deviceType == -1){
//mDownY2 = event.getY();
onTouchClick(v);
//}
}
if(flag == 1){
renderer.xAngle = 0;
renderer.yAngle = 0;
renderer.scaleX = renderer.scaleInitX;
renderer.scaleY = renderer.scaleInitY;
flag = 0;
}
//180设备特殊处理
if(Constants.deviceType == -1 && renderer._is180Open == 0){
//System.out.println("test33= "+renderer.scaleX);
if(renderer.scaleX > 4f){
base = 85f;
}else if(renderer.scaleX > 3){
base = 80f;
}else if(renderer.scaleX > 2){
base = 70f;
}else if(renderer.scaleX > 1.5){
base = 60f;
}else{
base = 40f;
}
//System.out.println("test22:X="+renderer.mAngleX+" Y= "+renderer.mAngleY);
if(renderer.mAngleX > base){//已左移到最左边
renderer.mAngleX = base;
if(renderer.mAngleY < -base){//左上
if(base >= 70f) base = 40f;
renderer.mAngleY = -base;
}
if(renderer.mAngleY > base){//右上
if(base >= 70f) base = 40f;
renderer.mAngleY = base;
}
}else if(renderer.mAngleX < -base){//最右边
renderer.mAngleX = -base;
if(renderer.mAngleY > base){//右上
if(base >= 70f) base = 40f;
renderer.mAngleY = base;
}
if(renderer.mAngleY < -base){
if(base >= 70f) base = 40f;
renderer.mAngleY = -base;
}
}else if(renderer.mAngleY > base){//最上面
renderer.mAngleY = base;
}else if(renderer.mAngleY < -base){//最下面
if(base >= 70f) base = 40f;
renderer.mAngleY = -base;
}
}else{
//IPC设备
//System.out.println("renderer.scaleX22:::: "+renderer.scaleX+" : "+renderer.xAngle);
if(renderer.scaleX > 4f){
base = 3.5f;
}else if(renderer.scaleX > 3f){
base = 2.5f;
}else if(renderer.scaleX > 2f){
base = 1.7f;
}else if(renderer.scaleX > 1.5f){
base = 1.2f;
}else{
base = 0.7f;
}
if(renderer.xAngle > base){//已左移到最左边
tempX = renderer.xAngle;
renderer.xAngle = base;
if(renderer.yAngle < -base)//左上
renderer.yAngle = -base;
if(renderer.yAngle > base)//右上
renderer.yAngle = base;
}else if(renderer.xAngle < -base){//最右边
tempX = renderer.xAngle;
renderer.xAngle = -base;
if(renderer.yAngle > base)//右上
renderer.yAngle = base;
if(renderer.yAngle < -base)
renderer.yAngle = -base;
}else if(renderer.yAngle > base){//已左移到最下边
renderer.yAngle = base;
}else if(renderer.yAngle < -base){//最上边
renderer.yAngle = -base;
}
}
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == ZOOM) {//双指
float newDist = caluDist(event);
float gapLenght = newDist - oldDist;
if(gapLenght == 0) {
break;
}else if(Math.abs(gapLenght)>15f){
if(gapLenght>0) { //放大ing
if(renderer.scaleX > MaxZomm){
}else{
renderer.scaleX += change;
renderer.scaleY += change;
if(Constants.deviceType == -1){
if(renderer._is180Open != 0){
renderer._is180Open = 0;
renderer.changeMatrix();
MaxZomm = 3;
}
renderer.wheelEvent(gapLenght);
}
}
}else { //缩小ing
if(renderer.scaleX <= renderer.scaleInitX){
//System.out.println("renderer.scaleX22:::: "+renderer.scaleX+" : "+renderer.scaleY);
//优化修改:180缩放到最小时 平滑缩放
renderer.xAngle = 0;
renderer.yAngle = 0;
//renderer.scaleX = renderer.scaleInitX;
//renderer.scaleY = renderer.scaleInitY;
if(Constants.deviceType == -1 && renderer._is180Open != 1){
renderer.scaleX -= change;
renderer.scaleY -= change;
if(renderer.scaleX < 1){
renderer._is180Open = 1;
renderer.changeMatrix();
MaxZomm = 4;
_clickFlag = 0;
}
}else{
renderer.scaleX = renderer.scaleInitX;
renderer.scaleY = renderer.scaleInitY;
}
break;
}else{
if((tempX > base || tempX < -base) && (base == 3 || base == 1.5)){
renderer.xAngle = 0;
renderer.yAngle = 0;
renderer.scaleX = renderer.scaleInitX;
renderer.scaleY = renderer.scaleInitY;
tempX = 0;
break;
}
renderer.scaleX -= change;
renderer.scaleY -= change;
if(Constants.deviceType == -1) renderer.wheelEvent(gapLenght);
}
}
oldDist = newDist;
}
} else if(mode == DRAG){//单指
// if(Constants.deviceType == -1){//180像机
// float dy = y - mPreviousY;// 计算触控笔Y位移
// float dx = x - mPreviousX;// 计算触控笔X位移
// renderer.mAngleX += dx * 0.1f;// 设置填充椭圆绕y轴旋转的角度
// renderer.mAngleY -= dy * 0.1f;// 设置填充椭圆绕x轴旋转的角度
// }else{
if(renderer.scaleX > 1){//拖动平移
float dy = y - mPreviousY;// 计算触控笔Y位移
float dx = x - mPreviousX;// 计算触控笔X位移
renderer.xAngle += dx * 0.002f;// 设置填充椭圆绕y轴旋转的角度
renderer.yAngle -= dy * 0.002f;// 设置填充椭圆绕x轴旋转的角度
renderer.mAngleX += dx * 0.1f;
renderer.mAngleY += dy * 0.1f;
//System.out.println("test222::::: "+renderer.mAngleX+" : "+renderer.mAngleY+" : "+dx+" : "+dy);
flag = 0;
}else if(renderer.scaleX <= 1){//renderer.scaleInitXY 改成 1
if(flag == 0){
flag = 1;
}
mCurrentPosX = event.getX();
mCurrentPosY = event.getY();
if (mCurrentPosX - mDownX > 0 && Math.abs(mCurrentPosY - mDownY) < 10){
//向右-缩小
if(renderer.scaleX >= renderer.scaleInitX){
renderer.scaleX -= change;
renderer.scaleY -= change;
}
}else if (mCurrentPosX - mDownX < 0 && Math.abs(mCurrentPosY - mDownY) < 10){
//向左
}else if (mCurrentPosY - mDownY > 0 && Math.abs(mCurrentPosX - mDownX) < 10){
flag = 2;
//向下-放大
renderer.scaleX += change - 0.07f;
renderer.scaleY += change - 0.07f;
//System.out.println("renderer.scaleX:::: "+renderer.scaleX+" : "+renderer.scaleY);
if(Constants.deviceType == -1 && renderer._is180Open != 0){
renderer._is180Open = 0;
renderer.changeMatrix();
MaxZomm = 3;
}
}else if (mCurrentPosY - mDownY < 0 && Math.abs(mCurrentPosX - mDownX) < 10){
//向上-缩小
if(renderer.scaleX >= renderer.scaleInitX){
renderer.scaleX -= change;
renderer.scaleY -= change;
}
}
}
// }
}
if(_stream == 0) glView.requestRender();
break;
}
mPreviousY = y;// 记录触控笔位置
mPreviousX = x;// 记录触控笔位置
} catch (Exception e) {
}
return true;
}
public float caluDist(MotionEvent event) {
float dx = event.getX(0) - event.getX(1);
float dy = event.getY(0) - event.getY(1);
return (float) Math.sqrt(dx * dx + dy * dy);
}
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
// if(_decoderDebugger != null && _decoderDebugger.decoderSuccess == 1){// && _decoderDebugger.decoderSuccess == 1
// glView.requestRender();
// }
}
int _nClickedCount = 0;
View _lastClieckView = null;
protected MyWinHandler _mHandler = new MyWinHandler();
public final static int DOUBLE_CLICKED = 100;
//1.点击视频窗口事件 发送消息(双击就是点两次)
public void onTouchClick(View v) {
if (v.equals(_lastClieckView)) {
//主要控制双击事件 单个视频可以注释
_nClickedCount++;
} else {
_nClickedCount = 1;
Message msg = new Message();
msg.what = DOUBLE_CLICKED;
msg.obj = v;
_mHandler.sendMessageDelayed(msg, 300);
}
_lastClieckView = v;
}
//2.接受消息
@SuppressLint("HandlerLeak")
class MyWinHandler extends Handler {
// 子类必须重写此方法,接受数据
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case DOUBLE_CLICKED:
selected(_nClickedCount);
_nClickedCount = 0;
_lastClieckView = null;
break;
}
}
}
int _clickFlag = 0;
public void selected(int nClickedCount) {
// 处理双击事件
if (nClickedCount > 1 && Constants.deviceType == -1) {
//跳转到指点的位置
if(renderer._is180Open != 0 && _clickFlag == 0){
// float dy = mDownY2 - mPreviousY;// 计算触控笔Y位移
// float dx = mDownX2 - mPreviousX;// 计算触控笔X位移
// renderer.mAngleX += dx * 0.1f;
// renderer.mAngleY += dy * 0.1f;
// System.out.println("test222:::double "+renderer.mAngleX+" : "+renderer.mAngleY+" : "+dx+" : "+dy);
_clickFlag = 1;
renderer._is180Open = 0;
renderer.changeMatrix();
MaxZomm = 3;
}else if(renderer._is180Open != 1){
renderer._is180Open = 1;
renderer.changeMatrix();
MaxZomm = 4;
_clickFlag = 0;
}
}
if(nClickedCount == 1){
//show(footer);
if(!_isScreen) return;
if(footer.getVisibility() == View.GONE){
footer.setVisibility(View.VISIBLE);
}else if(footer.getVisibility() == View.VISIBLE){
footer.setVisibility(View.GONE);
}
}
}
public void getSubUserRights(){
for (int i = 0; i < Constants._subUserList.size(); i++) {
if(devSid.equals(Constants._subUserList.get(i).getDid())){
_subUserState = Constants._subUserList.get(i).getState();
_isRightsTalk = (_subUserState & 8) == 8;
_isRightsRecord = (_subUserState & 2) == 2;
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
//private float[] gravity = new float[3];
@Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
System.out.println("x------------->" + Math.toDegrees(x)+" "+z);
System.out.println("y------------->" + y);
/*for(int i=0; i<3; i++) {
gravity [i] = (float) (0.1 * event.values[i] + 0.9 * gravity[i]);
}
System.out.println("X axis reading: " + gravity [0]);
System.out.println("Y axis reading: " + gravity [1]);
System.out.println("Z axis reading: " + gravity [2]);*/
//
// String msg = String.format(
// "Gravity\nX: %8.4f\nY: %8.4f\nZ: %8.4f\n" +
// "Motion\nX: %8.4f\nY: %8.4f\nZ: %8.4f",
// gravity[0], gravity[1], gravity[2],
// motion[0], motion[1], motion[2]);
}
}