//Copyright 2018 Huawei Technologies Co.,Ltd.
package com.huawei.mediacloud.livepushdemo.capture;

import android.Manifest;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.github.faucamp.simplertmp.RtmpHandler;
import com.huawei.mediacloud.livepushdemo.utils.ParameterSettingValues;
import com.huawei.publishsdk.HWVideoFrame;
import com.huawei.publishsdk.HwEncodeHandler;
import com.huawei.publishsdk.HwPublisher;
import com.huawei.publishsdk.HwRecordHandler;
import com.meicam.sdk.NvsCaptureVideoFx;
import com.meicam.sdk.NvsFxDescription;
import com.meicam.sdk.NvsSize;
import com.meicam.sdk.NvsStreamingContext;
import com.huawei.mediacloud.livepushdemo.R;
import com.huawei.mediacloud.livepushdemo.base.BaseActivity;
import com.huawei.mediacloud.livepushdemo.download.AssetDownloadActivity;
import com.huawei.mediacloud.livepushdemo.edit.adapter.SpaceItemDecoration;
import com.huawei.mediacloud.livepushdemo.edit.data.FilterItem;
import com.huawei.mediacloud.livepushdemo.utils.AppManager;
import com.huawei.mediacloud.livepushdemo.utils.AssetFxUtil;
import com.huawei.mediacloud.livepushdemo.utils.Constants;
import com.huawei.mediacloud.livepushdemo.utils.ScreenUtils;
import com.huawei.mediacloud.livepushdemo.utils.ToastUtil;
import com.huawei.mediacloud.livepushdemo.utils.Util;
import com.huawei.mediacloud.livepushdemo.utils.asset.NvAsset;
import com.huawei.mediacloud.livepushdemo.utils.asset.NvAssetManager;
import com.huawei.mediacloud.livepushdemo.utils.dataInfo.VideoClipFxInfo;
import com.huawei.mediacloud.livepushdemo.utils.permission.PermissionsActivity;
import com.huawei.mediacloud.livepushdemo.utils.permission.PermissionsChecker;
import com.huawei.mediacloud.livepushdemo.view.FaceUPropView;
import com.huawei.mediacloud.livepushdemo.view.FilterView;

import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import static com.huawei.mediacloud.livepushdemo.utils.NetworkUtils.NetworkUtils.isAvailableByPing;
import static com.huawei.publishsdk.HwPublisher.H264;
import static com.huawei.publishsdk.HwPublisher.RGBA;

public class CaptureActivity extends BaseActivity implements NvsStreamingContext.CaptureDeviceCallback,
        SurfaceTexture.OnFrameAvailableListener,GLSurfaceView.Renderer,
        RtmpHandler.RtmpListener,
        HwEncodeHandler.HwEncodeListener,
        HwRecordHandler.HwRecordListener{
    private static final String TAG = "Capture";

//    public static String rtmpUrl ="rtmp://119.3.69.60/live/zh111?vhost=live.myhwclouds.com.cn";
    public static String rtmpUrl ="rtmp://kitpush.hwcloudlive.com/live1/sdkdemo1";

//    public static String rtmpUrl ="rtmp://53314.livepush.myqcloud.com/live/zhanganlong?txSecret=ad67aea57569b295621c821a3632aed1&txTime=5D07B8FF";
    private boolean isRightUrl = false;

    public static final String BEAUTY_SHAPE_EYE_ENLARGING = "Eye Enlarging";
    public static final String BEAUTY_SHAPE_CHECK_THINNING = "Cheek Thinning";
    public static final String BEAUTY_SHAPE_INTENSITY_FORHEAD = "Intensity Forhead";
    public static final String BEAUTY_SHAPE_INTENSITY_CHIN = "Intensity Chin";
    public static final String BEAUTY_SHAPE_INTENSITY_NOSE = "Intensity Nose";
    public static final String BEAUTY_SHAPE_INTENSITY_MOUTH = "Intensity Mouth";

    private static final double NORMAL_VELUE_INTENSITY_FORHEAD = 0.5;
    private static final double NORMAL_VELUE_INTENSITY_CHIN = 0.5;
    private static final double NORMAL_VELUE_INTENSITY_MOUTH = 0.5;


    private static final int REQUEST_CAMERA_PERMISSION_CODE = 0;
    private static final int REQUEST_RECORD_AUDIO_PERMISSION_CODE = 1;
    private static final int REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_CODE = 2;

    public static final int CAPTURE_TYPE_ZOOM = 2;
    public static final int CAPTURE_TYPE_EXPOSE = 3;
    private static final int REQUEST_FILTER_LIST_CODE = 110;
    private static final int ARFACE_LIST_REQUES_CODE = 111;

    public static final int mVideoFPS = 15;

    private PermissionsChecker mPermissionsChecker; // 权限检测器
    private NvsStreamingContext mStreamingContext;
    private Button mCloseButton;
    private LinearLayout mFunctionButtonLayout;
    private LinearLayout mSwitchFacingLayout;
    private LinearLayout mSwitchEncoderLayout;
    private LinearLayout mFlashLayout;
    private ImageView mFlashButton;
    private LinearLayout mZoomLayout;
    private LinearLayout mExposureLayout;
    private LinearLayout mBeautyLayout;
    private LinearLayout mFilterLayout;
    private LinearLayout mFuLayout;
    private LinearLayout mOpenRecordLayout;
    private TextView mOk;
    private RelativeLayout mStartLayout;
    private Button capture_btn;
    private EditText rtmpUrl_edit;
    private SharedPreferences sp;

    private TextView mSeekTitle;
    private TextView mSeekProgress;
    private ImageView mImageAutoFocusRect;

    private NvAssetManager mAssetManager;

    private boolean mPermissionGranted;
    List<String> mAllRequestPermission = new ArrayList<>();
    private Dialog mBuilderPermission;
    private RelativeLayout mPermissionDialog;
    private boolean mIsSwitchingCamera = false;
    NvsStreamingContext.CaptureDeviceCapability mCapability = null;
    private AlphaAnimation mFocusAnimation;

    private int encodeBitrate;
    private int encodeGop;
    private int encodeWidth;
    private int encodeHeight;

    /*变焦以及曝光dialog*/
    private AlertDialog mCaptureZoomAndExposeDialog;
    private View mZoomView;
    private SeekBar mZoomSeekbar;
    private SeekBar mExposeSeekbar;
    private int mZoomValue;
    private int mMinExpose;
    private int mCaptureType;

    /*美颜Dialog*/
    private AlertDialog mCaptureBeautyDialog;
    private View mBeautyView;
    private Button mBeauty;
    private Button mBeauty_shape;
    private RelativeLayout mBeautySelect;
    private RelativeLayout mBeautyShapeSelect;
    /*美颜*/
    private ImageView mSharpening_iv_close;
    private ImageView mSharpening_iv_open;
    private Switch mBeauty_switch;
    private TextView mBeauty_switch_text;
    private SeekBar mStrength;
    private SeekBar mWhitening;
    private SeekBar mReddening;
    private Boolean mIsBeautyType = true;
    /*美型*/
    private Switch mBeauty_shape_switch;
    private TextView mBeauty_shape_switch_text;
    private SeekBar mLevel;
    private LinearLayout mBeautyShapeResetLayout;
    private ImageView mBeautyShapeResetIcon;
    private TextView mBeautyShapeResetTxt;
    private RecyclerView mBeautyShapeRecyclerView;
    private ShapeAdapter mShapeAdapter;
    private String mCurBeautyShapeId = BEAUTY_SHAPE_CHECK_THINNING;

    private NvsCaptureVideoFx mBeautyFx;//美颜特效
    private double mStrengthValue;
    private double mWhiteningValue;
    private double mReddeningValue;
    private double mLevelValue = 0;

    //滤镜
    private AlertDialog mFilterDialog;
    private FilterView mFilterView;
    private NvsCaptureVideoFx mCurCaptureVideoFx;
    private ArrayList<FilterItem> mFilterDataArrayList = new ArrayList<>();
    private int mFilterSelPos = 0;
    private VideoClipFxInfo mVideoClipFxInfo = new VideoClipFxInfo();

    //道具
    private boolean mCanUseARFace = false; // 人脸特效是否可用的标识.默认不可用
    private NvsCaptureVideoFx mARFaceU;
    private AlertDialog mFaceUPropDialog;
    private FaceUPropView mFaceUPropView;
    private ArrayList<FilterItem> mPropDataArrayList = new ArrayList<>();
    private int mFaceUPropSelPos = 0;
    private String mFaceUPropName = "";


    private boolean m_supportAutoFocus = false; // 是否支持自动聚焦

    private boolean mSharpenDefault = false;
    private SeekBar mDefaultBeauty_sb;
    private ImageView mDefaultBeauty_iv;
    private boolean mDefaultBeautyOpen = false;
    private LinearLayout mStrengthMenu_ll;
    private LinearLayout mWhiteningMenu_ll;
    private LinearLayout mReddeningMenu_ll;
    private int mBeautyIndex = 3;
    // 美颜开关
    private boolean mBeautySwitchIsOpend = false;
    // 美型开关
    private boolean mBeautyShapeSwitchIsOpen = false;
    // 基础滤镜强度
    private double mDefaultBeautyIntensity = 1.0;
    private RelativeLayout mStrength_bg;
    private RelativeLayout mWhitening_bg;
    private RelativeLayout mReddening_bg;
    private TextView mStrength_tv;
    private TextView mWhitening_tv;
    private TextView mReddening_tv;

    //add by zhang
    private boolean m_permissionGranted = false;
    private boolean m_useBeauty = true;
    private ByteBuffer RGBA_buffer;
    private int imageWidth = 720;
    private int imageHeight = 1280;
//    private int viewWidth = 720;
//    private int viewHeight = 1280;

    private int orgViewWidth = 720;
    private int orgViewHeight  = 1280;
    private int viewWidth = 720;
    private int viewHeight = 1280;
    private int viewPortX = 0;
    private int viewPortY = 0;

    private RelativeLayout mLogLayout;
    private TextView mLogText;
    Timer timer;

    private GLSurfaceView m_GLView;
    private SurfaceTexture mSurface;
    private boolean isEGLStoped = true;
    private int mTextureID;
    private int mProgram = 0;
    private int muMVPMatrixHandle = -1;
    private int muSTMatrixHandle = -1;
    private int maPositionHandle = -1;
    private int maTextureHandle = -1;
    private float[] mMVPMatrix = new float[16];
    private float[] mSTMatrix = new float[16];

    private int[] textures;
    private int[] frameBufferBinding;
    private int mTextureIDDst;

    private HwPublisher mPublisher;
    private boolean isConnected;
    private boolean isConnecting;
    private final Object writeLock = new Object();
    private int mCameraId;
    private String recPath = Environment.getExternalStorageDirectory().getPath() + "/test.mp4";
    private boolean isRecording;

    private int mCurrentDeviceIndex;

    private volatile int vfps;
    private volatile int vbitrate;
    private volatile int abitrate;

    private long startTouchTime;
    private int touchTimes;
    private boolean isShowLog;

    private static final int FLOAT_SIZE_BYTES = 4;
    private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 4 * FLOAT_SIZE_BYTES;
    private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
    private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 2;
    private final float[] mTriangleVerticesData = {
            // X, Y, U, V
            -1.0f, -1.0f, 0.f, 0.f,
            1.0f, -1.0f, 1.f, 0.f,
            -1.0f,  1.0f, 0.f, 1.f,
            1.0f,  1.0f, 1.f, 1.f,
    };

    private FloatBuffer mTriangleVertices;

    private final String mVertexShader =
            "attribute vec4 aPosition;\n" +
                    "attribute vec2 aTextureCoord;\n" +
                    "uniform mat4 uMVPMatrix;\n" +
                    "uniform mat4 uSTMatrix;\n" +
                    "varying vec2 textureCoordinate;\n" +
                    "void main()\n" +
                    "{\n" +
                    "gl_Position = uMVPMatrix * aPosition;\n" +
                    "vec4 tex4 = vec4(aTextureCoord.xy, 1.0, 1.0);\n" +
                    "textureCoordinate = (uSTMatrix * tex4).xy;\n" +
                    "}";

    private final String mFragmentShader =
            "#extension GL_OES_EGL_image_external : require\n" +
                    "precision mediump float;\n" +
                    "varying vec2 textureCoordinate;\n" +
                    "uniform samplerExternalOES s_texture;\n" +
                    "void main() {\n" +
                    "gl_FragColor = texture2D(s_texture, textureCoordinate);\n" +
                    "}";


    @Override
    protected int initRootView() {
        mStreamingContext = NvsStreamingContext.getInstance();
        mStreamingContext.removeAllCaptureVideoFx();
        Log.e(TAG,"initRootView");

        return R.layout.activity_capture;
    }

    private void initTimer(){
        // 初始化定时器
        timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String isSoftEnc;
                        if (mPublisher != null) {
                            if (mPublisher.isSoftEncoder()) {
                                isSoftEnc = "soft";
                            } else {
                                isSoftEnc = "hard";
                            }
                            mLogText.setText("vFPS:  " + vfps + "\n" + "vGOP:  " + mPublisher.getVSetGop() + "\n"
                                    + "vBitrate:  " + vbitrate  + " kb/s\n"
                                    + "vOutWidth:  " + mPublisher.getVOutWidth() + "\n" + "vOutHeigth:  " + mPublisher.getVOutHeight() + "\n"
                                    + "vPreViewWidth:  " + mPublisher.getPreviewResolution()[0] + "\n" + "vPreViewHeigth:  " + mPublisher.getPreviewResolution()[1] + "\n"
                                    + "vEncoder:  " + isSoftEnc + "\n"
                                    + "aSamplerate:  " + mPublisher.getASamplerate() + "\n"
                                    + "aBitrate:  " + abitrate / 1000 + " kb/s");
                        }
                    }
                });
            }
        }, 0, 1000);
    }

    // 停止定时器
    private void stopTimer(){
        if(timer != null){
            timer.cancel();
            // 一定设置为null，否则定时器不会被回收
            timer = null;
        }
    }

    @Override
    protected void initViews() {
        Log.e(TAG,"initViews");
        Intent intent = getIntent();
        if (intent != null) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                mCanUseARFace = bundle.getBoolean(Constants.CAN_USE_ARFACE_FROM_MAIN, true);
                encodeBitrate = bundle.getInt("encodeBitrate");
                encodeGop = bundle.getInt("encodeGop");
                encodeWidth = bundle.getInt("encodeWidth");

                if(encodeWidth==360)
                    encodeHeight = 640;
                else if(encodeWidth == 540)
                    encodeHeight = 960;
                else if(encodeWidth == 720)
                    encodeHeight =1280;
                Log.e(TAG, "initData: encode bit: "+encodeBitrate+"gop:"+encodeGop+"width"+encodeWidth);
            }
        }
        // restore data.
        sp = getSharedPreferences("rtmpurl", MODE_PRIVATE);
        rtmpUrl = sp.getString("rtmpUrl", rtmpUrl);
        // initialize url.
        rtmpUrl_edit = (EditText) findViewById(R.id.url);
        rtmpUrl_edit.setText(rtmpUrl);
