🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
**注意:即构新版需要进行模块级替换,即使用美颜Demo里的CustomVideoCapture模块替换即构Demo的同名模块。** **1.初始化MHSDK** **找到ZegoApplication.java文件,在****onCreate****方法中添加以下代码:** ``` MHSDK.getInstance().init(this," "); ``` **2.**** 初始化美颜界面** **找到MHCaptureRenderActivity.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 boolean isRended; private int mDeviceLevel; private ProgramTextureOES mProgramTextureOES; private ProgramTexture2d mProgramTexture2d; private ProgramTexture2d mProgramTexture2d1; private int[] bindingFrameBuffer = new int[1]; private int[] bindingRenderBuffer = new int[1]; private int[] viewPoint = new int[4]; private int vertexAttribEnableArraySize = 5; private ArrayList vertexAttribEnableArray; ``` **添加以下****方法****:** ``` private void initBeautyView() {     beautyContainer = findViewById(R.id.beauty_view_container);     mHandler = new Handler(getMainLooper());     try {         mDeviceLevel = ThemisUtil.judgeDeviceLevel(this);     }catch (Exception e){         e.printStackTrace();         Log.e(TAG, "judgeDeviceLevel error");     }     if (MHSDK.getInstance().isVerEnd()) {         setBeautyView();     } else {         if (beautyThread != null) {             beautyThread.interrupt();             beautyThread = null;         }         beautyThread = new BeautyThread(this);         beautyThread.start();     } } private void initMHBeautyManager(){     if (mhBeautyManager == null) {         mhBeautyManager = new MHBeautyManager(this,true);         mhBeautyManager.setMinFaceSize(120);         mhBeautyManager.setBeautyDataModel(BeautyDataModel.getInstance());         if (beautyViewHolder != null) {             beautyViewHolder.setMhBeautyManager(mhBeautyManager);         }     } } 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(new IBeautyViewHolder.VisibleListener() {         @Override         public void onVisibleChanged(boolean visible) {             if (!visible) {                 beautyViewHolder.show();             }         }     });     initMHBeautyManager(); } static class DiaLogListener implements DialogInterface.OnClickListener {     WeakReference activityWeakReference;     DiaLogListener(MHCaptureRenderActivity activity) {         this.activityWeakReference = new WeakReference<>(activity);     }     @Override     public void onClick(DialogInterface dialog, int which) {         MHCaptureRenderActivity 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(MHCaptureRenderActivity activity) {         this.activityWeakReference = new WeakReference<>(activity);     }     @Override     public void onClick(DialogInterface dialog, int which) {         MHCaptureRenderActivity 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;         }     } } ``` //由于demo进入应用直接进入美颜界面,为了防止授权校验未完成而一直显示标准版界面,需要等授权校验完成后初始化对应的美颜界面(延迟1秒或者按下面处理) ``` static class BeautyThread extends Thread {     WeakReference mainActivityWeakReference;     BeautyThread(MHCaptureRenderActivity MHCaptureRenderActivity) {         this.mainActivityWeakReference = new WeakReference<>(MHCaptureRenderActivity);     }     @Override     public void run() {         while (mainActivityWeakReference.get() != null && !MHSDK.getInstance().isVerEnd()) {             if (isInterrupted()) return;             try {                 Thread.sleep(200);             } catch (InterruptedException e) {                 e.printStackTrace();             }         }         final MHCaptureRenderActivity activity = mainActivityWeakReference.get();         if (activity != null) {             activity.mHandler.post(new Runnable() {                 @Override                 public void run() {                     activity.setBeautyView();;                 }             });         }     } } 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(); } @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);     } } public void saveOpenGLState() {     // 获取当前绑定的FrameBuffer     glGetIntegerv(GL_FRAMEBUFFER_BINDING, bindingFrameBuffer, 0);     // 获取当前绑定的RenderBuffer     glGetIntegerv(GL_RENDERBUFFER_BINDING, bindingRenderBuffer, 0);     // 获取viewpoint     glGetIntegerv(GL_VIEWPORT, viewPoint, 0);     // 获取顶点数据     if (vertexAttribEnableArray == null){         vertexAttribEnableArray = new ArrayList<>();     }     vertexAttribEnableArray.clear();     for (int x = 0; x < vertexAttribEnableArraySize; x++) {         int[] vertexAttribEnable = new int[1];         glGetVertexAttribiv(x, GL_VERTEX_ATTRIB_ARRAY_ENABLED, vertexAttribEnable, 0);         if (vertexAttribEnable[0] != 0) {             vertexAttribEnableArray.add(x);         }     } } public void restoreOpenGLState() {     // 还原当前绑定的FrameBuffer     glBindFramebuffer(GL_FRAMEBUFFER, bindingFrameBuffer[0]);     // 还原当前绑定的RenderBuffer     glBindRenderbuffer(GL_RENDERBUFFER, bindingRenderBuffer[0]);     // 还原viewpoint     glViewport(viewPoint[0], viewPoint[1], viewPoint[2], viewPoint[3]);     // 还原顶点数据     for (int x = 0; x < vertexAttribEnableArray.size(); x++) {         glEnableVertexAttribArray(vertexAttribEnableArray.get(x));     } } ``` **在OnCreate调用initBeautyView()方法** ``` initBeautyView(); ``` **设置ZegoCustomVideoCaptureConfig的****bufferType****为ZegoVideoBufferType.GL_TEXTURE_2D;** ``` videoCaptureConfig.bufferType = ZegoVideoBufferType.GL_TEXTURE_2D; mSDKEngine.enableCustomVideoCapture(true, videoCaptureConfig, ZegoPublishChannel.MAIN); ``` **在doPublish()里面设置码率为****1500** ``` zegoVideoConfig.setVideoBitrate(1500); ``` **在****onResume****里面调用****initMHBeautyManager****方法** ``` initMHBeautyManager(); ``` **重要,自定义onDrawFrame方法,代码如下** ``` @Override public int onDrawFrame(byte[] nv21Byte, int texId, int cameraWidth, int cameraHeight, int cameraRotation, float[] mvpMatrix, float[] texMatrix, long timeStamp) {     saveOpenGLState();     int tex2D = texId;     if (mProgramTextureOES == null) {         mProgramTextureOES = new  ProgramTextureOES();     }     tex2D = mProgramTextureOES.getTexId(tex2D,cameraWidth,cameraHeight);     if(mProgramTexture2d==null){         mProgramTexture2d = new ProgramTexture2d().setAngle(90).init();         mProgramTexture2d1 = new ProgramTexture2d().setAngle(90).init();     }     int  newTex2D = mProgramTexture2d.getTexId(tex2D,cameraHeight,cameraWidth);     if (mhBeautyManager!=null) {         newTex2D =  mhBeautyManager.render(newTex2D,cameraHeight,cameraWidth,4,1);     }     long now;     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {         now = SystemClock.elapsedRealtime();     } else {         now = TimeUnit.MILLISECONDS.toMillis(SystemClock.elapsedRealtime());     }     mSDKEngine.sendCustomVideoCaptureTextureData(newTex2D,cameraHeight,cameraWidth,now);     newTex2D = mProgramTexture2d1.getTexId(newTex2D,cameraWidth,cameraHeight);     restoreOpenGLState();     return newTex2D; } ``` **在****onSurfaceDestroy****方法里销毁****MHBeautyManager** ``` @Override public void onSurfaceDestroy() {     if (mhBeautyManager != null) {         mhBeautyManager.destroy();         mhBeautyManager = null;     } } ```