├── .gitignore ├── README-云信采集.md ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── netease │ │ └── tutorials1v1vcall │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── io │ │ │ └── netease │ │ │ └── tutorials1v1vcall │ │ │ ├── MainActivity.java │ │ │ ├── MeetingActivity.java │ │ │ ├── MeetingCustomActivity.java │ │ │ ├── NeedFaceUnityAcct.java │ │ │ ├── PreferenceUtil.java │ │ │ ├── custom │ │ │ ├── CameraRenderer.java │ │ │ ├── CameraUtils.java │ │ │ └── GlUtil.java │ │ │ └── profile │ │ │ ├── CPUInfoUtil.java │ │ │ ├── CSVUtils.java │ │ │ ├── Constant.java │ │ │ ├── FPSUtil.java │ │ │ └── MemoryInfoUtil.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_launcher_background.xml │ │ ├── selector_meeting_close_video.xml │ │ ├── selector_meeting_leave.xml │ │ ├── selector_meeting_mute.xml │ │ ├── selector_meeting_open_video.xml │ │ ├── selector_meeting_unmute.xml │ │ └── shape_main_btn_join.xml │ │ ├── layout │ │ ├── act_faceunity.xml │ │ ├── activity_main.xml │ │ └── activity_meeting.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_logo.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_logo.png │ │ ├── mipmap-xhdpi │ │ ├── close_video_click.png │ │ ├── close_video_default.png │ │ ├── close_video_hover.png │ │ ├── ic_camera_flip.png │ │ ├── ic_input_clear.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── ic_logo.png │ │ ├── leave_channel_click.png │ │ ├── leave_channel_default.png │ │ ├── leave_channel_hover.png │ │ ├── mute_click.png │ │ ├── mute_default.png │ │ ├── mute_hover.png │ │ ├── open_video_click.png │ │ ├── open_video_default.png │ │ ├── open_video_hover.png │ │ ├── unmute_click.png │ │ ├── unmute_default.png │ │ └── unmute_hover.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_logo.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-v19 │ │ └── styles.xml │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-v23 │ │ └── styles.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── io │ └── netease │ └── tutorials1v1vcall │ └── ExampleUnitTest.java ├── build.gradle ├── faceunity ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── makeup │ │ ├── chaomo.bundle │ │ ├── chuju.bundle │ │ ├── chuqiu.bundle │ │ ├── gangfeng.bundle │ │ ├── hongfeng.bundle │ │ ├── jianling.bundle │ │ ├── linjia.bundle │ │ ├── nuandong.bundle │ │ ├── oumei.bundle │ │ ├── qianzhihe.bundle │ │ ├── renyu.bundle │ │ ├── rose.bundle │ │ ├── shaonv.bundle │ │ ├── tianmei.bundle │ │ ├── wumei.bundle │ │ ├── xinggan.bundle │ │ ├── yanshimao.bundle │ │ └── ziyun.bundle │ └── sticker │ │ ├── cat_sparks.bundle │ │ ├── fashi.bundle │ │ ├── sdlr.bundle │ │ └── sdlu.bundle │ ├── java │ └── com │ │ └── faceunity │ │ └── nama │ │ ├── FUConfig.java │ │ ├── FURenderer.java │ │ ├── IFURenderer.java │ │ ├── base │ │ ├── BaseDelegate.java │ │ ├── BaseListAdapter.java │ │ └── BaseViewHolder.java │ │ ├── checkbox │ │ ├── CheckBoxCompat.java │ │ └── CheckGroup.java │ │ ├── control │ │ ├── BaseControlView.java │ │ ├── BodyBeautyControlView.java │ │ ├── FaceBeautyShapeControlView.java │ │ ├── FaceBeautySkinControlView.java │ │ ├── FilterControlView.java │ │ ├── MakeupControlView.java │ │ └── PropControlView.java │ │ ├── data │ │ ├── BodyBeautyDataFactory.java │ │ ├── FaceBeautyAndFilterDataFactory.java │ │ ├── FaceUnityDataFactory.java │ │ ├── MakeupDataFactory.java │ │ └── PropDataFactory.java │ │ ├── dialog │ │ ├── BaseDialogFragment.java │ │ ├── ConfirmDialogFragment.java │ │ └── ToastHelper.java │ │ ├── entity │ │ ├── BodyBeautyBean.java │ │ ├── FaceBeautyBean.java │ │ ├── FaceBeautyFilterBean.java │ │ ├── MakeupCombinationBean.java │ │ ├── ModelAttributeData.java │ │ └── PropBean.java │ │ ├── infe │ │ ├── AbstractBodyBeautyDataFactory.java │ │ ├── AbstractFaceBeautyDataFactory.java │ │ ├── AbstractMakeupDataFactory.java │ │ └── AbstractPropDataFactory.java │ │ ├── listener │ │ ├── FURendererListener.java │ │ ├── OnBottomAnimatorChangeListener.java │ │ └── OnMultiClickListener.java │ │ ├── repo │ │ ├── BodyBeautySource.java │ │ ├── FaceBeautySource.java │ │ ├── MakeupSource.java │ │ └── PropSource.java │ │ ├── seekbar │ │ ├── DiscreteSeekBar.java │ │ └── internal │ │ │ ├── Marker.java │ │ │ ├── PopupIndicator.java │ │ │ ├── compat │ │ │ ├── AnimatorCompat.java │ │ │ ├── SeekBarCompat.java │ │ │ └── SeekBarCompatDontCrash.java │ │ │ └── drawable │ │ │ ├── AlmostRippleDrawable.java │ │ │ ├── MarkerDrawable.java │ │ │ ├── StateDrawable.java │ │ │ ├── ThumbDrawable.java │ │ │ ├── TrackOvalDrawable.java │ │ │ └── TrackRectDrawable.java │ │ ├── ui │ │ └── FaceUnityView.java │ │ ├── utils │ │ └── FuDeviceUtils.java │ │ └── widget │ │ ├── CircleImageView.java │ │ └── TouchStateImageView.java │ └── res │ ├── color │ ├── bottom_radio_color.xml │ ├── dsb_progress_color_list.xml │ ├── dsb_ripple_color_list.xml │ ├── dsb_track_color_list.xml │ └── tv_main_color_selector.xml │ ├── drawable │ ├── bg_confirm_dialog.xml │ ├── bg_confirm_dialog_option.xml │ ├── bg_control_oval_selector.xml │ ├── bg_control_square_selector.xml │ ├── bg_radio_group.xml │ ├── bg_radio_left.xml │ ├── bg_radio_left_check.xml │ ├── bg_radio_left_selector.xml │ ├── bg_radio_middle.xml │ ├── bg_radio_right.xml │ ├── bg_radio_right_check.xml │ ├── bg_radio_right_selector.xml │ ├── bg_seek_bar.xml │ ├── bg_shape_oval_theme.xml │ ├── bg_shape_rect_theme.xml │ ├── bg_toast_more.xml │ ├── icon_beauty_shape_angle_close_selector.xml │ ├── icon_beauty_shape_angle_open_selector.xml │ ├── icon_beauty_shape_brow_height_close_selector.xml │ ├── icon_beauty_shape_brow_height_open_selector.xml │ ├── icon_beauty_shape_brow_space_close_selector.xml │ ├── icon_beauty_shape_brow_space_open_selector.xml │ ├── icon_beauty_shape_brow_thick_close_selector.xml │ ├── icon_beauty_shape_brow_thick_open_selector.xml │ ├── icon_beauty_shape_cheek_bones_close_selector.xml │ ├── icon_beauty_shape_cheek_bones_open_selector.xml │ ├── icon_beauty_shape_chin_close_selector.xml │ ├── icon_beauty_shape_chin_open_selector.xml │ ├── icon_beauty_shape_distance_close_selector.xml │ ├── icon_beauty_shape_distance_open_selector.xml │ ├── icon_beauty_shape_enlarge_eye_close_selector.xml │ ├── icon_beauty_shape_enlarge_eye_open_selector.xml │ ├── icon_beauty_shape_eye_height_close_selector.xml │ ├── icon_beauty_shape_eye_height_open_selector.xml │ ├── icon_beauty_shape_eye_lid_close_selector.xml │ ├── icon_beauty_shape_eye_lid_open_selector.xml │ ├── icon_beauty_shape_face_cheekthin_close_selector.xml │ ├── icon_beauty_shape_face_cheekthin_open_selector.xml │ ├── icon_beauty_shape_face_little_close_selector.xml │ ├── icon_beauty_shape_face_little_open_selector.xml │ ├── icon_beauty_shape_face_narrow_close_selector.xml │ ├── icon_beauty_shape_face_narrow_open_selector.xml │ ├── icon_beauty_shape_face_short_close_selector.xml │ ├── icon_beauty_shape_face_short_open_selector.xml │ ├── icon_beauty_shape_face_v_close_selector.xml │ ├── icon_beauty_shape_face_v_open_selector.xml │ ├── icon_beauty_shape_forehead_close_selector.xml │ ├── icon_beauty_shape_forehead_open_selector.xml │ ├── icon_beauty_shape_lip_thick_close_selector.xml │ ├── icon_beauty_shape_lip_thick_open_selector.xml │ ├── icon_beauty_shape_lower_jaw_close_selector.xml │ ├── icon_beauty_shape_lower_jaw_open_selector.xml │ ├── icon_beauty_shape_mouth_close_selector.xml │ ├── icon_beauty_shape_mouth_open_selector.xml │ ├── icon_beauty_shape_open_eyes_close_selector.xml │ ├── icon_beauty_shape_open_eyes_open_selector.xml │ ├── icon_beauty_shape_proboscis_close_selector.xml │ ├── icon_beauty_shape_proboscis_open_selector.xml │ ├── icon_beauty_shape_round_eye_close_selector.xml │ ├── icon_beauty_shape_round_eye_open_selector.xml │ ├── icon_beauty_shape_shrinking_close_selector.xml │ ├── icon_beauty_shape_shrinking_open_selector.xml │ ├── icon_beauty_shape_smile_close_selector.xml │ ├── icon_beauty_shape_smile_open_selector.xml │ ├── icon_beauty_shape_thin_nose_close_selector.xml │ ├── icon_beauty_shape_thin_nose_open_selector.xml │ ├── icon_beauty_skin_buffing_close_selector.xml │ ├── icon_beauty_skin_buffing_open_selector.xml │ ├── icon_beauty_skin_color_close_selector.xml │ ├── icon_beauty_skin_color_open_selector.xml │ ├── icon_beauty_skin_dark_circles_close_selector.xml │ ├── icon_beauty_skin_dark_circles_open_selector.xml │ ├── icon_beauty_skin_eyes_bright_close_selector.xml │ ├── icon_beauty_skin_eyes_bright_open_selector.xml │ ├── icon_beauty_skin_face_three_close_selector.xml │ ├── icon_beauty_skin_face_three_open_selector.xml │ ├── icon_beauty_skin_red_close_selector.xml │ ├── icon_beauty_skin_red_open_selector.xml │ ├── icon_beauty_skin_sharpen_close_selector.xml │ ├── icon_beauty_skin_sharpen_open_selector.xml │ ├── icon_beauty_skin_teeth_close_selector.xml │ ├── icon_beauty_skin_teeth_open_selector.xml │ ├── icon_beauty_skin_wrinkle_close_selector.xml │ ├── icon_beauty_skin_wrinkle_open_selector.xml │ ├── icon_body_hip_close_selector.xml │ ├── icon_body_hip_open_selector.xml │ ├── icon_body_little_head_close_selector.xml │ ├── icon_body_little_head_open_selector.xml │ ├── icon_body_shoulder_close_selector.xml │ ├── icon_body_shoulder_open_selector.xml │ ├── icon_body_slimming_close_selector.xml │ ├── icon_body_slimming_open_selector.xml │ ├── icon_body_stovepipe_close_selector.xml │ ├── icon_body_stovepipe_open_selector.xml │ ├── icon_body_thin_leg_close_selector.xml │ ├── icon_body_thin_leg_open_selector.xml │ ├── icon_body_waist_close_selector.xml │ └── icon_body_waist_open_selector.xml │ ├── layout │ ├── dialog_confirm.xml │ ├── layout_body_beauty_control.xml │ ├── layout_effect_control.xml │ ├── layout_face_beauty_control.xml │ ├── layout_faceunity.xml │ ├── layout_filter_control.xml │ ├── layout_make_up_control.xml │ ├── list_item_control_image_square.xml │ ├── list_item_control_title_image_circle.xml │ └── list_item_control_title_image_square.xml │ ├── mipmap-xxhdpi │ ├── bg_live_seek_bar_light.9.png │ ├── icon_beauty_box_angle_close_checked.png │ ├── icon_beauty_box_angle_close_normal.png │ ├── icon_beauty_box_angle_open_checked.png │ ├── icon_beauty_box_angle_open_normal.png │ ├── icon_beauty_box_brow_height_close_checked.png │ ├── icon_beauty_box_brow_height_close_normal.png │ ├── icon_beauty_box_brow_height_open_checked.png │ ├── icon_beauty_box_brow_height_open_normal.png │ ├── icon_beauty_box_brow_space_close_checked.png │ ├── icon_beauty_box_brow_space_close_normal.png │ ├── icon_beauty_box_brow_space_open_checked.png │ ├── icon_beauty_box_brow_space_open_normal.png │ ├── icon_beauty_box_brow_thick_close_checked.png │ ├── icon_beauty_box_brow_thick_close_normal.png │ ├── icon_beauty_box_brow_thick_open_checked.png │ ├── icon_beauty_box_brow_thick_open_normal.png │ ├── icon_beauty_box_buffing_close_checked.png │ ├── icon_beauty_box_buffing_close_normal.png │ ├── icon_beauty_box_buffing_open_checked.png │ ├── icon_beauty_box_buffing_open_normal.png │ ├── icon_beauty_box_cheek_bones_close_checked.png │ ├── icon_beauty_box_cheek_bones_close_normal.png │ ├── icon_beauty_box_cheek_bones_open_checked.png │ ├── icon_beauty_box_cheek_bones_open_normal.png │ ├── icon_beauty_box_chin_close_checked.png │ ├── icon_beauty_box_chin_close_normal.png │ ├── icon_beauty_box_chin_open_checked.png │ ├── icon_beauty_box_chin_open_normal.png │ ├── icon_beauty_box_color_close_checked.png │ ├── icon_beauty_box_color_close_normal.png │ ├── icon_beauty_box_color_open_checked.png │ ├── icon_beauty_box_color_open_normal.png │ ├── icon_beauty_box_dark_circles_close_checked.png │ ├── icon_beauty_box_dark_circles_close_normal.png │ ├── icon_beauty_box_dark_circles_open_checked.png │ ├── icon_beauty_box_dark_circles_open_normal.png │ ├── icon_beauty_box_distance_close_checked.png │ ├── icon_beauty_box_distance_close_normal.png │ ├── icon_beauty_box_distance_open_checked.png │ ├── icon_beauty_box_distance_open_normal.png │ ├── icon_beauty_box_enlarge_eye_level_close_checked.png │ ├── icon_beauty_box_enlarge_eye_level_close_normal.png │ ├── icon_beauty_box_enlarge_eye_level_open_checked.png │ ├── icon_beauty_box_enlarge_eye_level_open_normal.png │ ├── icon_beauty_box_eye_height_close_checked.png │ ├── icon_beauty_box_eye_height_close_normal.png │ ├── icon_beauty_box_eye_height_open_checked.png │ ├── icon_beauty_box_eye_height_open_normal.png │ ├── icon_beauty_box_eye_lid_close_checked.png │ ├── icon_beauty_box_eye_lid_close_normal.png │ ├── icon_beauty_box_eye_lid_open_checked.png │ ├── icon_beauty_box_eye_lid_open_normal.png │ ├── icon_beauty_box_eyes_bright_close_checked.png │ ├── icon_beauty_box_eyes_bright_close_normal.png │ ├── icon_beauty_box_eyes_bright_open_checked.png │ ├── icon_beauty_box_eyes_bright_open_normal.png │ ├── icon_beauty_box_face_cheekthin_level_close_checked.png │ ├── icon_beauty_box_face_cheekthin_level_close_normal.png │ ├── icon_beauty_box_face_cheekthin_level_open_checked.png │ ├── icon_beauty_box_face_cheekthin_level_open_normal.png │ ├── icon_beauty_box_face_little_close_checked.png │ ├── icon_beauty_box_face_little_close_normal.png │ ├── icon_beauty_box_face_little_open_checked.png │ ├── icon_beauty_box_face_little_open_normal.png │ ├── icon_beauty_box_face_narrow_close_checked.png │ ├── icon_beauty_box_face_narrow_close_normal.png │ ├── icon_beauty_box_face_narrow_open_checked.png │ ├── icon_beauty_box_face_narrow_open_normal.png │ ├── icon_beauty_box_face_short_close_checked.png │ ├── icon_beauty_box_face_short_close_normal.png │ ├── icon_beauty_box_face_short_open_checked.png │ ├── icon_beauty_box_face_short_open_normal.png │ ├── icon_beauty_box_face_three_close_checked.png │ ├── icon_beauty_box_face_three_close_normal.png │ ├── icon_beauty_box_face_three_open_checked.png │ ├── icon_beauty_box_face_three_open_normal.png │ ├── icon_beauty_box_face_v_close_checked.png │ ├── icon_beauty_box_face_v_close_normal.png │ ├── icon_beauty_box_face_v_open_checked.png │ ├── icon_beauty_box_face_v_open_normal.png │ ├── icon_beauty_box_forehead_close_checked.png │ ├── icon_beauty_box_forehead_close_normal.png │ ├── icon_beauty_box_forehead_open_checked.png │ ├── icon_beauty_box_forehead_open_normal.png │ ├── icon_beauty_box_lip_thick_close_checked.png │ ├── icon_beauty_box_lip_thick_close_normal.png │ ├── icon_beauty_box_lip_thick_open_checked.png │ ├── icon_beauty_box_lip_thick_open_normal.png │ ├── icon_beauty_box_lower_jaw_close_checked.png │ ├── icon_beauty_box_lower_jaw_close_normal.png │ ├── icon_beauty_box_lower_jaw_open_checked.png │ ├── icon_beauty_box_lower_jaw_open_normal.png │ ├── icon_beauty_box_mouth_bones_close_normal.png │ ├── icon_beauty_box_mouth_close_checked.png │ ├── icon_beauty_box_mouth_open_checked.png │ ├── icon_beauty_box_mouth_open_normal.png │ ├── icon_beauty_box_open_eyes_close_checked.png │ ├── icon_beauty_box_open_eyes_close_normal.png │ ├── icon_beauty_box_open_eyes_open_checked.png │ ├── icon_beauty_box_open_eyes_open_normal.png │ ├── icon_beauty_box_proboscis_close_checked.png │ ├── icon_beauty_box_proboscis_close_normal.png │ ├── icon_beauty_box_proboscis_open_checked.png │ ├── icon_beauty_box_proboscis_open_normal.png │ ├── icon_beauty_box_red_close_checked.png │ ├── icon_beauty_box_red_close_normal.png │ ├── icon_beauty_box_red_open_checked.png │ ├── icon_beauty_box_red_open_normal.png │ ├── icon_beauty_box_round_eye_level_close_checked.png │ ├── icon_beauty_box_round_eye_level_close_normal.png │ ├── icon_beauty_box_round_eye_level_open_checked.png │ ├── icon_beauty_box_round_eye_level_open_normal.png │ ├── icon_beauty_box_sharpen_close_checked.png │ ├── icon_beauty_box_sharpen_close_normal.png │ ├── icon_beauty_box_sharpen_open_checked.png │ ├── icon_beauty_box_sharpen_open_normal.png │ ├── icon_beauty_box_shrinking_close_checked.png │ ├── icon_beauty_box_shrinking_close_normal.png │ ├── icon_beauty_box_shrinking_open_checked.png │ ├── icon_beauty_box_shrinking_open_normal.png │ ├── icon_beauty_box_smile_close_checked.png │ ├── icon_beauty_box_smile_close_normal.png │ ├── icon_beauty_box_smile_open_checked.png │ ├── icon_beauty_box_smile_open_normal.png │ ├── icon_beauty_box_teeth_close_checked.png │ ├── icon_beauty_box_teeth_close_normal.png │ ├── icon_beauty_box_teeth_open_checked.png │ ├── icon_beauty_box_teeth_open_normal.png │ ├── icon_beauty_box_thin_nose_close_checked.png │ ├── icon_beauty_box_thin_nose_close_normal.png │ ├── icon_beauty_box_thin_nose_open_checked.png │ ├── icon_beauty_box_thin_nose_open_normal.png │ ├── icon_beauty_box_wrinkle_close_checked.png │ ├── icon_beauty_box_wrinkle_close_normal.png │ ├── icon_beauty_box_wrinkle_open_checked.png │ ├── icon_beauty_box_wrinkle_open_normal.png │ ├── icon_beauty_face_contrast.png │ ├── icon_beauty_filter_bailiang_1.png │ ├── icon_beauty_filter_cancel.png │ ├── icon_beauty_filter_fennen_1.png │ ├── icon_beauty_filter_lengsediao_1.png │ ├── icon_beauty_filter_natural_1.png │ ├── icon_beauty_filter_texture_gray_1.png │ ├── icon_body_hip_close_checked.png │ ├── icon_body_hip_close_normal.png │ ├── icon_body_hip_open_checked.png │ ├── icon_body_hip_open_normal.png │ ├── icon_body_little_head_close_checked.png │ ├── icon_body_little_head_close_normal.png │ ├── icon_body_little_head_open_checked.png │ ├── icon_body_little_head_open_normal.png │ ├── icon_body_shoulder_close_checked.png │ ├── icon_body_shoulder_close_normal.png │ ├── icon_body_shoulder_open_checked.png │ ├── icon_body_shoulder_open_normal.png │ ├── icon_body_slimming_close_checked.png │ ├── icon_body_slimming_close_normal.png │ ├── icon_body_slimming_open_checked.png │ ├── icon_body_slimming_open_normal.png │ ├── icon_body_stovepipe_close_checked.png │ ├── icon_body_stovepipe_close_normal.png │ ├── icon_body_stovepipe_open_checked.png │ ├── icon_body_stovepipe_open_normal.png │ ├── icon_body_thin_leg_close_checked.png │ ├── icon_body_thin_leg_close_normal.png │ ├── icon_body_thin_leg_open_checked.png │ ├── icon_body_thin_leg_open_normal.png │ ├── icon_body_waist_close_checked.png │ ├── icon_body_waist_close_normal.png │ ├── icon_body_waist_open_checked.png │ ├── icon_body_waist_open_normal.png │ ├── icon_control_none.png │ ├── icon_control_recover.png │ ├── icon_live_camera_change.png │ ├── icon_makeup_combination_age.png │ ├── icon_makeup_combination_bored_cat.png │ ├── icon_makeup_combination_charming.png │ ├── icon_makeup_combination_daisy.png │ ├── icon_makeup_combination_early_autumn.png │ ├── icon_makeup_combination_girl.png │ ├── icon_makeup_combination_harbour_wind.png │ ├── icon_makeup_combination_mermaid.png │ ├── icon_makeup_combination_neighbor_girl.png │ ├── icon_makeup_combination_occident.png │ ├── icon_makeup_combination_paper_cranes.png │ ├── icon_makeup_combination_purple_rhyme.png │ ├── icon_makeup_combination_red_maple.png │ ├── icon_makeup_combination_rose.png │ ├── icon_makeup_combination_sexy.png │ ├── icon_makeup_combination_supermodel.png │ ├── icon_makeup_combination_sweet.png │ ├── icon_makeup_combination_warm_winter.png │ ├── icon_sticker_cat_sparks.png │ ├── icon_sticker_fashi.png │ ├── icon_sticker_sdlr.png │ └── icon_sticker_sdlu.png │ ├── values-1024x600 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1024x768 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1184x720 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1196x720 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1280x720 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1280x800 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1334x750 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1700x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1776x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1794x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1800x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1812x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1920x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-1920x1200 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-2160x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-2280x1080 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-2300x1440 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-2560x1440 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-2560x1600 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-800x480 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-854x480 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-960x540 │ ├── lay_x.xml │ └── lay_y.xml │ ├── values-zh-rCN │ └── strings.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hs_err_pid7972.log ├── replay_pid7972.log ├── script.gradle └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /.idea/ 4 | /local.properties 5 | /.idea/workspace.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.3" 6 | 7 | defaultConfig { 8 | applicationId "io.netease.tutorials1v1vcall" 9 | minSdkVersion 19 10 | targetSdkVersion 29 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | // 16 | // ndk { 17 | // abiFilters 'armeabi-v7a', 'arm64-v8a' 18 | // } 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | compileOptions { 28 | sourceCompatibility JavaVersion.VERSION_1_8 29 | targetCompatibility JavaVersion.VERSION_1_8 30 | } 31 | } 32 | 33 | dependencies { 34 | implementation fileTree(dir: "libs", include: ["*.jar"]) 35 | implementation 'androidx.appcompat:appcompat:1.1.0' 36 | implementation 'com.netease.yunxin:nertc-full:4.6.50' 37 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 38 | testImplementation 'junit:junit:4.12' 39 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 40 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 41 | implementation project(path: ':faceunity') 42 | 43 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -keep class com.netease.lava.** {*;} 24 | -keep class com.netease.yunxin.** {*;} -------------------------------------------------------------------------------- /app/src/androidTest/java/io/netease/tutorials1v1vcall/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package io.netease.tutorials1v1vcall; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("io.netease.tutorials1v1vcall", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 29 | 30 | 34 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/java/io/netease/tutorials1v1vcall/NeedFaceUnityAcct.java: -------------------------------------------------------------------------------- 1 | package io.netease.tutorials1v1vcall; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.text.TextUtils; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | import androidx.annotation.Nullable; 10 | import androidx.appcompat.app.AppCompatActivity; 11 | 12 | 13 | public class NeedFaceUnityAcct extends AppCompatActivity { 14 | 15 | private boolean isOn = true;//是否使用FaceUnity 16 | 17 | @Override 18 | protected void onCreate(@Nullable Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.act_faceunity); 21 | 22 | final Button button = (Button) findViewById(R.id.btn_set); 23 | String isOpen = PreferenceUtil.getString(this, PreferenceUtil.KEY_FACEUNITY_IS_ON); 24 | if (TextUtils.isEmpty(isOpen) || isOpen.equals("false")) { 25 | isOn = false; 26 | } else { 27 | isOn = true; 28 | } 29 | button.setText(isOn ? "On" : "Off"); 30 | 31 | button.setOnClickListener(new View.OnClickListener() { 32 | @Override 33 | public void onClick(View v) { 34 | isOn = !isOn; 35 | button.setText(isOn ? "On" : "Off"); 36 | } 37 | }); 38 | 39 | Button btn_to_main = (Button) findViewById(R.id.btn_to_main); 40 | btn_to_main.setOnClickListener(new View.OnClickListener() { 41 | @Override 42 | public void onClick(View v) { 43 | Intent intent = new Intent(NeedFaceUnityAcct.this, MainActivity.class); 44 | PreferenceUtil.persistString(NeedFaceUnityAcct.this, PreferenceUtil.KEY_FACEUNITY_IS_ON, 45 | isOn + ""); 46 | startActivity(intent); 47 | finish(); 48 | } 49 | }); 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/io/netease/tutorials1v1vcall/PreferenceUtil.java: -------------------------------------------------------------------------------- 1 | package io.netease.tutorials1v1vcall; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.preference.PreferenceManager; 6 | import android.text.TextUtils; 7 | 8 | public class PreferenceUtil { 9 | public static final String KEY_FACEUNITY_IS_ON = "faceunity_is_on"; 10 | public static final String VALUE_ON = "on"; 11 | public static final String VALUE_OFF = "off"; 12 | 13 | public static boolean persistString(Context context, String key, String value) { 14 | if (context == null || TextUtils.isEmpty(key)) { 15 | return false; 16 | } 17 | SharedPreferences defaultPreference = PreferenceManager.getDefaultSharedPreferences(context); 18 | try { 19 | defaultPreference.edit().putString(key, value).apply(); 20 | } catch (Exception e) { 21 | return false; 22 | } 23 | return true; 24 | } 25 | 26 | public static String getString(Context context, String key) { 27 | if (context == null || TextUtils.isEmpty(key)) { 28 | return null; 29 | } 30 | SharedPreferences defaultPreference = PreferenceManager.getDefaultSharedPreferences(context); 31 | try { 32 | return defaultPreference.getString(key, ""); 33 | } catch (Exception e) { 34 | return null; 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/io/netease/tutorials1v1vcall/profile/Constant.java: -------------------------------------------------------------------------------- 1 | package io.netease.tutorials1v1vcall.profile; 2 | 3 | import android.os.Build; 4 | import android.os.Environment; 5 | 6 | import java.io.File; 7 | import java.util.regex.Pattern; 8 | 9 | /** 10 | * Created by tujh on 2018/2/7. 11 | */ 12 | 13 | public class Constant { 14 | public static final String APP_NAME = "YXRTC"; 15 | public static final String filePath = Environment.getExternalStoragePublicDirectory("") 16 | + File.separator + "FaceUnity" + File.separator + APP_NAME + File.separator; 17 | 18 | public static final String DICMFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath(); 19 | public static final String photoFilePath; 20 | public static final String cameraFilePath; 21 | 22 | static { 23 | if (Build.FINGERPRINT.contains("Flyme") 24 | || Pattern.compile("Flyme", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find() 25 | || Build.MANUFACTURER.contains("Meizu") 26 | || Build.MANUFACTURER.contains("MeiZu")) { 27 | photoFilePath = DICMFilePath + File.separator + "Camera" + File.separator; 28 | cameraFilePath = DICMFilePath + File.separator + "Video" + File.separator; 29 | } else if (Build.FINGERPRINT.contains("vivo") 30 | || Pattern.compile("vivo", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find() 31 | || Build.MANUFACTURER.contains("vivo") 32 | || Build.MANUFACTURER.contains("vivo")) { 33 | photoFilePath = cameraFilePath = Environment.getExternalStoragePublicDirectory("") + File.separator + "相机" + File.separator; 34 | } else { 35 | cameraFilePath = photoFilePath = DICMFilePath + File.separator + "Camera" + File.separator; 36 | } 37 | createFile(filePath); 38 | createFile(cameraFilePath); 39 | createFile(photoFilePath); 40 | } 41 | 42 | public static void createFile(String path) { 43 | File dir = new File(path); 44 | if (!dir.exists()) { 45 | dir.mkdirs(); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/io/netease/tutorials1v1vcall/profile/FPSUtil.java: -------------------------------------------------------------------------------- 1 | package io.netease.tutorials1v1vcall.profile; 2 | 3 | /** 4 | * FPS工具类 5 | * Created by tujh on 2018/5/24. 6 | */ 7 | public class FPSUtil { 8 | private static final int NANO_IN_ONE_MILLI_SECOND = 1000000; 9 | private static final int NANO_IN_ONE_SECOND = 1000 * NANO_IN_ONE_MILLI_SECOND; 10 | 11 | private static long sLastFrameTimeStamp = 0; 12 | 13 | /** 14 | * 每帧都计算 15 | * 16 | * @return 17 | */ 18 | public static double fps() { 19 | long tmp = System.nanoTime(); 20 | double fps = ((double) NANO_IN_ONE_SECOND) / (tmp - sLastFrameTimeStamp); 21 | sLastFrameTimeStamp = tmp; 22 | // Log.e(TAG, "FPS : " + fps); 23 | return fps; 24 | } 25 | 26 | private static long mStartTime = 0; 27 | 28 | /** 29 | * 平均值 30 | * 31 | * @return 32 | */ 33 | public static double fpsAVG(int time) { 34 | long tmp = System.nanoTime(); 35 | double fps = ((double) NANO_IN_ONE_SECOND) * time / (tmp - mStartTime); 36 | mStartTime = tmp; 37 | // Log.e(TAG, "FPS : " + fps); 38 | return fps; 39 | } 40 | 41 | private long mLimitMinTime = 33333333; 42 | private long mLimitStartTime; 43 | private int mLimitFrameRate; 44 | 45 | public void setLimitMinTime(long limitMinTime) { 46 | mLimitMinTime = limitMinTime; 47 | } 48 | 49 | public void limit() { 50 | try { 51 | if (mLimitFrameRate == 0 || mLimitFrameRate > 600000) { 52 | mLimitStartTime = System.nanoTime(); 53 | mLimitFrameRate = 0; 54 | } 55 | long sleepTime = mLimitMinTime * mLimitFrameRate++ - (System.nanoTime() - mLimitStartTime); 56 | if (sleepTime > 0) { 57 | Thread.sleep(sleepTime / NANO_IN_ONE_MILLI_SECOND, (int) (sleepTime % NANO_IN_ONE_MILLI_SECOND)); 58 | } 59 | } catch (InterruptedException e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_meeting_close_video.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_meeting_leave.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_meeting_mute.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_meeting_open_video.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_meeting_unmute.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_main_btn_join.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/layout/act_faceunity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 |