//        /*变焦以及曝光dialog*/
        LayoutInflater inflater = LayoutInflater.from(this);
        mZoomView = inflater.inflate(R.layout.zoom_view, null);
        mZoomSeekbar = (SeekBar) mZoomView.findViewById(R.id.zoom_seekbar);
        mExposeSeekbar = (SeekBar) mZoomView.findViewById(R.id.expose_seekbar);
        mSeekTitle = (TextView) mZoomView.findViewById(R.id.seekTitle);
        mSeekProgress = (TextView) mZoomView.findViewById(R.id.seekProgress);

        /*美颜dialog*/
        LayoutInflater beautyInflater = LayoutInflater.from(this);
        mBeautyView = beautyInflater.inflate(R.layout.beauty_view, null);
        mBeauty = (Button) mBeautyView.findViewById(R.id.beauty);
        mBeauty_shape = (Button) mBeautyView.findViewById(R.id.beauty_shape);
        mBeautySelect = (RelativeLayout) mBeautyView.findViewById(R.id.beauty_select);
        mBeautyShapeSelect = (RelativeLayout) mBeautyView.findViewById(R.id.beauty_shape_select);


        /*美颜*/
        mBeauty_switch = (Switch) mBeautyView.findViewById(R.id.beauty_switch);
        mBeauty_switch_text = (TextView) mBeautyView.findViewById(R.id.beauty_switch_text);
        mStrength = (SeekBar) mBeautyView.findViewById(R.id.strength);
        mWhitening = (SeekBar) mBeautyView.findViewById(R.id.whitening);
        mReddening = (SeekBar) mBeautyView.findViewById(R.id.reddening);
        mSharpening_iv_close = (ImageView) mBeautyView.findViewById(R.id.sharpening_iv_close); // 锐化关
        mSharpening_iv_close.setEnabled(false);
        mSharpening_iv_open = (ImageView) mBeautyView.findViewById(R.id.sharpening_iv_open); // 锐化开
        mSharpening_iv_open.setEnabled(false);
        mSharpening_iv_open.setVisibility(View.GONE);
        mDefaultBeauty_iv = (ImageView) mBeautyView.findViewById(R.id.default_beauty_iv); // 基础美颜seekbar
        mDefaultBeauty_iv.setEnabled(false);
        mDefaultBeauty_iv.setAlpha(0.4f);
        mDefaultBeauty_sb = (SeekBar) mBeautyView.findViewById(R.id.default_beauty_sb); // 基础美颜seekbar
        /*美颜选项按钮*/
        mStrengthMenu_ll = (LinearLayout) mBeautyView.findViewById(R.id.strength_menu_ll);
        mWhiteningMenu_ll = (LinearLayout) mBeautyView.findViewById(R.id.whitening_menu_ll);
        mReddeningMenu_ll = (LinearLayout) mBeautyView.findViewById(R.id.reddening_menu_ll);
        mStrengthMenu_ll.setAlpha(0.5f);
        mWhiteningMenu_ll.setAlpha(0.5f);
        mReddeningMenu_ll.setAlpha(0.5f);
        mStrengthMenu_ll.setEnabled(false);
        mWhiteningMenu_ll.setEnabled(false);
        mReddeningMenu_ll.setEnabled(false);
        /*美颜按钮样式相关*/
        mStrength_bg = (RelativeLayout) mBeautyView.findViewById(R.id.strength_bg);
        mWhitening_bg = (RelativeLayout) mBeautyView.findViewById(R.id.whitening_bg);
        mReddening_bg = (RelativeLayout) mBeautyView.findViewById(R.id.reddening_bg);
        mStrength_tv = (TextView) mBeautyView.findViewById(R.id.strength_tv);
        mWhitening_tv = (TextView) mBeautyView.findViewById(R.id.whitening_tv);
        mReddening_tv = (TextView) mBeautyView.findViewById(R.id.reddening_tv);

        /*美型*/
        mBeauty_shape_switch = (Switch) mBeautyView.findViewById(R.id.beauty_shape_switch);
        mBeauty_shape_switch_text = (TextView) mBeautyView.findViewById(R.id.beauty_shape_switch_text);
        mLevel = (SeekBar) mBeautyView.findViewById(R.id.level);
        mBeautyShapeResetLayout = (LinearLayout) mBeautyView.findViewById(R.id.beauty_shape_reset_layout);
        mBeautyShapeResetIcon = (ImageView) mBeautyView.findViewById(R.id.beauty_shape_reset_icon);
        mBeautyShapeResetTxt = (TextView) mBeautyView.findViewById(R.id.beauty_shape_reset_txt);
        mBeautyShapeRecyclerView = (RecyclerView) mBeautyView.findViewById(R.id.beauty_shape_item_list);

        mImageAutoFocusRect = (ImageView) findViewById(R.id.imageAutoFocusRect);
        mStartLayout = (RelativeLayout) findViewById(R.id.startLayout);
        capture_btn = (Button) findViewById(R.id.capture_btn);

        mCloseButton = (Button) findViewById(R.id.closeButton);
        mFunctionButtonLayout = (LinearLayout) findViewById(R.id.functionButtonLayout);
        mSwitchFacingLayout = (LinearLayout) findViewById(R.id.switchFacingLayout);
        mSwitchEncoderLayout = (LinearLayout) findViewById(R.id.switchEncoderLayout);
        mFlashLayout = (LinearLayout) findViewById(R.id.flashLayout);
        mFlashButton = (ImageView) findViewById(R.id.flashButton);
        mZoomLayout = (LinearLayout) findViewById(R.id.zoomLayout);
        mExposureLayout = (LinearLayout) findViewById(R.id.exposureLayout);
        mBeautyLayout = (LinearLayout) findViewById(R.id.beautyLayout);
        mFilterLayout = (LinearLayout) findViewById(R.id.filterLayout);
        mFuLayout = (LinearLayout) findViewById(R.id.fuLayout);
        mOpenRecordLayout = (LinearLayout) findViewById(R.id.openRecordLayout);

        mLogLayout = (RelativeLayout) findViewById(R.id.log_rl);
        mLogText = (TextView) findViewById(R.id.log_tv);

        m_GLView = (GLSurfaceView) findViewById(R.id.GLView);
        m_GLView.setEGLContextClientVersion(2); //设置使用OPENGL ES2.0
        m_GLView.setRenderer(CaptureActivity.this);
        m_GLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)) {
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO)) {
                    if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        m_permissionGranted = true;
                    } else {
                        requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_CODE);
                    }
                } else {
                    requestPermissions(new String[]{android.Manifest.permission.RECORD_AUDIO}, REQUEST_RECORD_AUDIO_PERMISSION_CODE);
                }
            } else {
                requestPermissions(new String[]{android.Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION_CODE);
            }
        } else {
            m_permissionGranted = true;
        }

        mCaptureZoomAndExposeDialog = new AlertDialog.Builder(this).create();
        mCaptureZoomAndExposeDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                closeCaptureDialogView(mCaptureZoomAndExposeDialog);
            }
        });

        mCaptureBeautyDialog = new AlertDialog.Builder(this).create();
        mCaptureBeautyDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                closeCaptureDialogView(mCaptureBeautyDialog);
            }
        });

        beautyClickListener();

        //外部输入初始化
        mPublisher = new HwPublisher(this);
        mPublisher.setEncodeHandler(new HwEncodeHandler(this),H264);
        mPublisher.setRtmpHandler(new RtmpHandler(this),H264);
        mPublisher.setRecordHandler(new HwRecordHandler(this));
        mPublisher.setPreviewResolution(encodeHeight, encodeWidth);//19201080
        mPublisher.setOutputResolution(encodeWidth, encodeHeight);
        mPublisher.setVideoHDMode();
        mPublisher.setVfps(mVideoFPS);
        mPublisher.setVBitrate(1024*encodeBitrate);
        mPublisher.setVgop(encodeGop);
        mPublisher.startCamera();

        isConnected = false;
        isRecording = false;
        isConnecting = false;
        mOpenRecordLayout.setEnabled(false);
        mOpenRecordLayout.getChildAt(0).setAlpha((float) 0.4);

        mFlashLayout.setEnabled(false);
        mFlashButton.setImageResource(R.mipmap.icon_flash_off);
        mFlashButton.setImageAlpha(128);

        mBeauty_switch.setChecked(true);

    }

    //滤镜数据初始化
    private void initFilterList() {
        mFilterDataArrayList.clear();
        mFilterDataArrayList = AssetFxUtil.getFilterData(this,
                getLocalData(NvAsset.ASSET_FILTER),
                null,
                true,
                false);
    }

    private void initFilterDialog() {
        mFilterDialog = new AlertDialog.Builder(this).create();
        mFilterDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                closeCaptureDialogView(mFilterDialog);
            }
        });
        mFilterView = new FilterView(this);
        //先设置滤镜数据
        mFilterView.setFilterArrayList(mFilterDataArrayList);
        mFilterView.initFilterRecyclerView(this);
        mFilterView.setIntensityLayoutVisible(View.INVISIBLE);
        mFilterView.setIntensityTextVisible(View.GONE);
        mFilterView.setFilterListener(new FilterView.OnFilterListener() {
            @Override
            public void onItmeClick(View v, int position) {
                int count = mFilterDataArrayList.size();
                if (position < 0 || position >= count)
                    return;
                if (mFilterSelPos == position)
                    return;
                mFilterSelPos = position;
                removeAllFilterFx();
                mFilterView.setIntensitySeekBarMaxValue(100);
                mFilterView.setIntensitySeekBarProgress(100);
                if (position == 0) {
                    mFilterView.setIntensityLayoutVisible(View.INVISIBLE);
                    mVideoClipFxInfo.setFxMode(VideoClipFxInfo.FXMODE_BUILTIN);
                    mVideoClipFxInfo.setFxId(null);
                    return;
                }
                mFilterView.setIntensityLayoutVisible(View.VISIBLE);
                FilterItem filterItem = mFilterDataArrayList.get(position);
                int filterMode = filterItem.getFilterMode();
                if (filterMode == FilterItem.FILTERMODE_BUILTIN) {
                    String filterName = filterItem.getFilterName();

                    if (!TextUtils.isEmpty(filterName) && filterItem.getIsCartoon()) {
                        mBeauty_switch.setChecked(false);//删除美颜美颜开关关闭,若添加美颜则删除当前美颜

                        mCurCaptureVideoFx = mStreamingContext.appendBuiltinCaptureVideoFx("Cartoon");
                        mCurCaptureVideoFx.setBooleanVal("Stroke Only", filterItem.getStrokenOnly());
                        mCurCaptureVideoFx.setBooleanVal("Grayscale", filterItem.getGrayScale());

                    } else if (!TextUtils.isEmpty(filterName)) {
                        mCurCaptureVideoFx = mStreamingContext.appendBuiltinCaptureVideoFx(filterName);
                    }
                    mVideoClipFxInfo.setFxMode(VideoClipFxInfo.FXMODE_BUILTIN);
                    mVideoClipFxInfo.setFxId(filterName);
                } else {
                    String filterPackageId = filterItem.getPackageId();
                    if (!TextUtils.isEmpty(filterPackageId)) {
                        mCurCaptureVideoFx = mStreamingContext.appendPackagedCaptureVideoFx(filterPackageId);
                    }
                    mVideoClipFxInfo.setFxMode(VideoClipFxInfo.FXMODE_PACKAGE);
                    mVideoClipFxInfo.setFxId(filterPackageId);
                }

                mCurCaptureVideoFx.setFilterIntensity(1.0f);
            }

            @Override
            public void onMoreFilter() {
                Bundle bundle = new Bundle();
                bundle.putInt("titleResId", R.string.moreFilter);
                bundle.putInt("assetType", NvAsset.ASSET_FILTER);
                AppManager.getInstance().jumpActivityForResult(CaptureActivity.this, AssetDownloadActivity.class, bundle, REQUEST_FILTER_LIST_CODE);
                mFilterView.setMoreFilterClickable(false);
            }

            @Override
            public void onIntensity(int value) {
                if (mCurCaptureVideoFx != null) {
                    float intensity = value / (float) 100;
                    mCurCaptureVideoFx.setFilterIntensity(intensity);
                }
            }
        });
    }

    //道具
    private void initFacUPropDataList() {
        mPropDataArrayList.clear();
        //先初始化道具数据数据
        ArrayList<NvAsset> faceULocalDataList = getLocalData(NvAsset.ASSET_FACE1_STICKER);
        ArrayList<NvAsset> faceUBundleDataList = getLocalData(NvAsset.ASSET_FACE_BUNDLE_STICKER);
        mPropDataArrayList = AssetFxUtil.getFaceUDataList(faceULocalDataList, faceUBundleDataList);
    }

    private void initFacUPropDialog() {
        mFaceUPropDialog = new AlertDialog.Builder(this).create();
        mFaceUPropDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                closeCaptureDialogView(mFaceUPropDialog);
            }
        });
        mFaceUPropView = new FaceUPropView(this);

        //先设置道具数据
        mFaceUPropView.setPropDataArrayList(mPropDataArrayList);
        mFaceUPropView.initPropRecyclerView(this);
        mFaceUPropView.setFaceUPropListener(new FaceUPropView.OnFaceUPropListener() {
            @Override
            public void onItmeClick(View v, int position) {
                int count = mPropDataArrayList.size();
                if (position < 0 || position >= count)
                    return;
                if (mARFaceU == null)
                    return;
                if (mFaceUPropSelPos == position)
                    return;

                mFaceUPropSelPos = position;
                mFaceUPropName = mPropDataArrayList.get(position).getFilterName();
                Log.e("===>", "ooooo: " + mFaceUPropName);
                mARFaceU.setStringVal("Face Ornament", position != 0 ? mFaceUPropName : "");
            }

            @Override
            public void onMoreFaceUProp() {
                mFaceUPropView.setMoreFaceUPropClickable(false);
                Bundle bundle = new Bundle();
                bundle.putInt("titleResId", R.string.moreFaceU);
                bundle.putInt("assetType", NvAsset.ASSET_FACE1_STICKER);
                AppManager.getInstance().jumpActivityForResult(CaptureActivity.this, AssetDownloadActivity.class, bundle, ARFACE_LIST_REQUES_CODE);
            }
        });
    }

    private void initShapeRecyclerView() {
        mShapeAdapter = new ShapeAdapter(this, getShapeDataList());
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        mBeautyShapeRecyclerView.setLayoutManager(linearLayoutManager);
        mBeautyShapeRecyclerView.setAdapter(mShapeAdapter);
        int space = ScreenUtils.dip2px(this, 8);
        mBeautyShapeRecyclerView.addItemDecoration(new SpaceItemDecoration(space, 0));
        mShapeAdapter.setOnItemClickListener(new ShapeAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                hiddenAllSeekBars();
                mLevel.setVisibility(View.VISIBLE);
                mCurBeautyShapeId = getShapeDataList().get(position).shapeId;
                double level = mARFaceU.getFloatVal(mCurBeautyShapeId) * 100;
                mLevel.setProgress((int) level);
            }
        });
    }

    private ArrayList<ShapeDataItem> getShapeDataList() {
        ArrayList<ShapeDataItem> list = new ArrayList<>();

        ShapeDataItem cheek_thinning = new ShapeDataItem();
        cheek_thinning.name = getResources().getString(R.string.cheek_thinning);
        cheek_thinning.resId = R.mipmap.cheek_thinning;
        cheek_thinning.type = "Default";
        cheek_thinning.shapeId = BEAUTY_SHAPE_CHECK_THINNING;
        list.add(cheek_thinning);

        ShapeDataItem eye_enlarging = new ShapeDataItem();
        eye_enlarging.name = getResources().getString(R.string.eye_enlarging);
        eye_enlarging.resId = R.mipmap.eye_enlarging;
        eye_enlarging.type = "Default";
        eye_enlarging.shapeId = BEAUTY_SHAPE_EYE_ENLARGING;
        list.add(eye_enlarging);

        ShapeDataItem intensity_forehead = new ShapeDataItem();
        intensity_forehead.name = getResources().getString(R.string.intensity_forehead);
        intensity_forehead.resId = R.mipmap.intensity_forehead;
        intensity_forehead.type = "Custom";
        intensity_forehead.shapeId = BEAUTY_SHAPE_INTENSITY_FORHEAD;
        list.add(intensity_forehead);

        ShapeDataItem intensity_chin = new ShapeDataItem();
        intensity_chin.name = getResources().getString(R.string.intensity_chin);
        intensity_chin.resId = R.mipmap.intensity_chin;
        intensity_chin.shapeId = BEAUTY_SHAPE_INTENSITY_CHIN;
        intensity_chin.type = "Custom";
        list.add(intensity_chin);

        ShapeDataItem intensity_nose = new ShapeDataItem();
        intensity_nose.name = getResources().getString(R.string.intensity_nose);
        intensity_nose.resId = R.mipmap.intensity_nose;
        intensity_nose.type = "Custom";
        intensity_nose.shapeId = BEAUTY_SHAPE_INTENSITY_NOSE;
        list.add(intensity_nose);

        ShapeDataItem intensity_mouth = new ShapeDataItem();
        intensity_mouth.name = getResources().getString(R.string.intensity_mouth);
        intensity_mouth.resId = R.mipmap.intensity_mouth;
        intensity_mouth.type = "Custom";
        intensity_mouth.shapeId = BEAUTY_SHAPE_INTENSITY_MOUTH;
        list.add(intensity_mouth);

        return list;
    }

    private void beautySeekEnabled(Boolean isEnabled) {
        mStrength.setEnabled(isEnabled);
        mStrength.setClickable(isEnabled);
        mWhitening.setEnabled(isEnabled);
        mWhitening.setClickable(isEnabled);
        mReddening.setEnabled(isEnabled);
        mReddening.setClickable(isEnabled);
    }

    private void beautyShapeSeekEnabled(Boolean isEnabled) {
        mLevel.setEnabled(isEnabled);
        mLevel.setClickable(isEnabled);
        mBeautyShapeResetLayout.setEnabled(isEnabled);
        mBeautyShapeResetLayout.setClickable(isEnabled);
        mShapeAdapter.setEnable(isEnabled);
        if (isEnabled) {
            mBeautyShapeResetIcon.setAlpha(1f);
            mBeautyShapeResetTxt.setTextColor(Color.WHITE);
        } else {
            mBeautyShapeResetIcon.setAlpha(0.5f);
            mBeautyShapeResetTxt.setTextColor(getResources().getColor(R.color.ms_disable_color));
        }
    }

    private void initBeautyData() {
        mStrengthValue = 0;
        mWhiteningValue = 0;
        mReddeningValue = 0;
        NvsFxDescription fxDescription = mStreamingContext.getVideoFxDescription("Beauty");
        List<NvsFxDescription.ParamInfoObject> paramInfo = fxDescription.getAllParamsInfo();
        for (NvsFxDescription.ParamInfoObject param : paramInfo) {
            String paramName = param.getString("paramName");
            if (paramName.equals("Strength")) {
                double maxValue = param.getFloat("floatMaxVal");
                mStrengthValue = param.getFloat("floatDefVal");
                Log.e("mStrengthValue=", mStrengthValue + "");
                mStrength.setMax((int) (maxValue * 100));
                mStrength.setProgress((int) (mStrengthValue * 100));
            } else if (paramName.equals("Whitening")) {
                double maxValue = param.getFloat("floatMaxVal");
                mWhiteningValue = param.getFloat("floatDefVal");
                Log.e("mWhiteningValue=", mWhiteningValue + "");
                mWhitening.setMax((int) (maxValue * 100));
                mWhitening.setProgress((int) (mWhiteningValue * 100));
            } else if (paramName.equals("Reddening")) {
                double maxValue = param.getFloat("floatMaxVal");
                mReddeningValue = param.getFloat("floatDefVal");
                Log.e("mReddeningValue=", mReddeningValue + "");
                mReddening.setMax((int) (maxValue * 100));
                mReddening.setProgress((int) (mReddeningValue * 100));
            }
        }

        //  人脸特效是否可用
        if (mCanUseARFace) {
            mARFaceU = mStreamingContext.appendBuiltinCaptureVideoFx("Face Effect");
            mARFaceU.setStringVal("Beautification Package", "assets:/NvBeautification.asset");
            if (mARFaceU != null) {
                mARFaceU.setMenuVal("Face Type", "");
                mARFaceU.setFloatVal("Face Shape Level", 0);
                resetBeautyShapeDefaultValue();
            }
        }
        mBeauty_switch.setChecked(true);
        beautySeekEnabled(true);
        mDefaultBeauty_sb.setProgress(0);
    }

    @Override
    protected void initTitle() {

    }

    @Override
    protected void initData() {
        Log.e(TAG,"initData");

        mAssetManager = NvAssetManager.sharedInstance();
        mAssetManager.searchLocalAssets(NvAsset.ASSET_FILTER);
        String bundlePath = "filter";
        mAssetManager.searchReservedAssets(NvAsset.ASSET_FILTER, bundlePath);

        mAssetManager.searchLocalAssets(NvAsset.ASSET_FACE1_STICKER);
        bundlePath = "arface";
        mAssetManager.searchReservedAssets(NvAsset.ASSET_FACE_BUNDLE_STICKER, bundlePath);

        mFocusAnimation = new AlphaAnimation(1.0f, 0.0f);
        mFocusAnimation.setDuration(1000);
        mFocusAnimation.setFillAfter(true);

        initBeautyData();
        //滤镜初始化
        initFilterList();
        initFilterDialog();
        //人脸道具初始化
        initFacUPropDataList();
        initFacUPropDialog();
        //美型初始化
        initShapeRecyclerView();

        mBeauty.setSelected(true);
        beautySeekEnabled(false);
        beautyShapeSeekEnabled(false);

    }

    @Override
    protected void initListener() {
        m_GLView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(m_GLView==null)
                    return false;
                if (touchTimes == 0) {
                    startTouchTime = System.nanoTime() / 1000000;
                    touchTimes++;
                } else {
                    long diffTimeMillis = System.nanoTime() / 1000000 - startTouchTime;
                    if(diffTimeMillis < 1500)
                    {
                        touchTimes++;
                    }
                    else
                    {
                        touchTimes=0;
                    }
                    if(touchTimes >= 4) {
                        if (!isShowLog) {
                            isShowLog = true;
                            mLogText.setVisibility(View.VISIBLE);
                            initTimer();
                        } else {
                            isShowLog = false;
                            mLogText.setVisibility(View.GONE);
                            stopTimer();
                        }
                        touchTimes = 0;
                    }
                }

                float rectHalfWidth = mImageAutoFocusRect.getWidth() / 2;
                if (event.getX() - rectHalfWidth >= 0 && event.getX() + rectHalfWidth <= m_GLView.getWidth()
                        && event.getY() - rectHalfWidth >= 0 && event.getY() + rectHalfWidth <= m_GLView.getHeight()) {
                    mImageAutoFocusRect.setX(event.getX() - rectHalfWidth);
                    mImageAutoFocusRect.setY(event.getY() - rectHalfWidth);
                    RectF rectFrame = new RectF();
                    rectFrame.set(mImageAutoFocusRect.getX(), mImageAutoFocusRect.getY(),
                            mImageAutoFocusRect.getX() + mImageAutoFocusRect.getWidth(),
                            mImageAutoFocusRect.getY() + mImageAutoFocusRect.getHeight());
                    //启动自动聚焦
                    mImageAutoFocusRect.startAnimation(mFocusAnimation);
                    if (m_supportAutoFocus)
                        mStreamingContext.startAutoFocus(new RectF(rectFrame));
                }
                return false;
            }
        });
        /*变焦调节*/
        mZoomSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            private boolean startTracking = false;

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (startTracking) {
                    if (mCaptureType == CAPTURE_TYPE_ZOOM)
                        mStreamingContext.setZoom(progress);//设置缩放比例
                }

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                startTracking = true;
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                startTracking = false;
            }
        });
        /*曝光补偿调节*/
        mExposeSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (mCaptureType == CAPTURE_TYPE_EXPOSE) {
                    mStreamingContext.setExposureCompensation(progress + mMinExpose);//设置曝光补偿
                    mSeekProgress.setText(progress + mMinExpose + "");
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        mCloseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mStreamingContext.removeAllCaptureVideoFx();
                if(isConnected){
                    mPublisher.stopRecord();
                    mPublisher.stopPublish();
                }
                mStreamingContext.connectCapturePreviewWithSurfaceTexture(null);
                if (mStreamingContext != null) {
                    mStreamingContext.stop();
                }
                stopTimer();
                finish();
            }
        });
        /*切换摄像头*/
        mSwitchFacingLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mIsSwitchingCamera) {
                    return;
                }
                if (mCurrentDeviceIndex == 0) {
                    mCurrentDeviceIndex = 1;
                    mFlashLayout.setEnabled(false);
                    mFlashButton.setImageResource(R.mipmap.icon_flash_off);
                    mFlashButton.setImageAlpha(128);
                } else {
                    mCurrentDeviceIndex = 0;
                    mFlashLayout.setEnabled(true);
                    mFlashButton.setImageResource(R.mipmap.icon_flash_off);
                    mFlashButton.setImageAlpha(255);
                }

                mIsSwitchingCamera = true;
                startCapturePreview(true);

