🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
**1.初始化MHSDK** **新建****App****.java文件,在****onCreate****方法中添加以下代码** ``` MHSDK.getInstance().init(this," "); ``` **2.**** 初始化美颜界面** **找到****VideoChatViewActivity****.java文件,继承****DefaultBeautyEffectListener****接口,添加以下变量:** ``` private Handler mHandler; private AlertDialog dialog; private RelativeLayout beautyContainer; private MHBeautyManager mhBeautyManager; private BaseBeautyViewHolder beautyViewHolder; private boolean isResume; private int retryCount; private Thread beautyThread; ``` **添加以下方法:** ``` private void initBeautyView() {     if (MHSDK.getInstance().isVerEnd()){         setBeautyView();     }else {         if (beautyThread != null) {             beautyThread.interrupt();             beautyThread = null;         }         beautyThread = new BeautyThread(this);         beautyThread.start();     } } private void showRetryDialog() {     if (dialog != null) {         dialog.cancel();     }     SDKDialogListener diaLogListener = new SDKDialogListener(this);     dialog = new AlertDialog.Builder(this)             .setTitle("提示")             .setMessage("资源获取失败,请检查网络")             .setCancelable(false)             .setPositiveButton("确定", diaLogListener)             .create();     dialog.show(); } private void showExitDialog() {     if (dialog != null) {         dialog.cancel();     }     DiaLogListener diaLogListener = new DiaLogListener(this);     dialog = new AlertDialog.Builder(this)             .setTitle("提示")             .setMessage("资源获取失败,请检查网络并退出重试")             .setCancelable(false)             .setPositiveButton("确定", diaLogListener)             .create();     dialog.show(); } private void setBeautyView(){     LogManager.getInstance().writeData("MainActivity_setBeautyView_SDKVersion=" + MHSDK.getInstance().getVer());     if (!MHSDK.getInstance().isVerifyAccess()){         if (retryCount < 10) {             showRetryDialog();         }else {             showExitDialog();             return;         }     }     if (beautyViewHolder != null) {         beautyViewHolder.release();         beautyViewHolder = null;     }     beautyViewHolder = BeautyViewHolderFactory.getBeautyViewHolder(getApplicationContext(), beautyContainer);     beautyViewHolder.show();     beautyViewHolder.setEffectListener(this);     beautyViewHolder.setVisibleListener(visible -> {         if (!visible) {             beautyViewHolder.show();         }     });     beautyViewHolder.setMhBeautyManager(mhBeautyManager); } static class DiaLogListener implements DialogInterface.OnClickListener {     WeakReference activityWeakReference;     DiaLogListener(LiveChatActivity activity) {         this.activityWeakReference = new WeakReference<>(activity);     }     @Override     public void onClick(DialogInterface dialog, int which) {         LiveChatActivity activity = activityWeakReference.get();         if (activity == null)return;         switch (which){             case -1:                 dialog.cancel();                 activity.finish();                 break;             case -2:                 dialog.cancel();                 break;         }     } } static class SDKDialogListener implements DialogInterface.OnClickListener {     WeakReference activityWeakReference;     SDKDialogListener(LiveChatActivity activity) {         this.activityWeakReference = new WeakReference<>(activity);     }     @Override     public void onClick(DialogInterface dialog, int which) {         LiveChatActivity activity = activityWeakReference.get();         if (activity == null)return;         switch (which){             case -1:                 activity.retryCount ++;                 MHSDK.getInstance().clearVerNote();                 MHSDK.getInstance().verify("");                 activity.initBeautyView();                 dialog.cancel();                 break;             case -2:                 dialog.cancel();                 break;         }     } } static class BeautyThread extends  Thread {     WeakReference mainActivityWeakReference;     BeautyThread(LiveChatActivity txMainActivity) {         this.mainActivityWeakReference = new WeakReference<>(txMainActivity);     }     @Override     public void run() {         while (mainActivityWeakReference.get()!= null && !MHSDK.getInstance().isVerEnd()) {             if (isInterrupted()) return;             try {                 Thread.sleep(200);             } catch (InterruptedException e) {                 e.printStackTrace();             }         }         LiveChatActivity activity = mainActivityWeakReference.get();         if (activity != null){             activity.mHandler.post(activity::setBeautyView);         }     } } @Override public void onFilterChanged(FilterBean filterBean) {     if (mhBeautyManager == null) {         return;     }     FilterEnum filterEnum = filterBean.getFilterEnum();     if (filterEnum == FilterEnum.PRO_FILTER) {         mhBeautyManager.changeDynamicFilter(filterBean.getmFilterName());     } else {         Bitmap lookupBitmap = BitmapUtil.getFilterBitmap(this,filterEnum);         mhBeautyManager.setFilter(lookupBitmap);     } } @Override public void onMeiBaiChanged(int progress) {     if (mhBeautyManager != null) {         mhBeautyManager.setSkinWhiting(progress);     } } @Override public void onMoPiChanged(int progress) {     if (mhBeautyManager != null) {         mhBeautyManager.setSkinSmooth(progress);     } } @Override public void onFengNenChanged(int progress) {     if (mhBeautyManager != null) {         mhBeautyManager.setSkinTenderness(progress);     } } @Override public void onBeautyOrigin() {     if (mhBeautyManager != null) {         mhBeautyManager.setSkinWhiting(0);         mhBeautyManager.setSkinSmooth(0);         mhBeautyManager.setSkinTenderness(0);     } } ``` **在****onCreate****方法中调用****initBeautyView****方法。** **3.**** 自定义渲染** **在****VideoChatViewActivity****.java添加以下变量** ``` private GLSurfaceView mGLSurfaceViewLocal; private VideoManager mVideoManager; private SinkConnector mEffectHandler = new SinkConnector() {     @Override     public int onDataAvailable(VideoCaptureFrame data) {         int textureId = data.mTextureId;         int newTexture = textureId;          try {                 if (mhBeautyManager == null) {                     mhBeautyManager = new MHBeautyManager(getApplicationContext(),true);                     mhBeautyManager.setBeautyDataModel(BeautyDataModel.getInstance());                     if (beautyViewHolder != null) {                         beautyViewHolder.setMhBeautyManager(mhBeautyManager);                     }                 }else{                     newTexture = mhBeautyManager.render4(textureId, data.mFormat.mWidth,  data.mFormat.mHeight);                 }         } catch (Exception e) {             e.printStackTrace();         }         return newTexture;     } }; ``` **setupLocalVideo****方法改为以下代码** ```    private void setupLocalVideo() {         // This is used to set a local preview.         // The steps setting local and remote view are very similar.         // But note that if the local user do not have a uid or do         // not care what the uid is, he can set his uid as ZERO.         // Our server will assign one and return the uid via the event         // handler callback function (onJoinChannelSuccess) after         // joining the channel successfully. //        mLocalView = RtcEngine.CreateRendererView(getBaseContext()); //        mLocalView.setZOrderMediaOverlay(true); //        mLocalContainer.addView(mLocalView);         DisplayMetrics displayMetrics = new DisplayMetrics();         getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); //        int height = displayMetrics.heightPixels/2; //        int width = displayMetrics.widthPixels/2; //        int height = displayMetrics.heightPixels; //        int width = displayMetrics.widthPixels;         int height = dip2px(300);         int width = dip2px(224);         Log.d(TAG, "width: " + width + ", height: " + height); //        mSmallHeight = height / 3; //        mSmallWidth = width / 3;         mGLSurfaceViewLocal = new GLSurfaceView(this);         if (mLocalContainer.getChildCount() > 0) {             mLocalContainer.removeAllViews();         }         mLocalContainer.addView(mGLSurfaceViewLocal,                 FrameLayout.LayoutParams.MATCH_PARENT,                 FrameLayout.LayoutParams.MATCH_PARENT);         mVideoManager = VideoManager.createInstance(this);         mVideoManager.allocate(width, height, 30, io.agora.kit.media.constant.Constant.CAMERA_FACING_FRONT);         mVideoManager.setRenderView(mGLSurfaceViewLocal);         mVideoManager.connectEffectHandler(mEffectHandler); //        mVideoManager.attachToRTCEngine(getWorker().getRtcEngine());         mVideoManager.attachToRTCEngine(mRtcEngine);         mVideoManager.startCapture(); //        mRtcEngine.setupLocalVideo(new VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 1001));     } ``` **4.设置渲染的宽高** **找到****VideoRender****.java文件,在****onDrawFrame****方法里添加以下代码** ``` GLES20.glViewport(0, 0,  mViewWidth,  mViewHeight); //加上这句 if (mEffectTextureId <= 0) {     mTextureOES.drawFrame(frame.mTextureId, frame.mTexMatrix, mMVP); } else {     frame.mTextureId = mEffectTextureId;     mFullFrameRectTexture2D.drawFrame(frame.mTextureId, frame.mTexMatrix, mMVP); } ```