//                Log.e(TAG, "mSwitchFacingLayout.setOnClickListener ");
//                if (mIsSwitchingCamera) {
//                    return;
//                }
//                if ((mCameraId%2) == 0) {
//                    mFlashLayout.setEnabled(false);
//                    mFlashButton.setImageResource(R.mipmap.icon_flash_off);
//                    mFlashButton.setImageAlpha(128);
//                } else {
//                    mFlashLayout.setEnabled(true);
//                    mFlashButton.setImageResource(R.mipmap.icon_flash_off);
//                    mFlashButton.setImageAlpha(255);
//                }
//
//                mIsSwitchingCamera = true;
//                mCameraId+=1;
//                switchCamera(mCameraId);
            }
        });
        /*切换软硬编码*/
        mSwitchEncoderLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "mSwitchEncoderLayout.setOnClickListener ");
                if (mPublisher.isSoftEncoder()) {
                    Toast.makeText(CaptureActivity.this,"编码 状态："+"硬编码",Toast.LENGTH_LONG).show();
                    mPublisher.switchToHardEncoder();
                } else {
                    Toast.makeText(CaptureActivity.this,"编码 状态："+"软编码",Toast.LENGTH_LONG).show();
                    mPublisher.switchToSoftEncoder();
                }
            }
        });
        /*闪光灯*/
        mFlashLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mStreamingContext.isFlashOn()) {
                    mStreamingContext.toggleFlash(false);
                    mFlashButton.setImageResource(R.mipmap.icon_flash_off);
                    mFlashButton.setImageAlpha(255);
                } else {
                    mStreamingContext.toggleFlash(true);
                    mFlashButton.setImageResource(R.mipmap.icon_flash_on);
                    mFlashButton.setImageAlpha(255);
                }
            }
        });
        /*变焦*/
        mZoomLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCaptureType = CAPTURE_TYPE_ZOOM;
                mSeekTitle.setText(R.string.change_zoo);
                mSeekProgress.setVisibility(View.INVISIBLE);
                mZoomSeekbar.setVisibility(View.VISIBLE);
                mExposeSeekbar.setVisibility(View.INVISIBLE);
                showCaptureDialogView(mCaptureZoomAndExposeDialog, mZoomView);
            }
        });
        /*曝光补偿*/
        mExposureLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCaptureType = CAPTURE_TYPE_EXPOSE;
                mSeekTitle.setText(R.string.exposure_compensation);
                mSeekProgress.setVisibility(View.VISIBLE);
                mSeekProgress.setText(mExposeSeekbar.getProgress() + mMinExpose + "");
                mZoomSeekbar.setVisibility(View.INVISIBLE);
                mExposeSeekbar.setVisibility(View.VISIBLE);
                showCaptureDialogView(mCaptureZoomAndExposeDialog, mZoomView);
            }
        });
        /*美颜*/
        mBeautyLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showCaptureDialogView(mCaptureBeautyDialog, mBeautyView);
            }
        });

        mBeautyShapeResetLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resetBeautyShapeDefaultValue();
                mLevel.setProgress(0);
                mShapeAdapter.setSelectPos(Integer.MAX_VALUE);
                hiddenAllSeekBars();
                mCurBeautyShapeId = BEAUTY_SHAPE_CHECK_THINNING;
            }
        });

        /*滤镜*/
        mFilterLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showCaptureDialogView(mFilterDialog, mFilterView);
            }
        });
        /*道具*/
        mFuLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mCanUseARFace) {
                    showCaptureDialogView(mFaceUPropDialog, mFaceUPropView);
                } else {
                    Util.showDialog(CaptureActivity.this, getResources().getString(R.string.tips_head), getResources().getString(R.string.tips_body));
                }
            }
        });

        /*录制*/
        mOpenRecordLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "mOpenRecordLayout.setOnClickListener ");
                if (!isRecording) {
                    isRecording = true;
                    mOpenRecordLayout.getChildAt(0).setBackgroundColor(Color.RED);
                    mOpenRecordLayout.getChildAt(0).setBackground(getDrawable(R.drawable.start_record_style));

                    Toast.makeText(CaptureActivity.this,"录制 状态："+"开始录制",Toast.LENGTH_LONG).show();
                    mPublisher.startRecord(recPath);
                } else {
                    isRecording = false;
                    mOpenRecordLayout.getChildAt(0).setBackgroundColor(Color.TRANSPARENT);

                    Toast.makeText(CaptureActivity.this,"编码 状态："+"停止录制"+recPath,Toast.LENGTH_LONG).show();
                    mPublisher.stopRecord();
                }
            }
        });

        capture_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(isConnecting)
                {
                    Toast.makeText(CaptureActivity.this,"推流 状态："+"正在连接，稍等！",Toast.LENGTH_LONG).show();
                    return;
                }
                if(!isConnected) {
                    mSwitchEncoderLayout.setEnabled(false);
                    mSwitchEncoderLayout.getChildAt(0).setAlpha((float) 0.4);
                    mOpenRecordLayout.setEnabled(true);
                    mOpenRecordLayout.getChildAt(0).setAlpha((float) 1);
                    isConnecting =true;

                    rtmpUrl = rtmpUrl_edit.getText().toString();
                    SharedPreferences.Editor editor = sp.edit();
                    editor.putString("rtmpUrl", rtmpUrl);
                    editor.apply();

                    mPublisher.startAudioRecord();
                    mPublisher.startPublish(rtmpUrl);

                    capture_btn.setText("结束推流");
                    capture_btn.setTextColor(Color.RED);
                    capture_btn.setClickable(false);
                    isRightUrl = false;
                }
                else
                {
                    mSwitchEncoderLayout.setEnabled(true);
                    mSwitchEncoderLayout.getChildAt(0).setAlpha((float) 1);

                    if(isRecording&&(mPublisher!=null)) {
                        isRecording = false;
                        mOpenRecordLayout.getChildAt(0).setBackgroundColor(Color.TRANSPARENT);
                        mOpenRecordLayout.getChildAt(0).setAlpha((float) 1);
                        Toast.makeText(CaptureActivity.this, "编码 状态：" + "停止录制" + recPath, Toast.LENGTH_LONG).show();
                        mPublisher.stopRecord();
                    }

                    mOpenRecordLayout.setEnabled(false);
                    mOpenRecordLayout.getChildAt(0).setAlpha((float) 0.4);

                    isConnected=false;
                    mPublisher.stopAudioRecord();
                    mPublisher.stopPublish();
                    capture_btn.setText("开始推流");
                    capture_btn.setTextColor(Color.WHITE);
                    capture_btn.setClickable(false);
                    isRightUrl = true;
                }
            }
        });
    }

    /* 美颜dialog 动作监听*/
    private void beautyClickListener() {
        /*美颜*/
        mBeauty.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!mIsBeautyType) {
                    hiddenAllSeekBars();
                    if (mBeautySwitchIsOpend && mBeautyIndex >= 0 && mBeautyIndex <= 2) {
                        updateBeautyMenuStyle(mBeautyIndex);
                        // 显示对应seekbar
                        switch (mBeautyIndex) {
                            case 0:
                                mStrength.setVisibility(View.VISIBLE);
                                break;
                            case 1:
                                mWhitening.setVisibility(View.VISIBLE);
                                break;
                            case 2:
                                mReddening.setVisibility(View.VISIBLE);
                                break;
                        }
                    }
                    if (mBeautySwitchIsOpend && mBeautyIndex > 2 && mBeautyFx.getBooleanVal("Default Beauty Enabled")) {
                        mDefaultBeauty_sb.setVisibility(View.VISIBLE);
                    }
                    mIsBeautyType = true;
                    mBeauty.setSelected(true);
                    mBeauty_shape.setSelected(false);
                    mBeautySelect.setVisibility(View.VISIBLE);
                    mBeautyShapeSelect.setVisibility(View.GONE);
                    if (!mSharpenDefault) {
                        mSharpening_iv_close.setVisibility(View.VISIBLE);
                    } else {
                        mSharpening_iv_open.setVisibility(View.VISIBLE);
                    }
                    mDefaultBeauty_iv.setVisibility(View.VISIBLE);
                }
            }
        });
        /*美型*/
        mBeauty_shape.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mIsBeautyType) {
                    hiddenAllSeekBars();
                    if (mBeautyShapeSwitchIsOpen && mShapeAdapter.getSelectPos() >= 0 && mShapeAdapter.getSelectPos() <= mShapeAdapter.getItemCount()) {
                        mLevel.setVisibility(View.VISIBLE);
                    }
                    mIsBeautyType = false;
                    mBeauty.setSelected(false);
                    mBeauty_shape.setSelected(true);
                    mBeautySelect.setVisibility(View.GONE);
                    mBeautyShapeSelect.setVisibility(View.VISIBLE);
                    mSharpening_iv_close.setVisibility(View.GONE);
                    mSharpening_iv_open.setVisibility(View.GONE);
                    mDefaultBeauty_iv.setVisibility(View.INVISIBLE);
                }
            }
        });
        /*锐化关状态——点击*/
        mSharpening_iv_close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mSharpenDefault = true;
                mBeautyFx.setBooleanVal("Default Sharpen Enabled", true);
                mSharpening_iv_close.setVisibility(View.GONE);
                mSharpening_iv_open.setVisibility(View.VISIBLE);
                ToastUtil.showToastCenterNoBg(getApplicationContext(), getResources().getString(R.string.sharpen_open));
            }
        });
        /*锐化开状态——点击*/
        mSharpening_iv_open.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mSharpenDefault = false;
                mBeautyFx.setBooleanVal("Default Sharpen Enabled", false);
                mSharpening_iv_close.setVisibility(View.VISIBLE);
                mSharpening_iv_open.setVisibility(View.GONE);
                ToastUtil.showToastCenterNoBg(getApplicationContext(), getResources().getString(R.string.sharpen_close));
            }
        });
        /*基础美颜*/
        mDefaultBeauty_iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDefaultBeautyOpen = !mDefaultBeautyOpen;
                if (mBeautyFx.getBooleanVal("Default Beauty Enabled") && (mDefaultBeauty_sb.getVisibility() == View.VISIBLE)) {
                    mBeautyFx.setBooleanVal("Default Beauty Enabled", false);
                    ToastUtil.showToastCenterNoBg(getApplicationContext(), getResources().getString(R.string.default_beauty_close));
                    mDefaultBeauty_iv.setAlpha(0.4f);
                    mDefaultBeauty_sb.setVisibility(View.GONE);
                    hiddenAllSeekBars();
                    if (mBeautySwitchIsOpend && mBeautyIndex >= 0 && mBeautyIndex <= 2) {
                        // 显示对应seekbar
                        switch (mBeautyIndex) {
                            case 0:
                                mStrength.setVisibility(View.VISIBLE);
                                break;
                            case 1:
                                mWhitening.setVisibility(View.VISIBLE);
                                break;
                            case 2:
                                mReddening.setVisibility(View.VISIBLE);
                                break;
                        }
                    }
                    return;
                }
                if (mBeautyFx.getBooleanVal("Default Beauty Enabled") && (mDefaultBeauty_sb.getVisibility() == View.GONE)) {
                    hiddenAllSeekBars();
                    mDefaultBeauty_sb.setVisibility(View.VISIBLE);
                }
                if (!mBeautyFx.getBooleanVal("Default Beauty Enabled") && (mDefaultBeauty_sb.getVisibility() == View.GONE)) {
                    mBeautyFx.setBooleanVal("Default Beauty Enabled", true);
                    ToastUtil.showToastCenterNoBg(getApplicationContext(), getResources().getString(R.string.default_beauty_open));
                    mDefaultBeauty_iv.setAlpha(1.0f);
                    hiddenAllSeekBars();
                    mDefaultBeauty_sb.setVisibility(View.VISIBLE);
                }
            }
        });
        /*美颜*/
        mBeauty_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mBeautySwitchIsOpend = isChecked;
                if (isChecked) {
                    mSharpening_iv_close.setEnabled(true);
                    if (mSharpening_iv_close.getVisibility() == View.GONE)
                        mSharpening_iv_close.setVisibility(View.VISIBLE);
                    mSharpening_iv_open.setEnabled(true);
                    mDefaultBeauty_iv.setEnabled(true);
                    mDefaultBeauty_iv.setAlpha(1.0f);
                    mStrengthMenu_ll.setEnabled(true);
                    mWhiteningMenu_ll.setEnabled(true);
                    mReddeningMenu_ll.setEnabled(true);
                    mStrengthMenu_ll.setAlpha(1.0f);
                    mWhiteningMenu_ll.setAlpha(1.0f);
                    mReddeningMenu_ll.setAlpha(1.0f);
                    //添加美颜采集特效
                    mBeautyFx = mStreamingContext.appendBeautyCaptureVideoFx();
                    mBeautyFx.setBooleanVal("Default Sharpen Enabled", mSharpenDefault);
                    mBeautyFx.setFloatVal("Strength", mStrengthValue);//设置美颜强度值
                    mBeautyFx.setFloatVal("Whitening", mWhiteningValue);
                    mBeautyFx.setFloatVal("Reddening", mReddeningValue);
                    // 基础滤镜强度
                    mDefaultBeautyIntensity = mBeautyFx.getFloatVal("Default Intensity");
                    mDefaultBeauty_sb.setProgress((int) (mDefaultBeautyIntensity * 100));
                    boolean ret = removeFilterFxByName("Cartoon");
                    if (ret) {
                        mFilterView.setSelectedPos(0);
                        mFilterView.notifyDataSetChanged();
                    }
                    mBeauty_switch_text.setText(R.string.beauty_close);
                    mDefaultBeauty_sb.setVisibility(View.VISIBLE);
                } else {
                    // 重置索引位置
                    mBeautyIndex = 3;
                    if (mBeauty.isSelected()) {
                        mSharpening_iv_close.setEnabled(false);
                        mSharpening_iv_close.setVisibility(View.VISIBLE);
                        mSharpening_iv_open.setEnabled(false);
                        mSharpening_iv_open.setVisibility(View.GONE);
                        mDefaultBeauty_iv.setEnabled(false);
                    }
                    if (mBeauty_shape.isSelected()) {
                        mSharpening_iv_close.setEnabled(false);
                        mSharpening_iv_close.setVisibility(View.GONE);
                        mSharpening_iv_open.setEnabled(false);
                        mSharpening_iv_open.setVisibility(View.GONE);
                        mDefaultBeauty_iv.setEnabled(false);
                    }
                    updateBeautyMenuStyle(5);
                    mDefaultBeauty_iv.setAlpha(0.4f);
                    mStrengthMenu_ll.setEnabled(false);
                    mWhiteningMenu_ll.setEnabled(false);
                    mReddeningMenu_ll.setEnabled(false);
                    mStrengthMenu_ll.setAlpha(0.5f);
                    mWhiteningMenu_ll.setAlpha(0.5f);
                    mReddeningMenu_ll.setAlpha(0.5f);
                    hiddenBeautySeekBars();
                    mSharpenDefault = false;
                    mBeauty_switch_text.setText(R.string.beauty_open);
                    removeFilterFxByName("Beauty");
                    mBeautyFx = null;
                }
                mBeauty_switch.setChecked(isChecked);
                beautySeekEnabled(isChecked);
            }
        });
        /*基础滤镜seekbar*/
        mDefaultBeauty_sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mDefaultBeautyIntensity = progress * 1.0 / 100;
                mBeautyFx.setFloatVal("Default Intensity", mDefaultBeautyIntensity);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        /*磨皮按钮*/
        mStrengthMenu_ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mBeautyIndex = 0;
                hiddenAllSeekBars();
                mStrength.setVisibility(View.VISIBLE);
                updateBeautyMenuStyle(0);
                beautySeekEnabled(true);
            }
        });
        /*磨皮*/
        mStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mStrengthValue = progress * 0.01;
                if (mBeautyFx != null) {
                    mBeautyFx.setFloatVal("Strength", mStrengthValue);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        /*美白按钮*/
        mWhiteningMenu_ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mBeautyIndex = 1;
                hiddenAllSeekBars();
                mWhitening.setVisibility(View.VISIBLE);
                updateBeautyMenuStyle(1);
                beautySeekEnabled(true);
            }
        });
        /*美白*/
        mWhitening.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mWhiteningValue = progress * 0.01;
                if (mBeautyFx != null) {
                    mBeautyFx.setFloatVal("Whitening", mWhiteningValue);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        /*红润按钮*/
        mReddeningMenu_ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mBeautyIndex = 2;
                hiddenAllSeekBars();
                mReddening.setVisibility(View.VISIBLE);
                updateBeautyMenuStyle(2);
                beautySeekEnabled(true);
            }
        });
        /*红润*/
        mReddening.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mReddeningValue = progress * 0.01;

                if (mBeautyFx != null) {
                    mBeautyFx.setFloatVal("Reddening", mReddeningValue);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        // 美型开关
        mBeauty_shape_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mBeautyShapeSwitchIsOpen = isChecked;
                if (!mCanUseARFace) {
                    mBeauty_shape_switch.setChecked(false);
                    Util.showDialog(CaptureActivity.this, getResources().getString(R.string.tips_head), getResources().getString(R.string.tips_body));
                } else {
                    if (isChecked) {
                        mARFaceU.setMenuVal("Face Type", "Custom");
                        mARFaceU.setFloatVal("Face Shape Level", 4);
                        mBeauty_shape_switch_text.setText(R.string.beauty_shape_close);
                    } else {
                        hiddenAllSeekBars();
                        mARFaceU.setFloatVal("Face Shape Level", 0);
                        mBeauty_shape_switch_text.setText(R.string.beauty_shape_open);
                        mShapeAdapter.setSelectPos(Integer.MAX_VALUE);
                    }
                    mBeauty_shape_switch.setChecked(isChecked);
                    beautyShapeSeekEnabled(isChecked);
                }
            }
        });

        /*程度*/
        mLevel.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (mARFaceU == null) {
                    return;
                }
                mLevelValue = ((float) progress) / ((float) 100);
                Log.e("===>", "level: " + mLevelValue);
                mARFaceU.setFloatVal(mCurBeautyShapeId, mLevelValue);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    private void updateBeautyMenuStyle(int beautyMenuIndex) {
        mStrength_bg.setBackgroundResource(0);
        mWhitening_bg.setBackgroundResource(0);
        mReddening_bg.setBackgroundResource(0);
        switch (beautyMenuIndex) {
            case 0:
                mStrength_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_selected);
                mWhitening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mReddening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mStrength_tv.setTextColor(Color.parseColor("#4A90E2"));
                mWhitening_tv.setTextColor(Color.WHITE);
                mReddening_tv.setTextColor(Color.WHITE);
                break;
            case 1:
                mStrength_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mWhitening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_selected);
                mReddening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mStrength_tv.setTextColor(Color.WHITE);
                mWhitening_tv.setTextColor(Color.parseColor("#4A90E2"));
                mReddening_tv.setTextColor(Color.WHITE);
                break;
            case 2:
                mStrength_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mWhitening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mReddening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_selected);
                mStrength_tv.setTextColor(Color.WHITE);
                mWhitening_tv.setTextColor(Color.WHITE);
                mReddening_tv.setTextColor(Color.parseColor("#4A90E2"));
                break;
            default:
                mStrength_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mWhitening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mReddening_bg.setBackgroundResource(R.drawable.beauty_shape_border_shape_default);
                mStrength_tv.setTextColor(Color.WHITE);
                mWhitening_tv.setTextColor(Color.WHITE);
                mReddening_tv.setTextColor(Color.WHITE);
                break;
        }
    }

    private void hiddenBeautySeekBars() {
        if (mDefaultBeauty_sb.getVisibility() == View.VISIBLE) {
            mDefaultBeauty_sb.setVisibility(View.GONE);
        }
        if (mStrength.getVisibility() == View.VISIBLE) {
            mStrength.setVisibility(View.GONE);
        }
        if (mWhitening.getVisibility() == View.VISIBLE) {
            mWhitening.setVisibility(View.GONE);
        }
        if (mReddening.getVisibility() == View.VISIBLE) {
            mReddening.setVisibility(View.GONE);
        }
    }

    private void hiddenAllSeekBars() {
        if (mDefaultBeauty_sb.getVisibility() == View.VISIBLE) {
            mDefaultBeauty_sb.setVisibility(View.GONE);
        }
        if (mStrength.getVisibility() == View.VISIBLE) {
            mStrength.setVisibility(View.GONE);
        }
        if (mWhitening.getVisibility() == View.VISIBLE) {
            mWhitening.setVisibility(View.GONE);
        }
        if (mReddening.getVisibility() == View.VISIBLE) {
            mReddening.setVisibility(View.GONE);
        }
        if (mLevel.getVisibility() == View.VISIBLE) {
            mLevel.setVisibility(View.GONE);
        }
    }

    private void resetBeautyShapeDefaultValue() {
        mARFaceU.setFloatVal(BEAUTY_SHAPE_EYE_ENLARGING, 0f);
        mARFaceU.setFloatVal(BEAUTY_SHAPE_CHECK_THINNING, 0f);
        mARFaceU.setFloatVal(BEAUTY_SHAPE_INTENSITY_FORHEAD, NORMAL_VELUE_INTENSITY_FORHEAD);
        mARFaceU.setFloatVal(BEAUTY_SHAPE_INTENSITY_CHIN, NORMAL_VELUE_INTENSITY_CHIN);
        mARFaceU.setFloatVal(BEAUTY_SHAPE_INTENSITY_NOSE, 0f);
        mARFaceU.setFloatVal(BEAUTY_SHAPE_INTENSITY_MOUTH, NORMAL_VELUE_INTENSITY_MOUTH);
    }

    private void removeAllFilterFx() {
        List<Integer> remove_list = new ArrayList<>();
        for (int i = 0; i < mStreamingContext.getCaptureVideoFxCount(); i++) {
            NvsCaptureVideoFx fx = mStreamingContext.getCaptureVideoFxByIndex(i);
            if (fx == null)
                continue;

            String name = fx.getBuiltinCaptureVideoFxName();
            if (name != null && !name.equals("Beauty") && !name.equals("Face Effect")) {
                remove_list.add(i);
                Log.e("===>", "fx name: " + name);
            }
        }
        if (!remove_list.isEmpty()) {
            for (int i = 0; i < remove_list.size(); i++) {
                mStreamingContext.removeCaptureVideoFx(remove_list.get(i));
            }
        }
    }

    private boolean removeFilterFxByName(String name) {
        for (int i = 0; i < mStreamingContext.getCaptureVideoFxCount(); i++) {
            NvsCaptureVideoFx fx = mStreamingContext.getCaptureVideoFxByIndex(i);
            if (fx.getDescription().getName().equals(name)) {
                mStreamingContext.removeCaptureVideoFx(i);
                return true;
            }
        }
        return false;
    }

    /**
     * 显示窗口
     */
    private void showCaptureDialogView(AlertDialog dialog, View view) {
        TranslateAnimation translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF, 1.0f);

        translate.setDuration(200);//动画时间500毫秒
        translate.setFillAfter(false);//动画出来控件可以点击
        mStartLayout.startAnimation(translate);
        dialog.show();
        dialog.setContentView(view);
        dialog.setCanceledOnTouchOutside(true);
        WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
        params.width = WindowManager.LayoutParams.MATCH_PARENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
        dialog.getWindow().setGravity(Gravity.BOTTOM);
        params.dimAmount = 0.0f;
        dialog.getWindow().setAttributes(params);
        dialog.getWindow().setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.colorTranslucent));
        dialog.getWindow().setWindowAnimations(R.style.fx_dlg_style);
        isShowCaptureButton(false);
    }

    /**
     * 关闭窗口
     */
    private void closeCaptureDialogView(AlertDialog dialog) {
        dialog.dismiss();
        TranslateAnimation translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF,
                1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        translate.setDuration(300);//动画时间300毫秒
        translate.setFillAfter(false);//动画出来控件可以点击
        mStartLayout.setAnimation(translate);
        isShowCaptureButton(true);
    }

    private void startPermissionsActivity(int code, String... permission) {
        PermissionsActivity.startActivityForResult(this, code, permission);
    }

    private int getCodeInPermission(String permission) {
        int code = 0;
        if (permission.equals(Manifest.permission.CAMERA)) {
            code = REQUEST_CAMERA_PERMISSION_CODE;
        } else if (permission.equals(Manifest.permission.RECORD_AUDIO)) {
            code = REQUEST_RECORD_AUDIO_PERMISSION_CODE;
        } else if (permission.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            code = REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_CODE;
        }
        return code;
    }

    // 获取当前引擎状态
    private int getCurrentEngineState() {
        return mStreamingContext.getStreamingEngineState();
    }

    private void updateSettingsWithCapability(int deviceIndex) {
        //获取采集设备能力描述对象，设置自动聚焦，曝光补偿，缩放
        mCapability = mStreamingContext.getCaptureDeviceCapability(deviceIndex);
        if (null == mCapability) {
            return;
        }

        //是否支持闪光灯
        if (mCapability.supportFlash) {
            mFlashLayout.setEnabled(true);
        }

        m_supportAutoFocus = mCapability.supportAutoFocus;

        // 是否支持缩放
        if (mCapability.supportZoom) {
            mZoomValue = mCapability.maxZoom;
            mZoomSeekbar.setMax(mZoomValue);
            mZoomSeekbar.setProgress(mStreamingContext.getZoom());
            mZoomSeekbar.setEnabled(true);
        } else {
            Log.e(TAG, "该设备不支持缩放");
        }

        // 是否支持曝光补偿
        if (mCapability.supportExposureCompensation) {
            mMinExpose = mCapability.minExposureCompensation;
            mExposeSeekbar.setMax(mCapability.maxExposureCompensation - mMinExpose);
            mExposeSeekbar.setProgress(mStreamingContext.getExposureCompensation() - mMinExpose);
            mExposeSeekbar.setEnabled(true);
        }
    }

    private void isShowCaptureButton(boolean isShow) {
        int show;
        if (isShow) {
            show = View.VISIBLE;
        } else {
            show = View.INVISIBLE;
        }
        if (show == View.VISIBLE) {
            mCloseButton.requestLayout();
            mFunctionButtonLayout.requestLayout();
            mStartLayout.requestLayout();
//            mRecordTime.requestLayout();
        }
        mCloseButton.setVisibility(show);
        mFunctionButtonLayout.setVisibility(show);
        mStartLayout.setVisibility(show);
//        mRecordTime.setVisibility(show);
    }

    private ArrayList<NvAsset> getLocalData(int assetType) {
        return mAssetManager.getUsableAssets(assetType, NvAsset.AspectRatio_All, 0);
    }


    @Override
    public void onClick(View view) {
    }

    @Override
    public void onCaptureDeviceCapsReady(int captureDeviceIndex) {
        if (mCurrentDeviceIndex != captureDeviceIndex) {
            return;
        }
        updateSettingsWithCapability(captureDeviceIndex);
    }

    @Override
    public void onCaptureDevicePreviewResolutionReady(int i) {
        NvsSize size = mStreamingContext.getCapturePreviewVideoSize(i);
        imageWidth = size.width;
        imageHeight = size.height;

        int ratio = (viewWidth*imageHeight)/(viewHeight*imageWidth);
        if(ratio <= 0){
            viewWidth = viewHeight*imageWidth/imageHeight;
            viewPortX = -(viewWidth - orgViewWidth)/2;
        }else{
            viewHeight = viewWidth*imageHeight/imageWidth;
            viewPortY = -(viewHeight - orgViewHeight)/2;
        }

        Log.e(TAG, "size: " + size.width + ", " + size.height);

    }

    @Override
    public void onCaptureDevicePreviewStarted(int i) {
        mIsSwitchingCamera = false;
        Log.e(TAG, "onCaptureDevicePreviewStarted ");
    }

    @Override
    public void onCaptureDeviceError(int i, int i1) {

    }

    @Override
    public void onCaptureDeviceStopped(int i) {

    }

    @Override
    public void onCaptureDeviceAutoFocusComplete(int i, boolean b) {

    }

    @Override
    public void onCaptureRecordingFinished(int i) {

    }

    @Override
    public void onCaptureRecordingError(int i) {

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.e(TAG,"onActivityResult");
        super.onActivityResult(requestCode, resultCode, data);
        switch (resultCode) {
            case PermissionsActivity.PERMISSIONS_DENIED:
                mBuilderPermission = new Dialog(CaptureActivity.this, R.style.dialogTransparent);
                mPermissionDialog = (RelativeLayout) getLayoutInflater().inflate(R.layout.capture_permission_dialog, null);
                mOk = (TextView) mPermissionDialog.findViewById(R.id.ok);
                mBuilderPermission.setContentView(mPermissionDialog);
                mOk.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mBuilderPermission.dismiss();
                        finish();
                    }
                });

                mBuilderPermission.show();
                break;
            case PermissionsActivity.PERMISSIONS_GRANTED:
                if (requestCode == REQUEST_CAMERA_PERMISSION_CODE) {
                    if (mAllRequestPermission.size() == 1) {
                        mPermissionGranted = true;
                        startCapturePreview(false);
                    } else {
                        int code = getCodeInPermission(mAllRequestPermission.get(mAllRequestPermission.size() - 1));
                        startPermissionsActivity(code, mAllRequestPermission.get(mAllRequestPermission.size() - 1));
                    }
                }
                if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION_CODE || requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_CODE) {
                    mPermissionGranted = true;
                    startCapturePreview(false);
                }
                break;
            case RESULT_OK:
                if (requestCode == REQUEST_FILTER_LIST_CODE) {
                    initFilterList();
                    mFilterView.setFilterArrayList(mFilterDataArrayList);
                    mFilterSelPos = AssetFxUtil.getSelectedFilterPos(mFilterDataArrayList, mVideoClipFxInfo);
                    mFilterView.setSelectedPos(mFilterSelPos);
                    mFilterView.notifyDataSetChanged();
                } else if (requestCode == ARFACE_LIST_REQUES_CODE) {
                    initFacUPropDataList();
                    mFaceUPropView.setPropDataArrayList(mPropDataArrayList);
                    mFaceUPropSelPos = AssetFxUtil.getSelectedFaceUPropPos(mPropDataArrayList, mFaceUPropName);
                    mFaceUPropView.setSelectedPos(mFaceUPropSelPos);
                    mFaceUPropView.notifyDataSetChanged();
                }
                break;
            default:
                break;
        }
    }

    @Override
    protected void onDestroy() {
        Log.e(TAG, "onDestroy");

        if(isRecording&&(mPublisher!=null)) {
            isRecording = false;
            mOpenRecordLayout.getChildAt(0).setBackgroundColor(Color.TRANSPARENT);
            mOpenRecordLayout.getChildAt(0).setAlpha((float) 1);
            Toast.makeText(CaptureActivity.this, "编码 状态：" + "停止录制"+recPath, Toast.LENGTH_LONG).show();
            mPublisher.stopRecord();
            mOpenRecordLayout.setEnabled(false);
            mOpenRecordLayout.getChildAt(0).setAlpha((float) 0.4);
        }
        if(isConnected&&(mPublisher!=null)) {
            mSwitchEncoderLayout.setEnabled(true);
            mSwitchEncoderLayout.getChildAt(0).setAlpha((float) 1);
            isConnected = false;
            isRecording =false;
//            disableEncoding();
            mPublisher.stopPublish();
            capture_btn.setText("开始推流");
            capture_btn.setTextColor(Color.WHITE);
        }
        mPublisher.stopAudioRecord();
        mPublisher.release();
        m_GLView = null;
        mSurface = null;
        mPublisher=null;
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        Log.e(TAG, "onResume");
        super.onResume();
        if (mPermissionsChecker == null) {
            mPermissionsChecker = new PermissionsChecker(this);
        }
        mFilterView.setMoreFilterClickable(true);
        mFaceUPropView.setMoreFaceUPropClickable(true);
        if(m_GLView!=null)
            m_GLView.onResume();
        if(mPublisher!=null)
            mPublisher.resumeRecord();
    }

    @Override
    protected void onPause() {
        Log.e(TAG, "onPause");
        super.onPause();
        isEGLStoped = true;
        if(mPublisher!=null)
            mPublisher.pauseRecord();
        mStreamingContext.connectCapturePreviewWithSurfaceTexture(null);
        if (mSurface != null)
            mSurface.setOnFrameAvailableListener(null);
        mStreamingContext.stop();
        if(m_GLView!=null) {
            m_GLView.onPause();
        }
    }

    @Override
    protected void onStop() {
        Log.e(TAG, "onStop");
        super.onStop();
        if (mStreamingContext != null) {
            mStreamingContext.stop();
        }
    }

    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        if(m_GLView==null||mSurface ==null)
            return;
//        Log.e(TAG, "onFrameAvailable");
        m_GLView.queueEvent(

                new Runnable() {
                    @Override
                    public synchronized void run()
                    {
                        if(!isEGLStoped) {
                            mSurface.updateTexImage();
                            mSurface.getTransformMatrix(mSTMatrix);
                            DownloadImageFromTexture2();
                        }
                    }
                });

        m_GLView.requestRender();
    }

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        Log.e(TAG, "onSurfaceCreated");
        GLES20.glClearColor(0, 0, 0, 1);
        Matrix.setIdentityM(mMVPMatrix, 0);

        mTriangleVertices = ByteBuffer.allocateDirect(
                mTriangleVerticesData.length * FLOAT_SIZE_BYTES)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        mTriangleVertices.put(mTriangleVerticesData).position(0);

        mProgram = createProgram(mVertexShader, mFragmentShader);
        if (mProgram == 0)
            return;

        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
        checkGLError("glGetAttribLocation aPosition");
        if (maPositionHandle == -1)
            return;

        maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
        checkGLError("glGetAttribLocation aTextureCoord");
        if (maTextureHandle == -1)
            return;

        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        checkGLError("glGetUniformLocation uMVPMatrix");
        if (muMVPMatrixHandle == -1)
            return;

        muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
        checkGLError("glGetUniformLocation uSTMatrix");
        if (muSTMatrixHandle == -1)
            return;

        textures = new int[2];
        GLES20.glGenTextures(2, textures, 0);
        if (textures[0] == 0 || textures[1] == 0)
            return;

        mTextureID = textures[0];
        mTextureIDDst = textures[1];
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
        checkGLError("glBindTexture");

        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

        mSurface = new SurfaceTexture(mTextureID);
        mSurface.setOnFrameAvailableListener(this);
        isEGLStoped = false;
        frameBufferBinding = new int[1];
        GLES20.glGenFramebuffers(1, frameBufferBinding, 0);
        checkGLError("DownloadImageFromTexture");

        runOnUiThread(new Runnable() {
            @Override
            public void run()
            {
                if(m_permissionGranted){
                    startCapturePreview(mCameraId);
                }
            }
        });
    }

    private void startCapturePreview(int id) {
        if (mStreamingContext == null||mSurface==null) {
            Log.e(TAG, "mStreamingContext is null!");
            return;
        }

        mStreamingContext.connectCapturePreviewWithSurfaceTexture(mSurface);
        mStreamingContext.setCaptureDeviceCallback(this);
        mStreamingContext.setCaptureFps(mVideoFPS);

//        if(m_useBeauty) {
//            NvsCaptureVideoFx fx = mStreamingContext.appendBeautyCaptureVideoFx();     //添加美颜采集特效
//            fx.setFloatVal("Strength", 0.5d);//设置美颜强度值(0-1)
//            fx.setFloatVal("Whitening", 0.5d);
//            fx.setFloatVal("Reddening", 0.5d);
//        }
        if (getCurrentEngineState() != NvsStreamingContext.STREAMING_ENGINE_STATE_CAPTUREPREVIEW) {
            if (!mStreamingContext.startCapturePreview(id, NvsStreamingContext.VIDEO_CAPTURE_RESOLUTION_GRADE_HIGH, NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_DONT_USE_SYSTEM_RECORDER |
                    NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_CAPTURE_BUDDY_HOST_VIDEO_FRAME
                    | NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_STRICT_PREVIEW_VIDEO_SIZE
                    |NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_DONT_CAPTURE_AUDIO, null))
                Log.e(TAG, "Failed to start capture preview!");
        }
        mCurrentDeviceIndex = id%2;
    }

    public void switchCamera(int id) {
        if(mStreamingContext != null)
        {
            mCameraId = id;
            mCameraId =mCameraId%2;
            if (!mStreamingContext.startCapturePreview(mCameraId,
                    NvsStreamingContext.VIDEO_CAPTURE_RESOLUTION_GRADE_HIGH,
                    NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_DONT_USE_SYSTEM_RECORDER |
                            NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_CAPTURE_BUDDY_HOST_VIDEO_FRAME
                            | NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_STRICT_PREVIEW_VIDEO_SIZE
                            |NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_DONT_CAPTURE_AUDIO
                    , null)) {
                Log.e(TAG, "Failed to start capture preview!");
            }
        }

    }

    private boolean startCapturePreview(boolean deviceChanged) {
        // 判断当前引擎状态是否为采集预览状态
        int captureResolutionGrade = ParameterSettingValues.instance().getCaptureResolutionGrade();
        if ( deviceChanged || getCurrentEngineState() != NvsStreamingContext.STREAMING_ENGINE_STATE_CAPTUREPREVIEW) {
            m_supportAutoFocus = false;
            if (!mStreamingContext.startCapturePreview(mCurrentDeviceIndex,
                    captureResolutionGrade,
                    NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_DONT_USE_SYSTEM_RECORDER |
                            NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_CAPTURE_BUDDY_HOST_VIDEO_FRAME
                            | NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_STRICT_PREVIEW_VIDEO_SIZE
                            |NvsStreamingContext.STREAMING_ENGINE_CAPTURE_FLAG_DONT_CAPTURE_AUDIO, null)) {
                Log.e(TAG, "Failed to start capture preview!");
                return false;
            }
        }
        return true;
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        orgViewWidth = width;
        orgViewHeight = height;

        viewWidth = orgViewWidth;
        viewHeight = orgViewHeight;


        Log.e(TAG, "onSurfaceChanged");
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
        draw(viewPortX, viewPortY,viewWidth, viewHeight);

//        DownloadImageFromTexture2();

    }

    private void draw(int x,int y,int width, int height) {
        GLES20.glUseProgram(mProgram);

        GLES20.glClearColor(0, 0, 0, 1);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);

//        GLES20.glViewport(0, 0, width, height);
//        GLES20.glViewport(viewPortX, viewPortY, width, height);//zhang
        GLES20.glViewport(x, y, width, height);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
        GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
        GLES20.glEnableVertexAttribArray(maPositionHandle);

        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
        GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
        GLES20.glEnableVertexAttribArray(maTextureHandle);

        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
        GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
        checkGLError("DownloadImageFromTexture");

        GLES20.glDisableVertexAttribArray(maPositionHandle);
        GLES20.glDisableVertexAttribArray(maTextureHandle);
    }

    private int loadShader(int shaderType, String source) {
        int shader = GLES20.glCreateShader(shaderType);
        if (shader != 0) {
            GLES20.glShaderSource(shader, source);
            GLES20.glCompileShader(shader);
            int[] compiled = new int[1];
            GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
            if (compiled[0] == 0) {
                Log.e(TAG, "Could not compile shader " + shaderType + ":");
                Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
                GLES20.glDeleteShader(shader);
                shader = 0;
            }
        }
        return shader;
    }

    private int createProgram(String vertexSource, String fragmentSource) {
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
        if (vertexShader == 0) {
            return 0;
        }
        int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
        if (pixelShader == 0) {
            return 0;
        }

        int program = GLES20.glCreateProgram();
        if (program != 0) {
            GLES20.glAttachShader(program, vertexShader);
            checkGLError("glAttachShader");
            GLES20.glAttachShader(program, pixelShader);
            checkGLError("glAttachShader");
            GLES20.glLinkProgram(program);
            int[] linkStatus = new int[1];
            GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
            if (linkStatus[0] != GLES20.GL_TRUE) {
                Log.e(TAG, "Could not link program: ");
                Log.e(TAG, GLES20.glGetProgramInfoLog(program));
                GLES20.glDeleteProgram(program);
                program = 0;
            }
        }
        return program;
    }

    private void checkGLError(String op) {
        int error;
        if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR)
            Log.e(TAG, op + ": glError " + error);
    }

    void DownloadImageFromTexture2() {
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDDst);
        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, imageWidth, imageHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
        GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBufferBinding[0]);
        GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mTextureIDDst, 0);
        checkGLError("DownloadImageFromTexture");

//        draw(imageWidth, imageHeight);
        draw(0,0,imageWidth, imageHeight);

        if (RGBA_buffer == null) {
            RGBA_buffer = ByteBuffer.allocate(imageWidth * imageHeight * 4);
        }
        RGBA_buffer.position(0);
        // Download image
//        GLES20.glReadPixels(viewPortX, viewPortY, imageWidth, imageHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, RGBA_buffer);//zhang
        GLES20.glReadPixels(0, 0, imageWidth, imageHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, RGBA_buffer);
        checkGLError("DownloadImageFromTexture");

        GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
        if(isConnected) {
            HWVideoFrame videoFrame = new HWVideoFrame();
            videoFrame.data = RGBA_buffer.array();
            videoFrame.width = imageWidth;
            videoFrame.height = imageHeight;
            videoFrame.type = RGBA;
            videoFrame.rotation = 0;
            mPublisher.pushExternVideoFrame(videoFrame);
        }
    }


    @Override
    public void onNetworkWeak() {
        Log.e(TAG,"onNetworkWeak");
    }

    @Override
    public void onNetworkResume() {
        Log.e(TAG,"onNetworkResume");
    }

    @Override
    public void onEncodeIllegalArgumentException(IllegalArgumentException e) {
        Log.e(TAG,"onEncodeIllegalArgumentException");
    }

    @Override
    public void onRecordPause() {
        Log.e(TAG,"onRecordPause");
    }

    @Override
    public void onRecordResume() {
        Log.e(TAG,"onRecordResume");
    }

    @Override
    public void onRecordStarted(String msg) {
        Log.e(TAG,"onRecordStarted");
    }

    @Override
    public void onRecordFinished(String msg) {
        Log.e(TAG,"onRecordFinished");
    }

    @Override
    public void onRecordIllegalArgumentException(IllegalArgumentException e) {
        Log.e(TAG,"onRecordIllegalArgumentException");
    }

    @Override
    public void onRecordIOException(IOException e) {
        Log.e(TAG,"onRecordIOException");
    }

    @Override
    public void onRtmpConnecting(String msg) {
        Log.e(TAG,"onRtmpConnecting");
        isConnecting=true;
        Toast.makeText(CaptureActivity.this,"推流连接 状态："+"Connecting",Toast.LENGTH_LONG).show();
    }

    @Override
    public void onRtmpConnected(String msg) {
        Log.e(TAG,"onRtmpConnected");
        isConnected=true;
        isConnecting =false;
        isRightUrl =true;

        capture_btn.setClickable(true);
        Toast.makeText(CaptureActivity.this,"推流连接 状态："+"Connected",Toast.LENGTH_LONG).show();
    }

    @Override
    public void onRtmpVideoStreaming() {
//        Log.e(TAG,"onRtmpVideoStreaming");
    }

    @Override
    public void onRtmpAudioStreaming() {
//        Log.e(TAG,"onRtmpAudioStreaming");
    }

    @Override
    public void onRtmpStopped() {
        Log.e(TAG,"onRtmpStopped");
        Toast.makeText(CaptureActivity.this,"推流连接 状态："+"Stopped",Toast.LENGTH_LONG).show();
    }

    @Override
    public void onRtmpDisconnected() {
        Log.e(TAG,"onRtmpDisconnected");
        isConnected = false;
        isConnecting = false;
        if(!isRightUrl) {
            Toast.makeText(CaptureActivity.this, "推流连接 状态：Disconnected,请检查推流地址是否错误！", Toast.LENGTH_LONG).show();
//            rtmpUrl = "rtmp://114.116.58.50/live/your-room-name?vhost=live-pub.huaweicloud.com";
//            rtmpUrl_edit.setText(rtmpUrl);
            if(mPublisher!=null)
                mPublisher.stopPublish();
        }
        else {
            Toast.makeText(CaptureActivity.this,"推流连接 状态："+"Disconnected",Toast.LENGTH_LONG).show();
        }
        capture_btn.setText("开始推流");
        capture_btn.setTextColor(Color.WHITE);
        capture_btn.setClickable(true);
    }

    @Override
    public void onRtmpVideoFpsChanged(double fps) {
        vfps = (int) fps;
    }

    @Override
    public void onRtmpVideoBitrateChanged(double bitrate) {
        vbitrate = (int) (bitrate/1000);
    }

    @Override
    public void onRtmpAudioBitrateChanged(double bitrate) {
        abitrate = (int) bitrate;
    }

    @Override
    public void onRtmpSocketException(SocketException e) {
        Log.e(TAG,"onRtmpSocketException");
        handleException(e);
    }

    @Override
    public void onRtmpIOException(IOException e) {
        Log.e(TAG,"onRtmpIOException");
        handleException(e);
    }

    @Override
    public void onRtmpIllegalArgumentException(IllegalArgumentException e) {
        Log.e(TAG,"onRtmpIllegalArgumentException");
        handleException(e);
    }

    @Override
    public void onRtmpIllegalStateException(IllegalStateException e) {
        Log.e(TAG,"onRtmpIllegalStateException");
        handleException(e);
    }

    private void handleException(Exception e) {
        try {
            Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
            isConnected = false;
            isConnecting = false;
            mPublisher.stopAudioRecord();
            mPublisher.stopPublish();
            mPublisher.stopRecord();
            capture_btn.setText("开始推流");
            capture_btn.setTextColor(Color.WHITE);
            capture_btn.setClickable(true);
        } catch (Exception e1) {
            //
        }
        handler.sendEmptyMessage(0);
    }

    public boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }

//断网自动重连
    int delayTime = 1;
    Thread reconnectworker=null;
    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case 0:
                    if(reconnectworker!=null){
                        reconnectworker.interrupt();
                        reconnectworker=null;
                    }
                    // 移除所有的msg.what为0等消息，保证只有一个循环消息队列再跑
                    handler.removeMessages(0);
                    reconnectworker = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Log.e(TAG, "handleMessage isMainThread: "+isMainThread() );

                            try {
                                Thread.sleep(delayTime*100);
                            } catch (InterruptedException e1) {
                                e1.printStackTrace();
                            }

                            // app的功能逻辑处理
                            Log.e(TAG, "handleException isAvailableByPing: "+isAvailableByPing() );
                            if(isAvailableByPing()){
                                Log.e(TAG, "handleMessage clicked! " );
                                runOnUiThread(
                                        new Runnable() {
                                            @Override
                                            public void run() {
                                                if(isConnected == false)
                                                {
                                                    capture_btn.performClick();
                                                }
                                            }
                                        }
                                );

                            }else{
                                handler.sendEmptyMessage(0);
                            }
                            delayTime++;
                            if(delayTime>10){
                                handler.sendEmptyMessage(1);
                            }
                        }
                    });
                    reconnectworker.start();

                    // 再次发出msg，循环更新
//                    handler.sendEmptyMessageDelayed(0, delayTime*1000);
                    break;

                case 1:
                    // 直接移除，定时器停止
                    handler.removeMessages(0);
                    if(reconnectworker!=null){
                        reconnectworker.interrupt();
                        reconnectworker=null;
                    }
                    break;

                default:
                    break;
            }
        };
    };

    static public class ShapeDataItem {
        String shapeId;
        int resId;
        String name;
        String type;
    }
}
