Commit ef93fa9fd4ba56f8c1751de847aef781800b814b
1 parent
6f705fd0
调整视频录制,删除七牛短视频sdk
Showing
59 changed files
with
8617 additions
and
1960 deletions
app/build.gradle
| @@ -13,6 +13,11 @@ android { | @@ -13,6 +13,11 @@ android { | ||
| 13 | ndk { | 13 | ndk { |
| 14 | abiFilters "armeabi-v7a", "arm64-v8a" | 14 | abiFilters "armeabi-v7a", "arm64-v8a" |
| 15 | } | 15 | } |
| 16 | + javaCompileOptions { | ||
| 17 | + annotationProcessorOptions { | ||
| 18 | + arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"] | ||
| 19 | + } | ||
| 20 | + } | ||
| 16 | 21 | ||
| 17 | } | 22 | } |
| 18 | 23 | ||
| @@ -49,5 +54,8 @@ dependencies { | @@ -49,5 +54,8 @@ dependencies { | ||
| 49 | implementation 'androidx.multidex:multidex:2.0.1' | 54 | implementation 'androidx.multidex:multidex:2.0.1' |
| 50 | // implementation 'com.cnlive.media:NewMediaPicker:1.1.4.28' | 55 | // implementation 'com.cnlive.media:NewMediaPicker:1.1.4.28' |
| 51 | implementation project(path: ':lib_media') | 56 | implementation project(path: ':lib_media') |
| 57 | + //ARouter | ||
| 58 | + implementation "com.alibaba:arouter-api:$rootProject.arouterApiVersion" | ||
| 59 | + annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterCompilerVersion" | ||
| 52 | 60 | ||
| 53 | } | 61 | } |
| 54 | \ No newline at end of file | 62 | \ No newline at end of file |
app/src/main/java/com/cnlive/strike/debug/MainActivity.java
| @@ -8,6 +8,7 @@ import android.content.Intent; | @@ -8,6 +8,7 @@ import android.content.Intent; | ||
| 8 | import android.os.Build; | 8 | import android.os.Build; |
| 9 | import android.os.Bundle; | 9 | import android.os.Bundle; |
| 10 | import android.os.Environment; | 10 | import android.os.Environment; |
| 11 | +import android.util.Log; | ||
| 11 | import android.view.View; | 12 | import android.view.View; |
| 12 | 13 | ||
| 13 | import com.cnlive.media.ImagePicker; | 14 | import com.cnlive.media.ImagePicker; |
| @@ -60,7 +61,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | @@ -60,7 +61,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | ||
| 60 | .maxVideoSize(100 * 1024 * 1024) | 61 | .maxVideoSize(100 * 1024 * 1024) |
| 61 | .isReturnUri(AndroidQUtil.isAndroidQ()) | 62 | .isReturnUri(AndroidQUtil.isAndroidQ()) |
| 62 | .selectMode(PickerConfig.PICKER_IMAGE) | 63 | .selectMode(PickerConfig.PICKER_IMAGE) |
| 63 | - .defaultSelectList(new ArrayList<Media>()) | 64 | + .defaultSelectList(select) |
| 64 | // .doCrop(1, 1, 40, 40) | 65 | // .doCrop(1, 1, 40, 40) |
| 65 | .needCamera(true) | 66 | .needCamera(true) |
| 66 | .builder() | 67 | .builder() |
| @@ -87,8 +88,12 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | @@ -87,8 +88,12 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | ||
| 87 | new ImagePicker | 88 | new ImagePicker |
| 88 | .Builder() | 89 | .Builder() |
| 89 | .setJumpCameraMode(PickerConfig.CAMERA_MODE_ALL) | 90 | .setJumpCameraMode(PickerConfig.CAMERA_MODE_ALL) |
| 91 | + .needCamera(true) | ||
| 92 | + .setFrontCamera(false) | ||
| 93 | + .defaultSelectList(select) | ||
| 90 | .builder() | 94 | .builder() |
| 91 | .startCamera(this, select, PickerConfig.PICKER_IMAGE, PickerConfig.DEFAULT_RESULT_CODE); | 95 | .startCamera(this, select, PickerConfig.PICKER_IMAGE, PickerConfig.DEFAULT_RESULT_CODE); |
| 96 | +// OnLineAnswerActivity.start(MainActivity.this, System.currentTimeMillis() / 1000, "102", new ArrayList<Media>()); | ||
| 92 | break; | 97 | break; |
| 93 | case R.id.bt_preview: | 98 | case R.id.bt_preview: |
| 94 | //打开预览 | 99 | //打开预览 |
app/src/main/java/com/cnlive/strike/debug/MediaApplication.java
| @@ -4,8 +4,7 @@ import android.app.Application; | @@ -4,8 +4,7 @@ import android.app.Application; | ||
| 4 | 4 | ||
| 5 | import androidx.multidex.MultiDex; | 5 | import androidx.multidex.MultiDex; |
| 6 | 6 | ||
| 7 | -import com.cnlive.media.utils.QiniuVideoUtil; | ||
| 8 | - | 7 | +import com.alibaba.android.arouter.launcher.ARouter; |
| 9 | 8 | ||
| 10 | 9 | ||
| 11 | public class MediaApplication extends Application { | 10 | public class MediaApplication extends Application { |
| @@ -14,6 +13,5 @@ public class MediaApplication extends Application { | @@ -14,6 +13,5 @@ public class MediaApplication extends Application { | ||
| 14 | super.onCreate(); | 13 | super.onCreate(); |
| 15 | // ARouter.init(this); | 14 | // ARouter.init(this); |
| 16 | MultiDex.install(this); | 15 | MultiDex.install(this); |
| 17 | - QiniuVideoUtil.initVideo(this); | ||
| 18 | } | 16 | } |
| 19 | } | 17 | } |
config.gradle
lib_media/build.gradle
| @@ -57,7 +57,7 @@ dependencies { | @@ -57,7 +57,7 @@ dependencies { | ||
| 57 | implementation "com.alibaba:arouter-api:$rootProject.arouterApiVersion" | 57 | implementation "com.alibaba:arouter-api:$rootProject.arouterApiVersion" |
| 58 | annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterCompilerVersion" | 58 | annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterCompilerVersion" |
| 59 | //七牛录制视频 | 59 | //七牛录制视频 |
| 60 | - implementation "com.cnlive.libs:video_qiniu:$rootProject.libVideoQiniu" | 60 | +// implementation "com.cnlive.libs:video_qiniu:$rootProject.libVideoQiniu" |
| 61 | implementation "com.qiniu:qiniu-android-sdk:$rootProject.qiniuAndroidSdk" | 61 | implementation "com.qiniu:qiniu-android-sdk:$rootProject.qiniuAndroidSdk" |
| 62 | 62 | ||
| 63 | implementation "com.cnlive.base:lib_util:$rootProject.libCnUtil" | 63 | implementation "com.cnlive.base:lib_util:$rootProject.libCnUtil" |
lib_media/src/main/AndroidManifest.xml
| @@ -17,11 +17,13 @@ | @@ -17,11 +17,13 @@ | ||
| 17 | <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" /> | 17 | <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" /> |
| 18 | <uses-permission android:name="com.sec.android.provider.badge.permission.READ" /> | 18 | <uses-permission android:name="com.sec.android.provider.badge.permission.READ" /> |
| 19 | <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" /> | 19 | <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" /> |
| 20 | + | ||
| 20 | <uses-feature android:name="android.hardware.camera" /> | 21 | <uses-feature android:name="android.hardware.camera" /> |
| 21 | <uses-feature android:name="android.hardware.camera.autofocus" /> | 22 | <uses-feature android:name="android.hardware.camera.autofocus" /> |
| 23 | + | ||
| 22 | <application | 24 | <application |
| 23 | - android:resizeableActivity="true" | ||
| 24 | - android:largeHeap="true"> | 25 | + android:largeHeap="true" |
| 26 | + android:resizeableActivity="true"> | ||
| 25 | <activity | 27 | <activity |
| 26 | android:name="com.cnlive.media.ui.activity.MediaActivity" | 28 | android:name="com.cnlive.media.ui.activity.MediaActivity" |
| 27 | android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" | 29 | android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" |
| @@ -60,6 +62,19 @@ | @@ -60,6 +62,19 @@ | ||
| 60 | android:screenOrientation="portrait" | 62 | android:screenOrientation="portrait" |
| 61 | android:theme="@style/Theme.AppCompat.NoActionBar" | 63 | android:theme="@style/Theme.AppCompat.NoActionBar" |
| 62 | android:windowSoftInputMode="stateAlwaysHidden" /> | 64 | android:windowSoftInputMode="stateAlwaysHidden" /> |
| 65 | + <activity | ||
| 66 | + android:name=".ui.activity.DiyCameraActivity" | ||
| 67 | + android:configChanges="keyboardHidden|screenSize|orientation|smallestScreenSize|screenLayout" | ||
| 68 | + android:launchMode="singleTop" | ||
| 69 | + android:resizeableActivity="true" | ||
| 70 | + android:screenOrientation="portrait" | ||
| 71 | + android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" /> | ||
| 63 | 72 | ||
| 73 | + <activity | ||
| 74 | + android:name=".ui.activity.OnLineAnswerActivity" | ||
| 75 | + android:configChanges="keyboardHidden|screenSize|orientation|smallestScreenSize|screenLayout" | ||
| 76 | + android:resizeableActivity="true" | ||
| 77 | + android:screenOrientation="portrait" | ||
| 78 | + android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" /> | ||
| 64 | </application> | 79 | </application> |
| 65 | </manifest> | 80 | </manifest> |
| 66 | \ No newline at end of file | 81 | \ No newline at end of file |
lib_media/src/main/java/com/cnlive/media/ImagePicker.java
| @@ -4,14 +4,14 @@ import android.app.Activity; | @@ -4,14 +4,14 @@ import android.app.Activity; | ||
| 4 | import android.app.Fragment; | 4 | import android.app.Fragment; |
| 5 | import android.content.Context; | 5 | import android.content.Context; |
| 6 | import android.content.Intent; | 6 | import android.content.Intent; |
| 7 | +import android.util.Log; | ||
| 7 | 8 | ||
| 8 | import com.cnlive.media.model.ImagePickerCropParams; | 9 | import com.cnlive.media.model.ImagePickerCropParams; |
| 9 | import com.cnlive.media.model.ImagePickerOptions; | 10 | import com.cnlive.media.model.ImagePickerOptions; |
| 10 | import com.cnlive.media.media.entity.Media; | 11 | import com.cnlive.media.media.entity.Media; |
| 12 | +import com.cnlive.media.ui.activity.DiyCameraActivity; | ||
| 11 | import com.cnlive.media.ui.activity.MediaActivity; | 13 | import com.cnlive.media.ui.activity.MediaActivity; |
| 12 | import com.cnlive.media.ui.activity.MediaPreviewActivity; | 14 | import com.cnlive.media.ui.activity.MediaPreviewActivity; |
| 13 | -import com.cnlive.media.ui.activity.RecordActivity; | ||
| 14 | -import com.qiniu.pili.droid.shortvideo.PLShortVideoEnv; | ||
| 15 | 15 | ||
| 16 | import java.util.ArrayList; | 16 | import java.util.ArrayList; |
| 17 | 17 | ||
| @@ -70,7 +70,7 @@ public class ImagePicker { | @@ -70,7 +70,7 @@ public class ImagePicker { | ||
| 70 | * @param resultCode 结果码 | 70 | * @param resultCode 结果码 |
| 71 | */ | 71 | */ |
| 72 | public void startCamera(Activity activity, int requestCode, int resultCode) { | 72 | public void startCamera(Activity activity, int requestCode, int resultCode) { |
| 73 | - Intent intent = new Intent(activity, RecordActivity.class); | 73 | + Intent intent = new Intent(activity, DiyCameraActivity.class); |
| 74 | intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | 74 | intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); |
| 75 | intent.putExtra(PickerConfig.RESULT_CODE, resultCode); | 75 | intent.putExtra(PickerConfig.RESULT_CODE, resultCode); |
| 76 | intent.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true); | 76 | intent.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true); |
| @@ -84,14 +84,16 @@ public class ImagePicker { | @@ -84,14 +84,16 @@ public class ImagePicker { | ||
| 84 | * @param requestCode 请求码 | 84 | * @param requestCode 请求码 |
| 85 | * @param resultCode 结果码 | 85 | * @param resultCode 结果码 |
| 86 | */ | 86 | */ |
| 87 | - public void startCamera(Activity activity, ArrayList<Media> selectMedia,int requestCode, int resultCode) { | ||
| 88 | - if (selectMedia==null)selectMedia=new ArrayList<>(); | ||
| 89 | - Intent intent = new Intent(activity, RecordActivity.class); | ||
| 90 | - intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | ||
| 91 | - intent.putExtra(PickerConfig.RESULT_CODE, resultCode); | ||
| 92 | - intent.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true); | ||
| 93 | - intent.putParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS, selectMedia); | ||
| 94 | - activity.startActivityForResult(intent, requestCode); | 87 | + public void startCamera(Activity activity, ArrayList<Media> selectMedia, int requestCode, int resultCode) { |
| 88 | +// if (selectMedia==null)selectMedia=new ArrayList<>(); | ||
| 89 | +// Intent intent = new Intent(activity, RecordActivity.class); | ||
| 90 | +// intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | ||
| 91 | +// intent.putExtra(PickerConfig.RESULT_CODE, resultCode); | ||
| 92 | +// intent.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true); | ||
| 93 | +// intent.putParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS, selectMedia); | ||
| 94 | +// activity.startActivityForResult(intent, requestCode); | ||
| 95 | + | ||
| 96 | + DiyCameraActivity.start(activity,selectMedia, mOptions, resultCode); | ||
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | /** | 99 | /** |
| @@ -161,6 +163,11 @@ public class ImagePicker { | @@ -161,6 +163,11 @@ public class ImagePicker { | ||
| 161 | return this; | 163 | return this; |
| 162 | } | 164 | } |
| 163 | 165 | ||
| 166 | + public Builder setFrontCamera(boolean frontCamera) { | ||
| 167 | + mOptions.setFrontCamera(frontCamera); | ||
| 168 | + return this; | ||
| 169 | + } | ||
| 170 | + | ||
| 164 | public Builder maxTime(int maxTime) { | 171 | public Builder maxTime(int maxTime) { |
| 165 | mOptions.setMaxTime(maxTime); | 172 | mOptions.setMaxTime(maxTime); |
| 166 | return this; | 173 | return this; |
lib_media/src/main/java/com/cnlive/media/frame/presenter/RecordFragmentPresenter.java
| 1 | -package com.cnlive.media.frame.presenter; | ||
| 2 | - | ||
| 3 | -import com.cnlive.media.frame.view.RecordFragmentView; | ||
| 4 | -import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 作 者 : wkq | ||
| 8 | - * <p> | ||
| 9 | - * 时 间 : 2020/10/29 10:06 | ||
| 10 | - * <p> | ||
| 11 | - * 名 字 : RecordFragmentPresenter | ||
| 12 | - * <p> | ||
| 13 | - * 简 介 : | ||
| 14 | - */ | ||
| 15 | -public class RecordFragmentPresenter extends MvpBasePresenter<RecordFragmentView> { | ||
| 16 | - | ||
| 17 | -} | 1 | +//package com.cnlive.media.frame.presenter; |
| 2 | +// | ||
| 3 | +//import com.cnlive.media.frame.view.RecordFragmentView; | ||
| 4 | +//import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | ||
| 5 | +// | ||
| 6 | +///** | ||
| 7 | +// * 作 者 : wkq | ||
| 8 | +// * <p> | ||
| 9 | +// * 时 间 : 2020/10/29 10:06 | ||
| 10 | +// * <p> | ||
| 11 | +// * 名 字 : RecordFragmentPresenter | ||
| 12 | +// * <p> | ||
| 13 | +// * 简 介 : | ||
| 14 | +// */ | ||
| 15 | +//public class RecordFragmentPresenter extends MvpBasePresenter<RecordFragmentView> { | ||
| 16 | +// | ||
| 17 | +//} |
lib_media/src/main/java/com/cnlive/media/frame/presenter/RecordPresenter.java
| 1 | -package com.cnlive.media.frame.presenter; | ||
| 2 | - | ||
| 3 | -import android.app.Activity; | ||
| 4 | -import android.content.pm.PackageManager; | ||
| 5 | -import android.os.Build; | ||
| 6 | -import android.text.TextUtils; | ||
| 7 | - | ||
| 8 | -import androidx.core.app.ActivityCompat; | ||
| 9 | - | ||
| 10 | -import com.cnlive.media.frame.view.RecordView; | ||
| 11 | -import com.cnlive.media.ui.activity.RecordActivity; | ||
| 12 | -import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | ||
| 13 | - | ||
| 14 | -import java.util.ArrayList; | ||
| 15 | -import java.util.List; | ||
| 16 | - | ||
| 17 | -/** | ||
| 18 | - * 作 者 : wkq | ||
| 19 | - * <p> | ||
| 20 | - * 时 间 : 2020/9/22 13:33 | ||
| 21 | - * <p> | ||
| 22 | - * 名 字 : RecordPresenter | ||
| 23 | - * <p> | ||
| 24 | - * 简 介 : | ||
| 25 | - */ | ||
| 26 | -public class RecordPresenter extends MvpBasePresenter<RecordView> { | ||
| 27 | - | ||
| 28 | - public boolean checkPermissions(Activity activity, String[] permissions, int requestCode, boolean request) { | ||
| 29 | - //Android6.0以下默认有权限 | ||
| 30 | - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) | ||
| 31 | - return true; | ||
| 32 | - | ||
| 33 | - List<String> needList = new ArrayList<>(); | ||
| 34 | - boolean needShowRationale = false; | ||
| 35 | - | ||
| 36 | - for (String permisson : permissions) { | ||
| 37 | - if (TextUtils.isEmpty(permisson)) continue; | ||
| 38 | - if (ActivityCompat.checkSelfPermission(activity, permisson) | ||
| 39 | - != PackageManager.PERMISSION_GRANTED) { | ||
| 40 | - needList.add(permisson); | ||
| 41 | - if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permisson)) | ||
| 42 | - needShowRationale = true; | ||
| 43 | - } | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | - if (needList.size() != 0) { | ||
| 47 | - final int count = needList.size(); | ||
| 48 | - String[] needArray = needList.toArray(new String[count]); | ||
| 49 | - if (needShowRationale) { | ||
| 50 | - getView().showPermission(needArray, requestCode); | ||
| 51 | - } else if (request) { | ||
| 52 | - ActivityCompat.requestPermissions(activity, needArray, requestCode); | ||
| 53 | - } | ||
| 54 | - return false; | ||
| 55 | - } else { | ||
| 56 | - return true; | ||
| 57 | - } | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | - public boolean[] onRequestPermissionsResult(RecordActivity recordActivity, int requestCode, String[] permissions, int[] grantResults) { | ||
| 61 | - | ||
| 62 | - boolean result = true; | ||
| 63 | - boolean isNeverAsk = false; | ||
| 64 | - | ||
| 65 | - int length = grantResults.length; | ||
| 66 | - for (int i = 0; i < length; i++) { | ||
| 67 | - String permission = permissions[i]; | ||
| 68 | - int grandResult = grantResults[i]; | ||
| 69 | - if (grandResult == PackageManager.PERMISSION_DENIED) { | ||
| 70 | - result = false; | ||
| 71 | - if (!ActivityCompat.shouldShowRequestPermissionRationale(recordActivity, permission)) | ||
| 72 | - isNeverAsk = true; | ||
| 73 | - } | ||
| 74 | - } | ||
| 75 | - | ||
| 76 | - return new boolean[]{result, isNeverAsk}; | ||
| 77 | - } | ||
| 78 | -} | 1 | +//package com.cnlive.media.frame.presenter; |
| 2 | +// | ||
| 3 | +//import android.app.Activity; | ||
| 4 | +//import android.content.pm.PackageManager; | ||
| 5 | +//import android.os.Build; | ||
| 6 | +//import android.text.TextUtils; | ||
| 7 | +// | ||
| 8 | +//import androidx.core.app.ActivityCompat; | ||
| 9 | +// | ||
| 10 | +//import com.cnlive.media.frame.view.RecordView; | ||
| 11 | +//import com.cnlive.media.ui.activity.RecordActivity; | ||
| 12 | +//import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | ||
| 13 | +// | ||
| 14 | +//import java.util.ArrayList; | ||
| 15 | +//import java.util.List; | ||
| 16 | +// | ||
| 17 | +///** | ||
| 18 | +// * 作 者 : wkq | ||
| 19 | +// * <p> | ||
| 20 | +// * 时 间 : 2020/9/22 13:33 | ||
| 21 | +// * <p> | ||
| 22 | +// * 名 字 : RecordPresenter | ||
| 23 | +// * <p> | ||
| 24 | +// * 简 介 : | ||
| 25 | +// */ | ||
| 26 | +//public class RecordPresenter extends MvpBasePresenter<RecordView> { | ||
| 27 | +// | ||
| 28 | +// public boolean checkPermissions(Activity activity, String[] permissions, int requestCode, boolean request) { | ||
| 29 | +// //Android6.0以下默认有权限 | ||
| 30 | +// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) | ||
| 31 | +// return true; | ||
| 32 | +// | ||
| 33 | +// List<String> needList = new ArrayList<>(); | ||
| 34 | +// boolean needShowRationale = false; | ||
| 35 | +// | ||
| 36 | +// for (String permisson : permissions) { | ||
| 37 | +// if (TextUtils.isEmpty(permisson)) continue; | ||
| 38 | +// if (ActivityCompat.checkSelfPermission(activity, permisson) | ||
| 39 | +// != PackageManager.PERMISSION_GRANTED) { | ||
| 40 | +// needList.add(permisson); | ||
| 41 | +// if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permisson)) | ||
| 42 | +// needShowRationale = true; | ||
| 43 | +// } | ||
| 44 | +// } | ||
| 45 | +// | ||
| 46 | +// if (needList.size() != 0) { | ||
| 47 | +// final int count = needList.size(); | ||
| 48 | +// String[] needArray = needList.toArray(new String[count]); | ||
| 49 | +// if (needShowRationale) { | ||
| 50 | +// getView().showPermission(needArray, requestCode); | ||
| 51 | +// } else if (request) { | ||
| 52 | +// ActivityCompat.requestPermissions(activity, needArray, requestCode); | ||
| 53 | +// } | ||
| 54 | +// return false; | ||
| 55 | +// } else { | ||
| 56 | +// return true; | ||
| 57 | +// } | ||
| 58 | +// } | ||
| 59 | +// | ||
| 60 | +// public boolean[] onRequestPermissionsResult(RecordActivity recordActivity, int requestCode, String[] permissions, int[] grantResults) { | ||
| 61 | +// | ||
| 62 | +// boolean result = true; | ||
| 63 | +// boolean isNeverAsk = false; | ||
| 64 | +// | ||
| 65 | +// int length = grantResults.length; | ||
| 66 | +// for (int i = 0; i < length; i++) { | ||
| 67 | +// String permission = permissions[i]; | ||
| 68 | +// int grandResult = grantResults[i]; | ||
| 69 | +// if (grandResult == PackageManager.PERMISSION_DENIED) { | ||
| 70 | +// result = false; | ||
| 71 | +// if (!ActivityCompat.shouldShowRequestPermissionRationale(recordActivity, permission)) | ||
| 72 | +// isNeverAsk = true; | ||
| 73 | +// } | ||
| 74 | +// } | ||
| 75 | +// | ||
| 76 | +// return new boolean[]{result, isNeverAsk}; | ||
| 77 | +// } | ||
| 78 | +//} |
lib_media/src/main/java/com/cnlive/media/frame/presenter/RecordPreviewPresenter.java
| 1 | -package com.cnlive.media.frame.presenter; | ||
| 2 | - | ||
| 3 | -import com.cnlive.media.frame.view.RecordPreviewView; | ||
| 4 | -import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 作 者 : wkq | ||
| 8 | - * <p> | ||
| 9 | - * 时 间 : 2020/9/28 9:36 | ||
| 10 | - * <p> | ||
| 11 | - * 名 字 : RecordPreviewPresenter | ||
| 12 | - * <p> | ||
| 13 | - * 简 介 : | ||
| 14 | - */ | ||
| 15 | -public class RecordPreviewPresenter extends MvpBasePresenter<RecordPreviewView> { | ||
| 16 | -} | 1 | +//package com.cnlive.media.frame.presenter; |
| 2 | +// | ||
| 3 | +//import com.cnlive.media.frame.view.RecordPreviewView; | ||
| 4 | +//import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | ||
| 5 | +// | ||
| 6 | +///** | ||
| 7 | +// * 作 者 : wkq | ||
| 8 | +// * <p> | ||
| 9 | +// * 时 间 : 2020/9/28 9:36 | ||
| 10 | +// * <p> | ||
| 11 | +// * 名 字 : RecordPreviewPresenter | ||
| 12 | +// * <p> | ||
| 13 | +// * 简 介 : | ||
| 14 | +// */ | ||
| 15 | +//public class RecordPreviewPresenter extends MvpBasePresenter<RecordPreviewView> { | ||
| 16 | +//} |
lib_media/src/main/java/com/cnlive/media/frame/view/MediaView.java
| @@ -28,9 +28,9 @@ import com.cnlive.libs.base.util.StatusBarUtil2; | @@ -28,9 +28,9 @@ import com.cnlive.libs.base.util.StatusBarUtil2; | ||
| 28 | import com.cnlive.media.PickerConfig; | 28 | import com.cnlive.media.PickerConfig; |
| 29 | import com.cnlive.media.media.entity.Folder; | 29 | import com.cnlive.media.media.entity.Folder; |
| 30 | import com.cnlive.media.media.entity.Media; | 30 | import com.cnlive.media.media.entity.Media; |
| 31 | +import com.cnlive.media.ui.activity.DiyCameraActivity; | ||
| 31 | import com.cnlive.media.ui.activity.ImageCropActivity; | 32 | import com.cnlive.media.ui.activity.ImageCropActivity; |
| 32 | import com.cnlive.media.ui.activity.MediaActivity; | 33 | import com.cnlive.media.ui.activity.MediaActivity; |
| 33 | -import com.cnlive.media.ui.activity.RecordActivity; | ||
| 34 | import com.cnlive.media.ui.adapter.FolderAdapter; | 34 | import com.cnlive.media.ui.adapter.FolderAdapter; |
| 35 | import com.cnlive.media.ui.adapter.PreviewBottomMediaAdapter; | 35 | import com.cnlive.media.ui.adapter.PreviewBottomMediaAdapter; |
| 36 | import com.cnlive.media.ui.fragment.MediaPickerFragment; | 36 | import com.cnlive.media.ui.fragment.MediaPickerFragment; |
| @@ -49,10 +49,10 @@ import com.cnlive.media.utils.observable.MeidaResultObservable; | @@ -49,10 +49,10 @@ import com.cnlive.media.utils.observable.MeidaResultObservable; | ||
| 49 | import com.cnlive.media.utils.observable.SelectStateUpdateObservable; | 49 | import com.cnlive.media.utils.observable.SelectStateUpdateObservable; |
| 50 | import com.cnlive.media.R; | 50 | import com.cnlive.media.R; |
| 51 | import com.hannesdorfmann.mosby3.mvp.MvpView; | 51 | import com.hannesdorfmann.mosby3.mvp.MvpView; |
| 52 | -import com.qiniu.pili.droid.shortvideo.PLShortVideoEnv; | ||
| 53 | 52 | ||
| 54 | import java.util.ArrayList; | 53 | import java.util.ArrayList; |
| 55 | 54 | ||
| 55 | +import static com.cnlive.media.PickerConfig.DEFAULT_RESULT_CODE; | ||
| 56 | import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_CAMERA; | 56 | import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_CAMERA; |
| 57 | import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_READ; | 57 | import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_READ; |
| 58 | 58 | ||
| @@ -105,8 +105,6 @@ public class MediaView implements MvpView { | @@ -105,8 +105,6 @@ public class MediaView implements MvpView { | ||
| 105 | 105 | ||
| 106 | private void initState() { | 106 | private void initState() { |
| 107 | StatusBarUtil2.setColor(mActivity, mActivity.getResources().getColor(R.color.status_bar_color), 0); | 107 | StatusBarUtil2.setColor(mActivity, mActivity.getResources().getColor(R.color.status_bar_color), 0); |
| 108 | -// //初始化七牛录制 | ||
| 109 | - PLShortVideoEnv.init(mActivity.getApplicationContext()); | ||
| 110 | MediaAddObservable.getInstance().addObserver(mActivity); | 108 | MediaAddObservable.getInstance().addObserver(mActivity); |
| 111 | MeidaResultObservable.getInstance().addObserver(mActivity); | 109 | MeidaResultObservable.getInstance().addObserver(mActivity); |
| 112 | MediaSelectStateObservable.getInstance().addObserver(mActivity); | 110 | MediaSelectStateObservable.getInstance().addObserver(mActivity); |
| @@ -536,13 +534,13 @@ public class MediaView implements MvpView { | @@ -536,13 +534,13 @@ public class MediaView implements MvpView { | ||
| 536 | ), | 534 | ), |
| 537 | false); | 535 | false); |
| 538 | if (hasPermissions) { | 536 | if (hasPermissions) { |
| 539 | - RecordActivity.newInstance(mActivity, mActivity.mOptions); | 537 | + DiyCameraActivity.start(mActivity,new ArrayList<>(),mActivity.mOptions,DEFAULT_RESULT_CODE); |
| 540 | } | 538 | } |
| 541 | } | 539 | } |
| 542 | ); | 540 | ); |
| 543 | 541 | ||
| 544 | if (hasPermission) { | 542 | if (hasPermission) { |
| 545 | - RecordActivity.newInstance(mActivity, mActivity.mOptions); | 543 | + DiyCameraActivity.start(mActivity,new ArrayList<>(),mActivity.mOptions,DEFAULT_RESULT_CODE); |
| 546 | } | 544 | } |
| 547 | } | 545 | } |
| 548 | 546 |
lib_media/src/main/java/com/cnlive/media/frame/view/RecordFragmentView.java
| 1 | -package com.cnlive.media.frame.view; | ||
| 2 | - | ||
| 3 | -import android.animation.Animator; | ||
| 4 | -import android.animation.AnimatorSet; | ||
| 5 | -import android.animation.ObjectAnimator; | ||
| 6 | -import android.os.Environment; | ||
| 7 | -import android.text.TextUtils; | ||
| 8 | -import android.util.Log; | ||
| 9 | -import android.view.MotionEvent; | ||
| 10 | -import android.view.View; | ||
| 11 | -import android.view.animation.OvershootInterpolator; | ||
| 12 | - | ||
| 13 | -import com.cnlive.libs.base.util.AlertUtil; | ||
| 14 | -import com.cnlive.media.PickerConfig; | ||
| 15 | -import com.cnlive.media.ui.activity.RecordActivity; | ||
| 16 | -import com.cnlive.media.ui.fragment.RecordFragment; | ||
| 17 | -import com.cnlive.media.utils.AndroidQUtil; | ||
| 18 | -import com.cnlive.media.utils.SamsungCamaerUtil; | ||
| 19 | -import com.cnlive.media.utils.ScreenUtils; | ||
| 20 | -import com.hannesdorfmann.mosby3.mvp.MvpView; | ||
| 21 | -import com.qiniu.pili.droid.shortvideo.PLAudioEncodeSetting; | ||
| 22 | -import com.qiniu.pili.droid.shortvideo.PLCameraSetting; | ||
| 23 | -import com.qiniu.pili.droid.shortvideo.PLDisplayMode; | ||
| 24 | -import com.qiniu.pili.droid.shortvideo.PLMicrophoneSetting; | ||
| 25 | -import com.qiniu.pili.droid.shortvideo.PLRecordSetting; | ||
| 26 | -import com.qiniu.pili.droid.shortvideo.PLRecordStateListener; | ||
| 27 | -import com.qiniu.pili.droid.shortvideo.PLShortVideoRecorder; | ||
| 28 | -import com.qiniu.pili.droid.shortvideo.PLVideoEncodeSetting; | ||
| 29 | - | ||
| 30 | -import java.io.File; | ||
| 31 | - | ||
| 32 | -/** | ||
| 33 | - * 作 者 : wkq | ||
| 34 | - * <p> | ||
| 35 | - * 时 间 : 2020/10/29 10:05 | ||
| 36 | - * <p> | ||
| 37 | - * 名 字 : RecordFragmentView | ||
| 38 | - * <p> | ||
| 39 | - * 简 介 : | ||
| 40 | - */ | ||
| 41 | -public class RecordFragmentView implements MvpView, PLRecordStateListener { | ||
| 42 | - | ||
| 43 | - RecordFragment mFragment; | ||
| 44 | - private PLRecordSetting recordSetting; | ||
| 45 | - private PLAudioEncodeSetting audioEncodeSetting; | ||
| 46 | - private PLMicrophoneSetting microphoneSetting; | ||
| 47 | - private PLVideoEncodeSetting videoEncodeSetting; | ||
| 48 | - private PLCameraSetting cameraSetting; | ||
| 49 | - String videoCaceDirPath; | ||
| 50 | - | ||
| 51 | - public RecordFragmentView(RecordFragment mFragment) { | ||
| 52 | - this.mFragment = mFragment; | ||
| 53 | - } | ||
| 54 | - | ||
| 55 | - public RecordActivity getActivity() { | ||
| 56 | - return (RecordActivity) mFragment.getActivity(); | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - public void initView() { | ||
| 60 | - | ||
| 61 | - if (getActivity().mOptions == null) { | ||
| 62 | - //Activity 缓存数据失效,一般情况是App被系统回收 | ||
| 63 | - return; | ||
| 64 | - } | ||
| 65 | - // 摄像头采集选项 | ||
| 66 | - if (mFragment.plShortVideoRecorder == null) | ||
| 67 | - mFragment.plShortVideoRecorder = new PLShortVideoRecorder(); | ||
| 68 | - if (cameraSetting == null) | ||
| 69 | - cameraSetting = new PLCameraSetting(); | ||
| 70 | - //设置摄像头 | ||
| 71 | - if (SamsungCamaerUtil.isSamsungAndOpenFont(mFragment.getActivity())) { | ||
| 72 | - cameraSetting.setCameraId(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_FRONT); | ||
| 73 | - } else { | ||
| 74 | - cameraSetting.setCameraId(chooseCameraFacingId()); | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - cameraSetting.setCameraPreviewSizeRatio(PLCameraSetting.CAMERA_PREVIEW_SIZE_RATIO.RATIO_16_9); | ||
| 78 | - cameraSetting.setCameraPreviewSizeLevel(PLCameraSetting.CAMERA_PREVIEW_SIZE_LEVEL.PREVIEW_SIZE_LEVEL_720P); | ||
| 79 | - // 麦克风采集选项 | ||
| 80 | - if (microphoneSetting == null) | ||
| 81 | - microphoneSetting = new PLMicrophoneSetting(); | ||
| 82 | - // 视频编码选项 | ||
| 83 | - videoEncodeSetting = new PLVideoEncodeSetting(mFragment.getActivity()); | ||
| 84 | - videoEncodeSetting.setEncodingSizeLevel(PLVideoEncodeSetting.VIDEO_ENCODING_SIZE_LEVEL.VIDEO_ENCODING_SIZE_LEVEL_720P_3); // 480x480 | ||
| 85 | - videoEncodeSetting.setEncodingBitrate(4000 * 1024); // 1000kbps | ||
| 86 | - videoEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编 | ||
| 87 | - // 音频编码选项 | ||
| 88 | - audioEncodeSetting = new PLAudioEncodeSetting(); | ||
| 89 | - audioEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编 | ||
| 90 | - // 美颜选项 | ||
| 91 | - // 录制选项 | ||
| 92 | - recordSetting = new PLRecordSetting(); | ||
| 93 | - //最大录制时常 | ||
| 94 | - //不限制七牛SDK录制时长,因为删除片段后SDK仍记录已删除片段的时间,重新录制时会导致录制时间缩短或合成失败 | ||
| 95 | - //目前通过计时器进行最大时长限制即可 | ||
| 96 | - recordSetting.setMaxRecordDuration(24 * 60 * 60 * 1000); | ||
| 97 | - | ||
| 98 | - recordSetting.setRecordSpeedVariable(true); | ||
| 99 | - recordSetting.setDisplayMode(PLDisplayMode.FULL); | ||
| 100 | - | ||
| 101 | - | ||
| 102 | - if (getActivity().mOptions == null || TextUtils.isEmpty(getActivity().mOptions.getCachePath())) { | ||
| 103 | - if (AndroidQUtil.isAndroidQ()) { | ||
| 104 | - videoCaceDirPath = getActivity().getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo"; | ||
| 105 | - } else { | ||
| 106 | - videoCaceDirPath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerVideo"; | ||
| 107 | - } | ||
| 108 | - } else { | ||
| 109 | - if (AndroidQUtil.isAndroidQ()) { | ||
| 110 | - videoCaceDirPath = mFragment.getActivity().getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo"; | ||
| 111 | - } else { | ||
| 112 | - videoCaceDirPath = getActivity().mOptions.getCachePath(); | ||
| 113 | - } | ||
| 114 | - } | ||
| 115 | - getActivity().mOptions.setCachePath(videoCaceDirPath); | ||
| 116 | - recordSetting.setVideoCacheDir(videoCaceDirPath); | ||
| 117 | - | ||
| 118 | - getActivity().videoPath = getActivity().mOptions.getCachePath() + System.currentTimeMillis() + ".mp4"; | ||
| 119 | - recordSetting.setVideoFilepath(getActivity().videoPath); | ||
| 120 | - mFragment.binding.rcControl.setFlashState(false); | ||
| 121 | - mFragment.binding.rcControl.setMaxTime(getActivity().mOptions.getMaxTime()); | ||
| 122 | - | ||
| 123 | - //设置闪光灯 | ||
| 124 | - | ||
| 125 | - // 设置录制速度 (默认为 1.0) | ||
| 126 | - mFragment.plShortVideoRecorder.setRecordStateListener(this); | ||
| 127 | - | ||
| 128 | - mFragment.plShortVideoRecorder.prepare(mFragment.binding.gSf, cameraSetting, microphoneSetting, videoEncodeSetting, audioEncodeSetting, null, recordSetting); | ||
| 129 | - //处理手动对焦事件 | ||
| 130 | - mFragment.binding.gSf.requestRender(); | ||
| 131 | - mFragment.binding.gSf.setOnTouchListener(new View.OnTouchListener() { | ||
| 132 | - @Override | ||
| 133 | - public boolean onTouch(View v, MotionEvent event) { | ||
| 134 | - if (event.getAction() == MotionEvent.ACTION_UP) { | ||
| 135 | - moveFocus(event.getRawX(), event.getRawY()); | ||
| 136 | - } | ||
| 137 | - return true; | ||
| 138 | - } | ||
| 139 | - }); | ||
| 140 | - //如果是裁剪类型只支持拍照 | ||
| 141 | - if (getActivity().isJumpCamera || getActivity().mOptions.getJumpCameraMode() >= 0) { | ||
| 142 | - mFragment.binding.rcControl.setRecordType(getActivity().mOptions.getJumpCameraMode()); | ||
| 143 | - } else { | ||
| 144 | - if (getActivity().mOptions.isNeedCrop()) { | ||
| 145 | - mFragment.binding.rcControl.setRecordType(PickerConfig.CAMERA_MODE_PIC); | ||
| 146 | - } else { | ||
| 147 | - mFragment.binding.rcControl.setRecordType(PickerConfig.CAMERA_MODE_ALL); | ||
| 148 | - } | ||
| 149 | - } | ||
| 150 | - } | ||
| 151 | - | ||
| 152 | - /** | ||
| 153 | - * 选择相机 | ||
| 154 | - * | ||
| 155 | - * @return | ||
| 156 | - */ | ||
| 157 | - private PLCameraSetting.CAMERA_FACING_ID chooseCameraFacingId() { | ||
| 158 | - if (PLCameraSetting.hasCameraFacing(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_3RD)) { | ||
| 159 | - return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_3RD; | ||
| 160 | - } else if (PLCameraSetting.hasCameraFacing(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK)) { | ||
| 161 | - return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK; | ||
| 162 | - } else { | ||
| 163 | - processFlash(false); | ||
| 164 | - return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_FRONT; | ||
| 165 | - } | ||
| 166 | - } | ||
| 167 | - | ||
| 168 | - /** | ||
| 169 | - * 设置闪光灯 | ||
| 170 | - * | ||
| 171 | - * @param isFlashingState | ||
| 172 | - */ | ||
| 173 | - public void processFlash(boolean isFlashingState) { | ||
| 174 | - mFragment.binding.rcControl.setFlashState(isFlashingState); | ||
| 175 | - } | ||
| 176 | - | ||
| 177 | - /** | ||
| 178 | - * 异常 | ||
| 179 | - * | ||
| 180 | - * @param message | ||
| 181 | - */ | ||
| 182 | - public void showMesage(String message) { | ||
| 183 | - | ||
| 184 | - if (TextUtils.isEmpty(message) || mFragment == null || mFragment.getActivity().isFinishing()) | ||
| 185 | - return; | ||
| 186 | - mFragment.getActivity().runOnUiThread(new Runnable() { | ||
| 187 | - @Override | ||
| 188 | - public void run() { | ||
| 189 | - AlertUtil.showDeftToast(mFragment.getActivity(), message); | ||
| 190 | - } | ||
| 191 | - }); | ||
| 192 | - | ||
| 193 | - | ||
| 194 | - } | ||
| 195 | - | ||
| 196 | - //移动对焦的动画 | ||
| 197 | - public void moveFocus(float x, float y) { | ||
| 198 | - | ||
| 199 | - mFragment.plShortVideoRecorder.manualFocus(80, 80, (int) x, (int) y); | ||
| 200 | - //缩小 | ||
| 201 | - float transX = x - ScreenUtils.getScreenWidth(getActivity()) / 2; | ||
| 202 | - | ||
| 203 | - float transY = y - ScreenUtils.getScreenHeight(getActivity()) / 2; | ||
| 204 | - ObjectAnimator translationX = ObjectAnimator.ofFloat(mFragment.binding.fv, "translationX", 0, transX); | ||
| 205 | - ObjectAnimator translationY = ObjectAnimator.ofFloat(mFragment.binding.fv, "translationY", 0, transY); | ||
| 206 | - AnimatorSet animSet = new AnimatorSet(); | ||
| 207 | - animSet.play(translationX).with(translationY); | ||
| 208 | - animSet.start(); | ||
| 209 | - animSet.addListener(new Animator.AnimatorListener() { | ||
| 210 | - @Override | ||
| 211 | - public void onAnimationStart(Animator animation) { | ||
| 212 | - | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - @Override | ||
| 216 | - public void onAnimationEnd(Animator animation) { | ||
| 217 | - mFragment.binding.fv.setVisibility(View.VISIBLE); | ||
| 218 | - } | ||
| 219 | - | ||
| 220 | - @Override | ||
| 221 | - public void onAnimationCancel(Animator animation) { | ||
| 222 | - | ||
| 223 | - } | ||
| 224 | - | ||
| 225 | - @Override | ||
| 226 | - public void onAnimationRepeat(Animator animation) { | ||
| 227 | - | ||
| 228 | - } | ||
| 229 | - }); | ||
| 230 | - ObjectAnimator scaleX = ObjectAnimator.ofFloat(mFragment.binding.fv, "scaleX", 1, 0.6f); | ||
| 231 | - ObjectAnimator scaleY = ObjectAnimator.ofFloat(mFragment.binding.fv, "scaleY", 1, 0.6f); | ||
| 232 | - | ||
| 233 | - AnimatorSet animSet2 = new AnimatorSet(); | ||
| 234 | - animSet2.play(scaleY).with(scaleX); | ||
| 235 | - animSet2.setInterpolator(new OvershootInterpolator()); | ||
| 236 | - animSet2.setDuration(800); | ||
| 237 | - animSet2.start(); | ||
| 238 | - animSet2.addListener(new Animator.AnimatorListener() { | ||
| 239 | - | ||
| 240 | - @Override | ||
| 241 | - public void onAnimationStart(Animator animation) { | ||
| 242 | - | ||
| 243 | - } | ||
| 244 | - | ||
| 245 | - @Override | ||
| 246 | - public void onAnimationEnd(Animator animation) { | ||
| 247 | - mFragment.binding.fv.setVisibility(View.GONE); | ||
| 248 | - } | ||
| 249 | - | ||
| 250 | - @Override | ||
| 251 | - public void onAnimationCancel(Animator animation) { | ||
| 252 | - | ||
| 253 | - } | ||
| 254 | - | ||
| 255 | - @Override | ||
| 256 | - public void onAnimationRepeat(Animator animation) { | ||
| 257 | - | ||
| 258 | - } | ||
| 259 | - }); | ||
| 260 | - } | ||
| 261 | - | ||
| 262 | - | ||
| 263 | - @Override | ||
| 264 | - public void onReady() { | ||
| 265 | - //设置闪光灯 | ||
| 266 | - mFragment.isReady = true; | ||
| 267 | - } | ||
| 268 | - | ||
| 269 | - @Override | ||
| 270 | - public void onError(int i) { | ||
| 271 | - showMesage("相机初始化异常"); | ||
| 272 | - mFragment.isReady = false; | ||
| 273 | - mFragment.isRecordIng = false; | ||
| 274 | - } | ||
| 275 | - | ||
| 276 | - @Override | ||
| 277 | - public void onDurationTooShort() { | ||
| 278 | - } | ||
| 279 | - | ||
| 280 | - @Override | ||
| 281 | - public void onRecordStarted() { | ||
| 282 | - } | ||
| 283 | - | ||
| 284 | - @Override | ||
| 285 | - public void onSectionRecording(long l, long l1, int i) { | ||
| 286 | - } | ||
| 287 | - | ||
| 288 | - @Override | ||
| 289 | - public void onRecordStopped() { | ||
| 290 | - Log.e("", ""); | ||
| 291 | - } | ||
| 292 | - | ||
| 293 | - @Override | ||
| 294 | - public void onSectionIncreased(long l, long l1, int i) { | ||
| 295 | - Log.e("", ""); | ||
| 296 | - } | ||
| 297 | - | ||
| 298 | - @Override | ||
| 299 | - public void onSectionDecreased(long l, long l1, int i) { | ||
| 300 | - } | ||
| 301 | - | ||
| 302 | - @Override | ||
| 303 | - public void onRecordCompleted() { | ||
| 304 | - mFragment.isReady = false; | ||
| 305 | - mFragment.isRecordIng = false; | ||
| 306 | - } | ||
| 307 | -} | 1 | +//package com.cnlive.media.frame.view; |
| 2 | +// | ||
| 3 | +//import android.animation.Animator; | ||
| 4 | +//import android.animation.AnimatorSet; | ||
| 5 | +//import android.animation.ObjectAnimator; | ||
| 6 | +//import android.os.Environment; | ||
| 7 | +//import android.text.TextUtils; | ||
| 8 | +//import android.util.Log; | ||
| 9 | +//import android.view.MotionEvent; | ||
| 10 | +//import android.view.View; | ||
| 11 | +//import android.view.animation.OvershootInterpolator; | ||
| 12 | +// | ||
| 13 | +//import com.cnlive.libs.base.util.AlertUtil; | ||
| 14 | +//import com.cnlive.media.PickerConfig; | ||
| 15 | +//import com.cnlive.media.ui.activity.RecordActivity; | ||
| 16 | +//import com.cnlive.media.ui.fragment.RecordFragment; | ||
| 17 | +//import com.cnlive.media.utils.AndroidQUtil; | ||
| 18 | +//import com.cnlive.media.utils.SamsungCamaerUtil; | ||
| 19 | +//import com.cnlive.media.utils.ScreenUtils; | ||
| 20 | +//import com.hannesdorfmann.mosby3.mvp.MvpView; | ||
| 21 | +//import com.qiniu.pili.droid.shortvideo.PLAudioEncodeSetting; | ||
| 22 | +//import com.qiniu.pili.droid.shortvideo.PLCameraSetting; | ||
| 23 | +//import com.qiniu.pili.droid.shortvideo.PLDisplayMode; | ||
| 24 | +//import com.qiniu.pili.droid.shortvideo.PLMicrophoneSetting; | ||
| 25 | +//import com.qiniu.pili.droid.shortvideo.PLRecordSetting; | ||
| 26 | +//import com.qiniu.pili.droid.shortvideo.PLRecordStateListener; | ||
| 27 | +//import com.qiniu.pili.droid.shortvideo.PLShortVideoRecorder; | ||
| 28 | +//import com.qiniu.pili.droid.shortvideo.PLVideoEncodeSetting; | ||
| 29 | +// | ||
| 30 | +//import java.io.File; | ||
| 31 | +// | ||
| 32 | +///** | ||
| 33 | +// * 作 者 : wkq | ||
| 34 | +// * <p> | ||
| 35 | +// * 时 间 : 2020/10/29 10:05 | ||
| 36 | +// * <p> | ||
| 37 | +// * 名 字 : RecordFragmentView | ||
| 38 | +// * <p> | ||
| 39 | +// * 简 介 : | ||
| 40 | +// */ | ||
| 41 | +//public class RecordFragmentView implements MvpView, PLRecordStateListener { | ||
| 42 | +// | ||
| 43 | +// RecordFragment mFragment; | ||
| 44 | +// private PLRecordSetting recordSetting; | ||
| 45 | +// private PLAudioEncodeSetting audioEncodeSetting; | ||
| 46 | +// private PLMicrophoneSetting microphoneSetting; | ||
| 47 | +// private PLVideoEncodeSetting videoEncodeSetting; | ||
| 48 | +// private PLCameraSetting cameraSetting; | ||
| 49 | +// String videoCaceDirPath; | ||
| 50 | +// | ||
| 51 | +// public RecordFragmentView(RecordFragment mFragment) { | ||
| 52 | +// this.mFragment = mFragment; | ||
| 53 | +// } | ||
| 54 | +// | ||
| 55 | +// public RecordActivity getActivity() { | ||
| 56 | +// return (RecordActivity) mFragment.getActivity(); | ||
| 57 | +// } | ||
| 58 | +// | ||
| 59 | +// public void initView() { | ||
| 60 | +// | ||
| 61 | +// if (getActivity().mOptions == null) { | ||
| 62 | +// //Activity 缓存数据失效,一般情况是App被系统回收 | ||
| 63 | +// return; | ||
| 64 | +// } | ||
| 65 | +// // 摄像头采集选项 | ||
| 66 | +// if (mFragment.plShortVideoRecorder == null) | ||
| 67 | +// mFragment.plShortVideoRecorder = new PLShortVideoRecorder(); | ||
| 68 | +// if (cameraSetting == null) | ||
| 69 | +// cameraSetting = new PLCameraSetting(); | ||
| 70 | +// //设置摄像头 | ||
| 71 | +// if (SamsungCamaerUtil.isSamsungAndOpenFont(mFragment.getActivity())) { | ||
| 72 | +// cameraSetting.setCameraId(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_FRONT); | ||
| 73 | +// } else { | ||
| 74 | +// cameraSetting.setCameraId(chooseCameraFacingId()); | ||
| 75 | +// } | ||
| 76 | +// | ||
| 77 | +// cameraSetting.setCameraPreviewSizeRatio(PLCameraSetting.CAMERA_PREVIEW_SIZE_RATIO.RATIO_16_9); | ||
| 78 | +// cameraSetting.setCameraPreviewSizeLevel(PLCameraSetting.CAMERA_PREVIEW_SIZE_LEVEL.PREVIEW_SIZE_LEVEL_720P); | ||
| 79 | +// // 麦克风采集选项 | ||
| 80 | +// if (microphoneSetting == null) | ||
| 81 | +// microphoneSetting = new PLMicrophoneSetting(); | ||
| 82 | +// // 视频编码选项 | ||
| 83 | +// videoEncodeSetting = new PLVideoEncodeSetting(mFragment.getActivity()); | ||
| 84 | +// videoEncodeSetting.setEncodingSizeLevel(PLVideoEncodeSetting.VIDEO_ENCODING_SIZE_LEVEL.VIDEO_ENCODING_SIZE_LEVEL_720P_3); // 480x480 | ||
| 85 | +// videoEncodeSetting.setEncodingBitrate(4000 * 1024); // 1000kbps | ||
| 86 | +// videoEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编 | ||
| 87 | +// // 音频编码选项 | ||
| 88 | +// audioEncodeSetting = new PLAudioEncodeSetting(); | ||
| 89 | +// audioEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编 | ||
| 90 | +// // 美颜选项 | ||
| 91 | +// // 录制选项 | ||
| 92 | +// recordSetting = new PLRecordSetting(); | ||
| 93 | +// //最大录制时常 | ||
| 94 | +// //不限制七牛SDK录制时长,因为删除片段后SDK仍记录已删除片段的时间,重新录制时会导致录制时间缩短或合成失败 | ||
| 95 | +// //目前通过计时器进行最大时长限制即可 | ||
| 96 | +// recordSetting.setMaxRecordDuration(24 * 60 * 60 * 1000); | ||
| 97 | +// | ||
| 98 | +// recordSetting.setRecordSpeedVariable(true); | ||
| 99 | +// recordSetting.setDisplayMode(PLDisplayMode.FULL); | ||
| 100 | +// | ||
| 101 | +// | ||
| 102 | +// if (getActivity().mOptions == null || TextUtils.isEmpty(getActivity().mOptions.getCachePath())) { | ||
| 103 | +// if (AndroidQUtil.isAndroidQ()) { | ||
| 104 | +// videoCaceDirPath = getActivity().getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo"; | ||
| 105 | +// } else { | ||
| 106 | +// videoCaceDirPath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerVideo"; | ||
| 107 | +// } | ||
| 108 | +// } else { | ||
| 109 | +// if (AndroidQUtil.isAndroidQ()) { | ||
| 110 | +// videoCaceDirPath = mFragment.getActivity().getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo"; | ||
| 111 | +// } else { | ||
| 112 | +// videoCaceDirPath = getActivity().mOptions.getCachePath(); | ||
| 113 | +// } | ||
| 114 | +// } | ||
| 115 | +// getActivity().mOptions.setCachePath(videoCaceDirPath); | ||
| 116 | +// recordSetting.setVideoCacheDir(videoCaceDirPath); | ||
| 117 | +// | ||
| 118 | +// getActivity().videoPath = getActivity().mOptions.getCachePath() + System.currentTimeMillis() + ".mp4"; | ||
| 119 | +// recordSetting.setVideoFilepath(getActivity().videoPath); | ||
| 120 | +// mFragment.binding.rcControl.setFlashState(false); | ||
| 121 | +// mFragment.binding.rcControl.setMaxTime(getActivity().mOptions.getMaxTime()); | ||
| 122 | +// | ||
| 123 | +// //设置闪光灯 | ||
| 124 | +// | ||
| 125 | +// // 设置录制速度 (默认为 1.0) | ||
| 126 | +// mFragment.plShortVideoRecorder.setRecordStateListener(this); | ||
| 127 | +// | ||
| 128 | +// mFragment.plShortVideoRecorder.prepare(mFragment.binding.gSf, cameraSetting, microphoneSetting, videoEncodeSetting, audioEncodeSetting, null, recordSetting); | ||
| 129 | +// //处理手动对焦事件 | ||
| 130 | +// mFragment.binding.gSf.requestRender(); | ||
| 131 | +// mFragment.binding.gSf.setOnTouchListener(new View.OnTouchListener() { | ||
| 132 | +// @Override | ||
| 133 | +// public boolean onTouch(View v, MotionEvent event) { | ||
| 134 | +// if (event.getAction() == MotionEvent.ACTION_UP) { | ||
| 135 | +// moveFocus(event.getRawX(), event.getRawY()); | ||
| 136 | +// } | ||
| 137 | +// return true; | ||
| 138 | +// } | ||
| 139 | +// }); | ||
| 140 | +// //如果是裁剪类型只支持拍照 | ||
| 141 | +// if (getActivity().isJumpCamera || getActivity().mOptions.getJumpCameraMode() >= 0) { | ||
| 142 | +// mFragment.binding.rcControl.setRecordType(getActivity().mOptions.getJumpCameraMode()); | ||
| 143 | +// } else { | ||
| 144 | +// if (getActivity().mOptions.isNeedCrop()) { | ||
| 145 | +// mFragment.binding.rcControl.setRecordType(PickerConfig.CAMERA_MODE_PIC); | ||
| 146 | +// } else { | ||
| 147 | +// mFragment.binding.rcControl.setRecordType(PickerConfig.CAMERA_MODE_ALL); | ||
| 148 | +// } | ||
| 149 | +// } | ||
| 150 | +// } | ||
| 151 | +// | ||
| 152 | +// /** | ||
| 153 | +// * 选择相机 | ||
| 154 | +// * | ||
| 155 | +// * @return | ||
| 156 | +// */ | ||
| 157 | +// private PLCameraSetting.CAMERA_FACING_ID chooseCameraFacingId() { | ||
| 158 | +// if (PLCameraSetting.hasCameraFacing(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_3RD)) { | ||
| 159 | +// return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_3RD; | ||
| 160 | +// } else if (PLCameraSetting.hasCameraFacing(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK)) { | ||
| 161 | +// return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK; | ||
| 162 | +// } else { | ||
| 163 | +// processFlash(false); | ||
| 164 | +// return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_FRONT; | ||
| 165 | +// } | ||
| 166 | +// } | ||
| 167 | +// | ||
| 168 | +// /** | ||
| 169 | +// * 设置闪光灯 | ||
| 170 | +// * | ||
| 171 | +// * @param isFlashingState | ||
| 172 | +// */ | ||
| 173 | +// public void processFlash(boolean isFlashingState) { | ||
| 174 | +// mFragment.binding.rcControl.setFlashState(isFlashingState); | ||
| 175 | +// } | ||
| 176 | +// | ||
| 177 | +// /** | ||
| 178 | +// * 异常 | ||
| 179 | +// * | ||
| 180 | +// * @param message | ||
| 181 | +// */ | ||
| 182 | +// public void showMesage(String message) { | ||
| 183 | +// | ||
| 184 | +// if (TextUtils.isEmpty(message) || mFragment == null || mFragment.getActivity().isFinishing()) | ||
| 185 | +// return; | ||
| 186 | +// mFragment.getActivity().runOnUiThread(new Runnable() { | ||
| 187 | +// @Override | ||
| 188 | +// public void run() { | ||
| 189 | +// AlertUtil.showDeftToast(mFragment.getActivity(), message); | ||
| 190 | +// } | ||
| 191 | +// }); | ||
| 192 | +// | ||
| 193 | +// | ||
| 194 | +// } | ||
| 195 | +// | ||
| 196 | +// //移动对焦的动画 | ||
| 197 | +// public void moveFocus(float x, float y) { | ||
| 198 | +// | ||
| 199 | +// mFragment.plShortVideoRecorder.manualFocus(80, 80, (int) x, (int) y); | ||
| 200 | +// //缩小 | ||
| 201 | +// float transX = x - ScreenUtils.getScreenWidth(getActivity()) / 2; | ||
| 202 | +// | ||
| 203 | +// float transY = y - ScreenUtils.getScreenHeight(getActivity()) / 2; | ||
| 204 | +// ObjectAnimator translationX = ObjectAnimator.ofFloat(mFragment.binding.fv, "translationX", 0, transX); | ||
| 205 | +// ObjectAnimator translationY = ObjectAnimator.ofFloat(mFragment.binding.fv, "translationY", 0, transY); | ||
| 206 | +// AnimatorSet animSet = new AnimatorSet(); | ||
| 207 | +// animSet.play(translationX).with(translationY); | ||
| 208 | +// animSet.start(); | ||
| 209 | +// animSet.addListener(new Animator.AnimatorListener() { | ||
| 210 | +// @Override | ||
| 211 | +// public void onAnimationStart(Animator animation) { | ||
| 212 | +// | ||
| 213 | +// } | ||
| 214 | +// | ||
| 215 | +// @Override | ||
| 216 | +// public void onAnimationEnd(Animator animation) { | ||
| 217 | +// mFragment.binding.fv.setVisibility(View.VISIBLE); | ||
| 218 | +// } | ||
| 219 | +// | ||
| 220 | +// @Override | ||
| 221 | +// public void onAnimationCancel(Animator animation) { | ||
| 222 | +// | ||
| 223 | +// } | ||
| 224 | +// | ||
| 225 | +// @Override | ||
| 226 | +// public void onAnimationRepeat(Animator animation) { | ||
| 227 | +// | ||
| 228 | +// } | ||
| 229 | +// }); | ||
| 230 | +// ObjectAnimator scaleX = ObjectAnimator.ofFloat(mFragment.binding.fv, "scaleX", 1, 0.6f); | ||
| 231 | +// ObjectAnimator scaleY = ObjectAnimator.ofFloat(mFragment.binding.fv, "scaleY", 1, 0.6f); | ||
| 232 | +// | ||
| 233 | +// AnimatorSet animSet2 = new AnimatorSet(); | ||
| 234 | +// animSet2.play(scaleY).with(scaleX); | ||
| 235 | +// animSet2.setInterpolator(new OvershootInterpolator()); | ||
| 236 | +// animSet2.setDuration(800); | ||
| 237 | +// animSet2.start(); | ||
| 238 | +// animSet2.addListener(new Animator.AnimatorListener() { | ||
| 239 | +// | ||
| 240 | +// @Override | ||
| 241 | +// public void onAnimationStart(Animator animation) { | ||
| 242 | +// | ||
| 243 | +// } | ||
| 244 | +// | ||
| 245 | +// @Override | ||
| 246 | +// public void onAnimationEnd(Animator animation) { | ||
| 247 | +// mFragment.binding.fv.setVisibility(View.GONE); | ||
| 248 | +// } | ||
| 249 | +// | ||
| 250 | +// @Override | ||
| 251 | +// public void onAnimationCancel(Animator animation) { | ||
| 252 | +// | ||
| 253 | +// } | ||
| 254 | +// | ||
| 255 | +// @Override | ||
| 256 | +// public void onAnimationRepeat(Animator animation) { | ||
| 257 | +// | ||
| 258 | +// } | ||
| 259 | +// }); | ||
| 260 | +// } | ||
| 261 | +// | ||
| 262 | +// | ||
| 263 | +// @Override | ||
| 264 | +// public void onReady() { | ||
| 265 | +// //设置闪光灯 | ||
| 266 | +// mFragment.isReady = true; | ||
| 267 | +// } | ||
| 268 | +// | ||
| 269 | +// @Override | ||
| 270 | +// public void onError(int i) { | ||
| 271 | +// showMesage("相机初始化异常"); | ||
| 272 | +// mFragment.isReady = false; | ||
| 273 | +// mFragment.isRecordIng = false; | ||
| 274 | +// } | ||
| 275 | +// | ||
| 276 | +// @Override | ||
| 277 | +// public void onDurationTooShort() { | ||
| 278 | +// } | ||
| 279 | +// | ||
| 280 | +// @Override | ||
| 281 | +// public void onRecordStarted() { | ||
| 282 | +// } | ||
| 283 | +// | ||
| 284 | +// @Override | ||
| 285 | +// public void onSectionRecording(long l, long l1, int i) { | ||
| 286 | +// } | ||
| 287 | +// | ||
| 288 | +// @Override | ||
| 289 | +// public void onRecordStopped() { | ||
| 290 | +// Log.e("", ""); | ||
| 291 | +// } | ||
| 292 | +// | ||
| 293 | +// @Override | ||
| 294 | +// public void onSectionIncreased(long l, long l1, int i) { | ||
| 295 | +// Log.e("", ""); | ||
| 296 | +// } | ||
| 297 | +// | ||
| 298 | +// @Override | ||
| 299 | +// public void onSectionDecreased(long l, long l1, int i) { | ||
| 300 | +// } | ||
| 301 | +// | ||
| 302 | +// @Override | ||
| 303 | +// public void onRecordCompleted() { | ||
| 304 | +// mFragment.isReady = false; | ||
| 305 | +// mFragment.isRecordIng = false; | ||
| 306 | +// } | ||
| 307 | +//} |
lib_media/src/main/java/com/cnlive/media/frame/view/RecordPreviewView.java
| 1 | -package com.cnlive.media.frame.view; | ||
| 2 | - | ||
| 3 | -import android.animation.AnimatorSet; | ||
| 4 | -import android.animation.ObjectAnimator; | ||
| 5 | -import android.content.Intent; | ||
| 6 | -import android.net.Uri; | ||
| 7 | -import android.text.TextUtils; | ||
| 8 | -import android.view.View; | ||
| 9 | -import android.view.ViewGroup; | ||
| 10 | -import android.view.animation.OvershootInterpolator; | ||
| 11 | -import android.widget.FrameLayout; | ||
| 12 | -import android.widget.RelativeLayout; | ||
| 13 | - | ||
| 14 | -import androidx.core.content.FileProvider; | ||
| 15 | - | ||
| 16 | -import com.bumptech.glide.Glide; | ||
| 17 | -import com.bumptech.glide.load.engine.DiskCacheStrategy; | ||
| 18 | -import com.bumptech.glide.request.RequestOptions; | ||
| 19 | -import com.cnlive.libs.base.util.AlertUtil; | ||
| 20 | -import com.cnlive.media.PickerConfig; | ||
| 21 | -import com.cnlive.media.media.entity.Media; | ||
| 22 | -import com.cnlive.media.ui.activity.ImageCropActivity; | ||
| 23 | -import com.cnlive.media.ui.activity.RecordActivity; | ||
| 24 | -import com.cnlive.media.ui.fragment.RecordPreviewFragment; | ||
| 25 | -import com.cnlive.media.utils.GlideCacheUtil; | ||
| 26 | -import com.cnlive.media.utils.MediaUtils; | ||
| 27 | -import com.cnlive.media.utils.album.AlbumProcessUtil; | ||
| 28 | -import com.cnlive.media.utils.album.OnSaveCallback; | ||
| 29 | -import com.cnlive.media.utils.observable.MediaAddObservable; | ||
| 30 | -import com.cnlive.media.utils.observable.MeidaResultObservable; | ||
| 31 | -import com.hannesdorfmann.mosby3.mvp.MvpView; | ||
| 32 | -import com.qiniu.pili.droid.shortvideo.PLDisplayMode; | ||
| 33 | -import com.qiniu.pili.droid.shortvideo.PLMediaFile; | ||
| 34 | -import com.qiniu.pili.droid.shortvideo.PLShortVideoEditor; | ||
| 35 | -import com.qiniu.pili.droid.shortvideo.PLVideoEditSetting; | ||
| 36 | - | ||
| 37 | -import java.io.File; | ||
| 38 | -import java.util.ArrayList; | ||
| 39 | - | ||
| 40 | -/** | ||
| 41 | - * 作 者 : wkq | ||
| 42 | - * <p> | ||
| 43 | - * 时 间 : 2020/9/28 9:35 | ||
| 44 | - * <p> | ||
| 45 | - * 名 字 : RecordPreviewView | ||
| 46 | - * <p> | ||
| 47 | - * 简 介 : | ||
| 48 | - */ | ||
| 49 | -public class RecordPreviewView implements MvpView { | ||
| 50 | - RecordPreviewFragment mFragment; | ||
| 51 | - private PLMediaFile mMediaFile; | ||
| 52 | - | ||
| 53 | - public RecordPreviewView(RecordPreviewFragment mFragment) { | ||
| 54 | - this.mFragment = mFragment; | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - public void initView(RecordActivity mActivity) { | ||
| 58 | - | ||
| 59 | - if (mFragment.type == 0) { | ||
| 60 | - mFragment.binding.ivPre.setVisibility(View.VISIBLE); | ||
| 61 | - mFragment.binding.rlVideo.setVisibility(View.GONE); | ||
| 62 | - GlideCacheUtil.intoItemImageBitmap(mActivity, mActivity.preBitmap, mFragment.binding.ivPre); | ||
| 63 | - } else if (mFragment.type == 1) { | ||
| 64 | - mFragment.binding.ivPre.setVisibility(View.GONE); | ||
| 65 | - mFragment.binding.rlVideo.setVisibility(View.VISIBLE); | ||
| 66 | - RequestOptions option = new RequestOptions(); | ||
| 67 | - option.dontTransform() | ||
| 68 | - .diskCacheStrategy(DiskCacheStrategy.RESOURCE) | ||
| 69 | - .dontAnimate(); | ||
| 70 | - Glide.with(mFragment).load(mFragment.path).apply(option).into(mFragment.binding.ivVideo); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - ObjectAnimator animator_cancel = ObjectAnimator.ofFloat(mFragment.binding.tbOk, "translationX", 200, 0); | ||
| 74 | - ObjectAnimator animator_confirm = ObjectAnimator.ofFloat(mFragment.binding.tbCancel, "translationX", -200, 0); | ||
| 75 | - | ||
| 76 | - AnimatorSet set = new AnimatorSet(); | ||
| 77 | - set.playTogether(animator_cancel, animator_confirm); | ||
| 78 | - set.setInterpolator(new OvershootInterpolator()); | ||
| 79 | - set.setDuration(200); | ||
| 80 | - set.start(); | ||
| 81 | - | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - public void initPre() { | ||
| 85 | - mMediaFile = new PLMediaFile(mFragment.path); | ||
| 86 | - PLVideoEditSetting setting = new PLVideoEditSetting(); | ||
| 87 | - setting.setSourceFilepath(mFragment.path); | ||
| 88 | - setting.setGifPreviewEnabled(false); | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - | ||
| 92 | - public void showMessage(String message) { | ||
| 93 | - if (mFragment == null || TextUtils.isEmpty(message)) return; | ||
| 94 | - AlertUtil.showDeftToast(mFragment.getActivity(), message); | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - public void showSuccessMessage(String message) { | ||
| 98 | - if (mFragment == null || TextUtils.isEmpty(message)) return; | ||
| 99 | - AlertUtil.showSuccessToast(mFragment.getActivity(), message); | ||
| 100 | - } | ||
| 101 | - | ||
| 102 | - public void savePic(RecordActivity mActivity) { | ||
| 103 | - | ||
| 104 | - AlbumProcessUtil.saveBitmap(mActivity, mActivity.preBitmap, new OnSaveCallback() { | ||
| 105 | - @Override | ||
| 106 | - public void onSuccess(String path) { | ||
| 107 | - File file = new File(path); | ||
| 108 | - if (file != null && file.exists() && file.canRead() && file.canWrite()) { | ||
| 109 | - | ||
| 110 | - Uri uri = FileProvider.getUriForFile(mFragment.getActivity(), mFragment.getActivity().getApplicationContext().getPackageName() + ".fileprovider", file); | ||
| 111 | - Media media = new Media(path, file.getName(), System.currentTimeMillis(), 1, file.length(), (int) System.currentTimeMillis(), file.getParent(), uri.toString()); | ||
| 112 | - media.setSelect(false); | ||
| 113 | - media.setReturnUri(mActivity.mOptions.isReturnUri()); | ||
| 114 | - if (mActivity.preBitmap != null && mActivity.preBitmap.getHeight() > 0 && mActivity.preBitmap.getWidth() > 0) { | ||
| 115 | - media.setImgHeight(mActivity.preBitmap.getHeight()); | ||
| 116 | - media.setImgWidth(mActivity.preBitmap.getWidth()); | ||
| 117 | - media.setLongImg(MediaUtils.isLongImg(mActivity.preBitmap.getWidth(), mActivity.preBitmap.getHeight())); | ||
| 118 | - } | ||
| 119 | - if (mActivity.mOptions.needCrop) { | ||
| 120 | - ImageCropActivity.start(mActivity, path, mActivity.mOptions); | ||
| 121 | - } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) { | ||
| 122 | - MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 123 | - mActivity.finish(); | ||
| 124 | - } else if (mActivity.isJumpCamera) { | ||
| 125 | - if (mActivity.selectMedia == null) | ||
| 126 | - mActivity.selectMedia = new ArrayList<Media>(); | ||
| 127 | - mActivity.selectMedia.add(media); | ||
| 128 | - Intent intent = new Intent(); | ||
| 129 | - intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, mActivity.selectMedia); | ||
| 130 | - mActivity.setResult(mActivity.resultCode, intent); | ||
| 131 | - mActivity.finish(); | ||
| 132 | - } else { | ||
| 133 | - MediaAddObservable.getInstance().addMedia(media); | ||
| 134 | - mActivity.finish(); | ||
| 135 | - } | ||
| 136 | - | ||
| 137 | - } else { | ||
| 138 | - mFragment.requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 139 | - } | ||
| 140 | - } | ||
| 141 | - | ||
| 142 | - @Override | ||
| 143 | - public void onFail(String message) { | ||
| 144 | - showMessage("图片保存异常"); | ||
| 145 | - } | ||
| 146 | - }); | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | - public void saveVideo(RecordActivity mActivity) { | ||
| 150 | - if (mMediaFile == null || mActivity == null) return; | ||
| 151 | - File file = new File(mMediaFile.getFilepath()); | ||
| 152 | - Uri uri = FileProvider.getUriForFile(mFragment.getActivity(), mFragment.getActivity().getApplicationContext().getPackageName() + ".fileprovider", file); | ||
| 153 | - Media media = new Media(mMediaFile.getFilepath(), file.getName(), System.currentTimeMillis(), 3, file.length(), (int) System.currentTimeMillis(), file.getParent(), (int) mMediaFile.getDurationMs(), uri.toString()); | ||
| 154 | - media.setImgWidth(mMediaFile.getVideoWidth()); | ||
| 155 | - media.setImgHeight(mMediaFile.getVideoHeight()); | ||
| 156 | - media.setSelect(false); | ||
| 157 | - media.setReturnUri(mActivity.mOptions.isReturnUri()); | ||
| 158 | - if (mActivity.isJumpCamera) { | ||
| 159 | - MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 160 | - } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) { | ||
| 161 | - MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 162 | - mActivity.finish(); | ||
| 163 | - } else if (mActivity.mOptions.needCrop) { | ||
| 164 | - RecordActivity.newInstance(mActivity, mActivity.mOptions); | ||
| 165 | - mActivity.finish(); | ||
| 166 | - } else { | ||
| 167 | - MediaAddObservable.getInstance().addMedia(media); | ||
| 168 | - mActivity.finish(); | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | - mMediaFile.release(); | ||
| 172 | - | ||
| 173 | - } | ||
| 174 | -} | 1 | +//package com.cnlive.media.frame.view; |
| 2 | +// | ||
| 3 | +//import android.animation.AnimatorSet; | ||
| 4 | +//import android.animation.ObjectAnimator; | ||
| 5 | +//import android.content.Intent; | ||
| 6 | +//import android.net.Uri; | ||
| 7 | +//import android.text.TextUtils; | ||
| 8 | +//import android.view.View; | ||
| 9 | +//import android.view.ViewGroup; | ||
| 10 | +//import android.view.animation.OvershootInterpolator; | ||
| 11 | +//import android.widget.FrameLayout; | ||
| 12 | +//import android.widget.RelativeLayout; | ||
| 13 | +// | ||
| 14 | +//import androidx.core.content.FileProvider; | ||
| 15 | +// | ||
| 16 | +//import com.bumptech.glide.Glide; | ||
| 17 | +//import com.bumptech.glide.load.engine.DiskCacheStrategy; | ||
| 18 | +//import com.bumptech.glide.request.RequestOptions; | ||
| 19 | +//import com.cnlive.libs.base.util.AlertUtil; | ||
| 20 | +//import com.cnlive.media.PickerConfig; | ||
| 21 | +//import com.cnlive.media.media.entity.Media; | ||
| 22 | +//import com.cnlive.media.ui.activity.ImageCropActivity; | ||
| 23 | +//import com.cnlive.media.ui.activity.RecordActivity; | ||
| 24 | +//import com.cnlive.media.ui.fragment.RecordPreviewFragment; | ||
| 25 | +//import com.cnlive.media.utils.GlideCacheUtil; | ||
| 26 | +//import com.cnlive.media.utils.MediaUtils; | ||
| 27 | +//import com.cnlive.media.utils.album.AlbumProcessUtil; | ||
| 28 | +//import com.cnlive.media.utils.album.OnSaveCallback; | ||
| 29 | +//import com.cnlive.media.utils.observable.MediaAddObservable; | ||
| 30 | +//import com.cnlive.media.utils.observable.MeidaResultObservable; | ||
| 31 | +//import com.hannesdorfmann.mosby3.mvp.MvpView; | ||
| 32 | +//import com.qiniu.pili.droid.shortvideo.PLDisplayMode; | ||
| 33 | +//import com.qiniu.pili.droid.shortvideo.PLMediaFile; | ||
| 34 | +//import com.qiniu.pili.droid.shortvideo.PLShortVideoEditor; | ||
| 35 | +//import com.qiniu.pili.droid.shortvideo.PLVideoEditSetting; | ||
| 36 | +// | ||
| 37 | +//import java.io.File; | ||
| 38 | +//import java.util.ArrayList; | ||
| 39 | +// | ||
| 40 | +///** | ||
| 41 | +// * 作 者 : wkq | ||
| 42 | +// * <p> | ||
| 43 | +// * 时 间 : 2020/9/28 9:35 | ||
| 44 | +// * <p> | ||
| 45 | +// * 名 字 : RecordPreviewView | ||
| 46 | +// * <p> | ||
| 47 | +// * 简 介 : | ||
| 48 | +// */ | ||
| 49 | +//public class RecordPreviewView implements MvpView { | ||
| 50 | +// RecordPreviewFragment mFragment; | ||
| 51 | +// private PLMediaFile mMediaFile; | ||
| 52 | +// | ||
| 53 | +// public RecordPreviewView(RecordPreviewFragment mFragment) { | ||
| 54 | +// this.mFragment = mFragment; | ||
| 55 | +// } | ||
| 56 | +// | ||
| 57 | +// public void initView(RecordActivity mActivity) { | ||
| 58 | +// | ||
| 59 | +// if (mFragment.type == 0) { | ||
| 60 | +// mFragment.binding.ivPre.setVisibility(View.VISIBLE); | ||
| 61 | +// mFragment.binding.rlVideo.setVisibility(View.GONE); | ||
| 62 | +// GlideCacheUtil.intoItemImageBitmap(mActivity, mActivity.preBitmap, mFragment.binding.ivPre); | ||
| 63 | +// } else if (mFragment.type == 1) { | ||
| 64 | +// mFragment.binding.ivPre.setVisibility(View.GONE); | ||
| 65 | +// mFragment.binding.rlVideo.setVisibility(View.VISIBLE); | ||
| 66 | +// RequestOptions option = new RequestOptions(); | ||
| 67 | +// option.dontTransform() | ||
| 68 | +// .diskCacheStrategy(DiskCacheStrategy.RESOURCE) | ||
| 69 | +// .dontAnimate(); | ||
| 70 | +// Glide.with(mFragment).load(mFragment.path).apply(option).into(mFragment.binding.ivVideo); | ||
| 71 | +// } | ||
| 72 | +// | ||
| 73 | +// ObjectAnimator animator_cancel = ObjectAnimator.ofFloat(mFragment.binding.tbOk, "translationX", 200, 0); | ||
| 74 | +// ObjectAnimator animator_confirm = ObjectAnimator.ofFloat(mFragment.binding.tbCancel, "translationX", -200, 0); | ||
| 75 | +// | ||
| 76 | +// AnimatorSet set = new AnimatorSet(); | ||
| 77 | +// set.playTogether(animator_cancel, animator_confirm); | ||
| 78 | +// set.setInterpolator(new OvershootInterpolator()); | ||
| 79 | +// set.setDuration(200); | ||
| 80 | +// set.start(); | ||
| 81 | +// | ||
| 82 | +// } | ||
| 83 | +// | ||
| 84 | +// public void initPre() { | ||
| 85 | +// mMediaFile = new PLMediaFile(mFragment.path); | ||
| 86 | +// PLVideoEditSetting setting = new PLVideoEditSetting(); | ||
| 87 | +// setting.setSourceFilepath(mFragment.path); | ||
| 88 | +// setting.setGifPreviewEnabled(false); | ||
| 89 | +// } | ||
| 90 | +// | ||
| 91 | +// | ||
| 92 | +// public void showMessage(String message) { | ||
| 93 | +// if (mFragment == null || TextUtils.isEmpty(message)) return; | ||
| 94 | +// AlertUtil.showDeftToast(mFragment.getActivity(), message); | ||
| 95 | +// } | ||
| 96 | +// | ||
| 97 | +// public void showSuccessMessage(String message) { | ||
| 98 | +// if (mFragment == null || TextUtils.isEmpty(message)) return; | ||
| 99 | +// AlertUtil.showSuccessToast(mFragment.getActivity(), message); | ||
| 100 | +// } | ||
| 101 | +// | ||
| 102 | +// public void savePic(RecordActivity mActivity) { | ||
| 103 | +// | ||
| 104 | +// AlbumProcessUtil.saveBitmap(mActivity, mActivity.preBitmap, new OnSaveCallback() { | ||
| 105 | +// @Override | ||
| 106 | +// public void onSuccess(String path) { | ||
| 107 | +// File file = new File(path); | ||
| 108 | +// if (file != null && file.exists() && file.canRead() && file.canWrite()) { | ||
| 109 | +// | ||
| 110 | +// Uri uri = FileProvider.getUriForFile(mFragment.getActivity(), mFragment.getActivity().getApplicationContext().getPackageName() + ".fileprovider", file); | ||
| 111 | +// Media media = new Media(path, file.getName(), System.currentTimeMillis(), 1, file.length(), (int) System.currentTimeMillis(), file.getParent(), uri.toString()); | ||
| 112 | +// media.setSelect(false); | ||
| 113 | +// media.setReturnUri(mActivity.mOptions.isReturnUri()); | ||
| 114 | +// if (mActivity.preBitmap != null && mActivity.preBitmap.getHeight() > 0 && mActivity.preBitmap.getWidth() > 0) { | ||
| 115 | +// media.setImgHeight(mActivity.preBitmap.getHeight()); | ||
| 116 | +// media.setImgWidth(mActivity.preBitmap.getWidth()); | ||
| 117 | +// media.setLongImg(MediaUtils.isLongImg(mActivity.preBitmap.getWidth(), mActivity.preBitmap.getHeight())); | ||
| 118 | +// } | ||
| 119 | +// if (mActivity.mOptions.needCrop) { | ||
| 120 | +// ImageCropActivity.start(mActivity, path, mActivity.mOptions); | ||
| 121 | +// } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) { | ||
| 122 | +// MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 123 | +// mActivity.finish(); | ||
| 124 | +// } else if (mActivity.isJumpCamera) { | ||
| 125 | +// if (mActivity.selectMedia == null) | ||
| 126 | +// mActivity.selectMedia = new ArrayList<Media>(); | ||
| 127 | +// mActivity.selectMedia.add(media); | ||
| 128 | +// Intent intent = new Intent(); | ||
| 129 | +// intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, mActivity.selectMedia); | ||
| 130 | +// mActivity.setResult(mActivity.resultCode, intent); | ||
| 131 | +// mActivity.finish(); | ||
| 132 | +// } else { | ||
| 133 | +// MediaAddObservable.getInstance().addMedia(media); | ||
| 134 | +// mActivity.finish(); | ||
| 135 | +// } | ||
| 136 | +// | ||
| 137 | +// } else { | ||
| 138 | +// mFragment.requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 139 | +// } | ||
| 140 | +// } | ||
| 141 | +// | ||
| 142 | +// @Override | ||
| 143 | +// public void onFail(String message) { | ||
| 144 | +// showMessage("图片保存异常"); | ||
| 145 | +// } | ||
| 146 | +// }); | ||
| 147 | +// } | ||
| 148 | +// | ||
| 149 | +// public void saveVideo(RecordActivity mActivity) { | ||
| 150 | +// if (mMediaFile == null || mActivity == null) return; | ||
| 151 | +// File file = new File(mMediaFile.getFilepath()); | ||
| 152 | +// Uri uri = FileProvider.getUriForFile(mFragment.getActivity(), mFragment.getActivity().getApplicationContext().getPackageName() + ".fileprovider", file); | ||
| 153 | +// Media media = new Media(mMediaFile.getFilepath(), file.getName(), System.currentTimeMillis(), 3, file.length(), (int) System.currentTimeMillis(), file.getParent(), (int) mMediaFile.getDurationMs(), uri.toString()); | ||
| 154 | +// media.setImgWidth(mMediaFile.getVideoWidth()); | ||
| 155 | +// media.setImgHeight(mMediaFile.getVideoHeight()); | ||
| 156 | +// media.setSelect(false); | ||
| 157 | +// media.setReturnUri(mActivity.mOptions.isReturnUri()); | ||
| 158 | +// if (mActivity.isJumpCamera) { | ||
| 159 | +// MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 160 | +// } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) { | ||
| 161 | +// MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 162 | +// mActivity.finish(); | ||
| 163 | +// } else if (mActivity.mOptions.needCrop) { | ||
| 164 | +// RecordActivity.newInstance(mActivity, mActivity.mOptions); | ||
| 165 | +// mActivity.finish(); | ||
| 166 | +// } else { | ||
| 167 | +// MediaAddObservable.getInstance().addMedia(media); | ||
| 168 | +// mActivity.finish(); | ||
| 169 | +// } | ||
| 170 | +// | ||
| 171 | +// mMediaFile.release(); | ||
| 172 | +// | ||
| 173 | +// } | ||
| 174 | +//} |
lib_media/src/main/java/com/cnlive/media/frame/view/RecordView.java
| 1 | -package com.cnlive.media.frame.view; | ||
| 2 | - | ||
| 3 | -import android.app.Dialog; | ||
| 4 | -import android.content.pm.ActivityInfo; | ||
| 5 | -import android.os.Build; | ||
| 6 | -import android.text.TextUtils; | ||
| 7 | -import android.view.View; | ||
| 8 | -import android.view.WindowManager; | ||
| 9 | - | ||
| 10 | -import androidx.activity.OnBackPressedCallback; | ||
| 11 | -import androidx.core.app.ActivityCompat; | ||
| 12 | -import androidx.fragment.app.Fragment; | ||
| 13 | - | ||
| 14 | -import com.cnlive.libs.base.util.AlertUtil; | ||
| 15 | -import com.cnlive.media.R; | ||
| 16 | -import com.cnlive.media.ui.activity.RecordActivity; | ||
| 17 | -import com.cnlive.media.ui.fragment.RecordFragment; | ||
| 18 | -import com.cnlive.media.ui.fragment.RecordPreviewFragment; | ||
| 19 | -import com.cnlive.media.utils.AlertDialogUtils; | ||
| 20 | -import com.cnlive.media.utils.PermissionChecker; | ||
| 21 | -import com.hannesdorfmann.mosby3.mvp.MvpView; | ||
| 22 | - | ||
| 23 | -/** | ||
| 24 | - * 作 者 : wkq | ||
| 25 | - * <p> | ||
| 26 | - * 时 间 : 2020/9/22 13:32 | ||
| 27 | - * <p> | ||
| 28 | - * 名 字 : RecordView | ||
| 29 | - * <p> | ||
| 30 | - * 简 介 : | ||
| 31 | - */ | ||
| 32 | -public class RecordView implements MvpView { | ||
| 33 | - | ||
| 34 | - RecordActivity mActivity; | ||
| 35 | - | ||
| 36 | - | ||
| 37 | - public RecordView(RecordActivity mActivity) { | ||
| 38 | - this.mActivity = mActivity; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - public void initView() { | ||
| 42 | - processFullScreen(); | ||
| 43 | - //处理fragment 回调 | ||
| 44 | - mActivity.getOnBackPressedDispatcher().addCallback(mActivity, new OnBackPressedCallback(true) { | ||
| 45 | - @Override | ||
| 46 | - public void handleOnBackPressed() { | ||
| 47 | - Fragment currentFragment = mActivity.getSupportFragmentManager().findFragmentById(R.id.pre_frame); | ||
| 48 | - if (currentFragment instanceof RecordPreviewFragment) { | ||
| 49 | - mActivity.getSupportFragmentManager().popBackStack(); | ||
| 50 | - } else { | ||
| 51 | - mActivity.finish(); | ||
| 52 | - } | ||
| 53 | - } | ||
| 54 | - }); | ||
| 55 | - | ||
| 56 | - | ||
| 57 | - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { | ||
| 58 | - mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); | ||
| 59 | - } | ||
| 60 | - checkPermisssion(); | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - //检测权限 | ||
| 64 | - public void checkPermisssion() { | ||
| 65 | - boolean hasPermissions; | ||
| 66 | - if (mActivity.isNeedAudio){ | ||
| 67 | - hasPermissions = mActivity.getPresenter().checkPermissions(mActivity, mActivity.permissionsRecord, mActivity.PERMISISSION_CODE_ASK, true); | ||
| 68 | - }else { | ||
| 69 | - hasPermissions = mActivity.getPresenter().checkPermissions(mActivity, mActivity.permissionsRecordNoAudio, mActivity.PERMISISSION_CODE_ASK, true); | ||
| 70 | - } | ||
| 71 | - if (hasPermissions) { | ||
| 72 | - mActivity.getSupportFragmentManager().beginTransaction().replace(R.id.pre_frame, RecordFragment.newInstance()).addToBackStack("").commitAllowingStateLoss(); | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | - } | ||
| 76 | - /** | ||
| 77 | - * 处理刘海屏全屏问题 | ||
| 78 | - */ | ||
| 79 | - public void processFullScreen() { | ||
| 80 | - | ||
| 81 | - WindowManager.LayoutParams lp= mActivity.getWindow().getAttributes(); | ||
| 82 | - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||
| 83 | - lp.layoutInDisplayCutoutMode =WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; | ||
| 84 | - } | ||
| 85 | - mActivity.getWindow().setAttributes(lp); | ||
| 86 | - // 设置页面全屏显示 | ||
| 87 | - View decorView = mActivity.getWindow().getDecorView(); | ||
| 88 | - decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_STABLE); | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - | ||
| 92 | - public void showMessage(String message) { | ||
| 93 | - | ||
| 94 | - if (TextUtils.isEmpty(message) || mActivity == null || mActivity.isFinishing()) return; | ||
| 95 | - mActivity.runOnUiThread(new Runnable() { | ||
| 96 | - @Override | ||
| 97 | - public void run() { | ||
| 98 | - AlertUtil.showDeftToast(mActivity, message); | ||
| 99 | - } | ||
| 100 | - }); | ||
| 101 | - | ||
| 102 | - | ||
| 103 | - } | ||
| 104 | - | ||
| 105 | - | ||
| 106 | - | ||
| 107 | - | ||
| 108 | - public void showPermission(String[] needList, int requestCode) { | ||
| 109 | - if (mActivity.dialog != null) mActivity.dialog.dismiss(); | ||
| 110 | - mActivity.dialog = AlertDialogUtils.showTwoButtonDialog( | ||
| 111 | - mActivity, | ||
| 112 | - mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel), | ||
| 113 | - mActivity.getString(R.string.dialog_imagepicker_permission_confirm), | ||
| 114 | - mActivity.getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message), | ||
| 115 | - R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() { | ||
| 116 | - @Override | ||
| 117 | - public void onClickLeft(Dialog dialog) { | ||
| 118 | - dialog.dismiss(); | ||
| 119 | - showMessage("无法获取存读取权限,您的app将无法正常使用"); | ||
| 120 | - mActivity.finish(); | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - @Override | ||
| 124 | - public void onClickRight(Dialog dialog) { | ||
| 125 | - dialog.dismiss(); | ||
| 126 | - ActivityCompat.requestPermissions(mActivity, needList, requestCode); | ||
| 127 | - } | ||
| 128 | - }); | ||
| 129 | - } | ||
| 130 | - | ||
| 131 | - public void showPermissionPerpetual(int requestCode) { | ||
| 132 | - | ||
| 133 | - if (mActivity.dialog != null) mActivity.dialog.dismiss(); | ||
| 134 | - mActivity.dialog = AlertDialogUtils.showTwoButtonDialog( | ||
| 135 | - mActivity, | ||
| 136 | - mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel), | ||
| 137 | - mActivity.getString(R.string.dialog_imagepicker_permission_confirm), | ||
| 138 | - mActivity.getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message), | ||
| 139 | - R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() { | ||
| 140 | - @Override | ||
| 141 | - public void onClickLeft(Dialog dialog) { | ||
| 142 | - dialog.dismiss(); | ||
| 143 | - showMessage("无法获取存读取权限,您的app将无法正常使用"); | ||
| 144 | - mActivity.finish(); | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | - @Override | ||
| 148 | - public void onClickRight(Dialog dialog) { | ||
| 149 | - dialog.dismiss(); | ||
| 150 | - PermissionChecker.settingPermissionActivity(mActivity, requestCode); | ||
| 151 | - mActivity.isNeverAsk = true; | ||
| 152 | - } | ||
| 153 | - }); | ||
| 154 | - | ||
| 155 | - } | ||
| 156 | -} | 1 | +//package com.cnlive.media.frame.view; |
| 2 | +// | ||
| 3 | +//import android.app.Dialog; | ||
| 4 | +//import android.content.pm.ActivityInfo; | ||
| 5 | +//import android.os.Build; | ||
| 6 | +//import android.text.TextUtils; | ||
| 7 | +//import android.view.View; | ||
| 8 | +//import android.view.WindowManager; | ||
| 9 | +// | ||
| 10 | +//import androidx.activity.OnBackPressedCallback; | ||
| 11 | +//import androidx.core.app.ActivityCompat; | ||
| 12 | +//import androidx.fragment.app.Fragment; | ||
| 13 | +// | ||
| 14 | +//import com.cnlive.libs.base.util.AlertUtil; | ||
| 15 | +//import com.cnlive.media.R; | ||
| 16 | +//import com.cnlive.media.ui.activity.RecordActivity; | ||
| 17 | +//import com.cnlive.media.ui.fragment.RecordFragment; | ||
| 18 | +//import com.cnlive.media.ui.fragment.RecordPreviewFragment; | ||
| 19 | +//import com.cnlive.media.utils.AlertDialogUtils; | ||
| 20 | +//import com.cnlive.media.utils.PermissionChecker; | ||
| 21 | +//import com.hannesdorfmann.mosby3.mvp.MvpView; | ||
| 22 | +// | ||
| 23 | +///** | ||
| 24 | +// * 作 者 : wkq | ||
| 25 | +// * <p> | ||
| 26 | +// * 时 间 : 2020/9/22 13:32 | ||
| 27 | +// * <p> | ||
| 28 | +// * 名 字 : RecordView | ||
| 29 | +// * <p> | ||
| 30 | +// * 简 介 : | ||
| 31 | +// */ | ||
| 32 | +//public class RecordView implements MvpView { | ||
| 33 | +// | ||
| 34 | +// RecordActivity mActivity; | ||
| 35 | +// | ||
| 36 | +// | ||
| 37 | +// public RecordView(RecordActivity mActivity) { | ||
| 38 | +// this.mActivity = mActivity; | ||
| 39 | +// } | ||
| 40 | +// | ||
| 41 | +// public void initView() { | ||
| 42 | +// processFullScreen(); | ||
| 43 | +// //处理fragment 回调 | ||
| 44 | +// mActivity.getOnBackPressedDispatcher().addCallback(mActivity, new OnBackPressedCallback(true) { | ||
| 45 | +// @Override | ||
| 46 | +// public void handleOnBackPressed() { | ||
| 47 | +// Fragment currentFragment = mActivity.getSupportFragmentManager().findFragmentById(R.id.pre_frame); | ||
| 48 | +// if (currentFragment instanceof RecordPreviewFragment) { | ||
| 49 | +// mActivity.getSupportFragmentManager().popBackStack(); | ||
| 50 | +// } else { | ||
| 51 | +// mActivity.finish(); | ||
| 52 | +// } | ||
| 53 | +// } | ||
| 54 | +// }); | ||
| 55 | +// | ||
| 56 | +// | ||
| 57 | +// if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { | ||
| 58 | +// mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); | ||
| 59 | +// } | ||
| 60 | +// checkPermisssion(); | ||
| 61 | +// } | ||
| 62 | +// | ||
| 63 | +// //检测权限 | ||
| 64 | +// public void checkPermisssion() { | ||
| 65 | +// boolean hasPermissions; | ||
| 66 | +// if (mActivity.isNeedAudio){ | ||
| 67 | +// hasPermissions = mActivity.getPresenter().checkPermissions(mActivity, mActivity.permissionsRecord, mActivity.PERMISISSION_CODE_ASK, true); | ||
| 68 | +// }else { | ||
| 69 | +// hasPermissions = mActivity.getPresenter().checkPermissions(mActivity, mActivity.permissionsRecordNoAudio, mActivity.PERMISISSION_CODE_ASK, true); | ||
| 70 | +// } | ||
| 71 | +// if (hasPermissions) { | ||
| 72 | +// mActivity.getSupportFragmentManager().beginTransaction().replace(R.id.pre_frame, RecordFragment.newInstance()).addToBackStack("").commitAllowingStateLoss(); | ||
| 73 | +// } | ||
| 74 | +// | ||
| 75 | +// } | ||
| 76 | +// /** | ||
| 77 | +// * 处理刘海屏全屏问题 | ||
| 78 | +// */ | ||
| 79 | +// public void processFullScreen() { | ||
| 80 | +// | ||
| 81 | +// WindowManager.LayoutParams lp= mActivity.getWindow().getAttributes(); | ||
| 82 | +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||
| 83 | +// lp.layoutInDisplayCutoutMode =WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; | ||
| 84 | +// } | ||
| 85 | +// mActivity.getWindow().setAttributes(lp); | ||
| 86 | +// // 设置页面全屏显示 | ||
| 87 | +// View decorView = mActivity.getWindow().getDecorView(); | ||
| 88 | +// decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_STABLE); | ||
| 89 | +// } | ||
| 90 | +// | ||
| 91 | +// | ||
| 92 | +// public void showMessage(String message) { | ||
| 93 | +// | ||
| 94 | +// if (TextUtils.isEmpty(message) || mActivity == null || mActivity.isFinishing()) return; | ||
| 95 | +// mActivity.runOnUiThread(new Runnable() { | ||
| 96 | +// @Override | ||
| 97 | +// public void run() { | ||
| 98 | +// AlertUtil.showDeftToast(mActivity, message); | ||
| 99 | +// } | ||
| 100 | +// }); | ||
| 101 | +// | ||
| 102 | +// | ||
| 103 | +// } | ||
| 104 | +// | ||
| 105 | +// | ||
| 106 | +// | ||
| 107 | +// | ||
| 108 | +// public void showPermission(String[] needList, int requestCode) { | ||
| 109 | +// if (mActivity.dialog != null) mActivity.dialog.dismiss(); | ||
| 110 | +// mActivity.dialog = AlertDialogUtils.showTwoButtonDialog( | ||
| 111 | +// mActivity, | ||
| 112 | +// mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel), | ||
| 113 | +// mActivity.getString(R.string.dialog_imagepicker_permission_confirm), | ||
| 114 | +// mActivity.getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message), | ||
| 115 | +// R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() { | ||
| 116 | +// @Override | ||
| 117 | +// public void onClickLeft(Dialog dialog) { | ||
| 118 | +// dialog.dismiss(); | ||
| 119 | +// showMessage("无法获取存读取权限,您的app将无法正常使用"); | ||
| 120 | +// mActivity.finish(); | ||
| 121 | +// } | ||
| 122 | +// | ||
| 123 | +// @Override | ||
| 124 | +// public void onClickRight(Dialog dialog) { | ||
| 125 | +// dialog.dismiss(); | ||
| 126 | +// ActivityCompat.requestPermissions(mActivity, needList, requestCode); | ||
| 127 | +// } | ||
| 128 | +// }); | ||
| 129 | +// } | ||
| 130 | +// | ||
| 131 | +// public void showPermissionPerpetual(int requestCode) { | ||
| 132 | +// | ||
| 133 | +// if (mActivity.dialog != null) mActivity.dialog.dismiss(); | ||
| 134 | +// mActivity.dialog = AlertDialogUtils.showTwoButtonDialog( | ||
| 135 | +// mActivity, | ||
| 136 | +// mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel), | ||
| 137 | +// mActivity.getString(R.string.dialog_imagepicker_permission_confirm), | ||
| 138 | +// mActivity.getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message), | ||
| 139 | +// R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() { | ||
| 140 | +// @Override | ||
| 141 | +// public void onClickLeft(Dialog dialog) { | ||
| 142 | +// dialog.dismiss(); | ||
| 143 | +// showMessage("无法获取存读取权限,您的app将无法正常使用"); | ||
| 144 | +// mActivity.finish(); | ||
| 145 | +// } | ||
| 146 | +// | ||
| 147 | +// @Override | ||
| 148 | +// public void onClickRight(Dialog dialog) { | ||
| 149 | +// dialog.dismiss(); | ||
| 150 | +// PermissionChecker.settingPermissionActivity(mActivity, requestCode); | ||
| 151 | +// mActivity.isNeverAsk = true; | ||
| 152 | +// } | ||
| 153 | +// }); | ||
| 154 | +// | ||
| 155 | +// } | ||
| 156 | +//} |
lib_media/src/main/java/com/cnlive/media/model/ImagePickerOptions.java
| @@ -2,6 +2,7 @@ package com.cnlive.media.model; | @@ -2,6 +2,7 @@ package com.cnlive.media.model; | ||
| 2 | 2 | ||
| 3 | import android.os.Parcel; | 3 | import android.os.Parcel; |
| 4 | import android.os.Parcelable; | 4 | import android.os.Parcelable; |
| 5 | +import android.util.Log; | ||
| 5 | 6 | ||
| 6 | import com.cnlive.media.PickerConfig; | 7 | import com.cnlive.media.PickerConfig; |
| 7 | import com.cnlive.media.media.entity.Media; | 8 | import com.cnlive.media.media.entity.Media; |
| @@ -49,7 +50,17 @@ public class ImagePickerOptions implements Parcelable { | @@ -49,7 +50,17 @@ public class ImagePickerOptions implements Parcelable { | ||
| 49 | public boolean isReturnUri = false; | 50 | public boolean isReturnUri = false; |
| 50 | //直接跳转相机 控制相机的模式 0 全支持 1 照片 2 视频 | 51 | //直接跳转相机 控制相机的模式 0 全支持 1 照片 2 视频 |
| 51 | public int jumpCameraMode = -1; | 52 | public int jumpCameraMode = -1; |
| 52 | - public boolean isPreview = false; | 53 | + public boolean isPreview = false; |
| 54 | + public boolean frontCamera = false; | ||
| 55 | + | ||
| 56 | + public boolean isFrontCamera() { | ||
| 57 | + return frontCamera; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + public void setFrontCamera(boolean frontCamera) { | ||
| 61 | + this.frontCamera = frontCamera; | ||
| 62 | + } | ||
| 63 | + | ||
| 53 | public boolean isPreview() { | 64 | public boolean isPreview() { |
| 54 | return isPreview; | 65 | return isPreview; |
| 55 | } | 66 | } |
| @@ -59,7 +70,6 @@ public class ImagePickerOptions implements Parcelable { | @@ -59,7 +70,6 @@ public class ImagePickerOptions implements Parcelable { | ||
| 59 | } | 70 | } |
| 60 | 71 | ||
| 61 | 72 | ||
| 62 | - | ||
| 63 | public int getJumpCameraMode() { | 73 | public int getJumpCameraMode() { |
| 64 | return jumpCameraMode; | 74 | return jumpCameraMode; |
| 65 | } | 75 | } |
| @@ -197,6 +207,30 @@ public class ImagePickerOptions implements Parcelable { | @@ -197,6 +207,30 @@ public class ImagePickerOptions implements Parcelable { | ||
| 197 | this.isReturnUri = isReturnUri; | 207 | this.isReturnUri = isReturnUri; |
| 198 | } | 208 | } |
| 199 | 209 | ||
| 210 | + @Override | ||
| 211 | + public String toString() { | ||
| 212 | + return "ImagePickerOptions{" + | ||
| 213 | + "maxNum=" + maxNum + | ||
| 214 | + ", maxVideoSize=" + maxVideoSize + | ||
| 215 | + ", maxImageSize=" + maxImageSize + | ||
| 216 | + ", needCamera=" + needCamera + | ||
| 217 | + ", selectMode=" + selectMode + | ||
| 218 | + ", selects=" + selects + | ||
| 219 | + ", cachePath='" + cachePath + '\'' + | ||
| 220 | + ", videoTrimPath='" + videoTrimPath + '\'' + | ||
| 221 | + ", friendCircle=" + friendCircle + | ||
| 222 | + ", cropParams=" + cropParams + | ||
| 223 | + ", needCrop=" + needCrop + | ||
| 224 | + ", singlePick=" + singlePick + | ||
| 225 | + ", showTime=" + showTime + | ||
| 226 | + ", maxTime=" + maxTime + | ||
| 227 | + ", selectGift=" + selectGift + | ||
| 228 | + ", isReturnUri=" + isReturnUri + | ||
| 229 | + ", jumpCameraMode=" + jumpCameraMode + | ||
| 230 | + ", isPreview=" + isPreview + | ||
| 231 | + ", frontCamera=" + frontCamera + | ||
| 232 | + '}'; | ||
| 233 | + } | ||
| 200 | 234 | ||
| 201 | @Override | 235 | @Override |
| 202 | public int describeContents() { | 236 | public int describeContents() { |
| @@ -222,6 +256,7 @@ public class ImagePickerOptions implements Parcelable { | @@ -222,6 +256,7 @@ public class ImagePickerOptions implements Parcelable { | ||
| 222 | isReturnUri = in.readByte() != 0; | 256 | isReturnUri = in.readByte() != 0; |
| 223 | jumpCameraMode = in.readInt(); | 257 | jumpCameraMode = in.readInt(); |
| 224 | isPreview = in.readByte() != 0; | 258 | isPreview = in.readByte() != 0; |
| 259 | + frontCamera = in.readByte() != 0; | ||
| 225 | } | 260 | } |
| 226 | 261 | ||
| 227 | public static final Creator<ImagePickerOptions> CREATOR = new Creator<ImagePickerOptions>() { | 262 | public static final Creator<ImagePickerOptions> CREATOR = new Creator<ImagePickerOptions>() { |
| @@ -255,6 +290,7 @@ public class ImagePickerOptions implements Parcelable { | @@ -255,6 +290,7 @@ public class ImagePickerOptions implements Parcelable { | ||
| 255 | dest.writeByte((byte) (selectGift ? 1 : 0)); | 290 | dest.writeByte((byte) (selectGift ? 1 : 0)); |
| 256 | dest.writeByte((byte) (isReturnUri ? 1 : 0)); | 291 | dest.writeByte((byte) (isReturnUri ? 1 : 0)); |
| 257 | dest.writeInt(jumpCameraMode); | 292 | dest.writeInt(jumpCameraMode); |
| 258 | - dest.writeByte((byte)(isPreview ? 1 : 0));; | 293 | + dest.writeByte((byte) (isPreview ? 1 : 0)); |
| 294 | + dest.writeByte((byte) (frontCamera ? 1 : 0)); | ||
| 259 | } | 295 | } |
| 260 | } | 296 | } |
lib_media/src/main/java/com/cnlive/media/ui/activity/DiyCameraActivity.java
0 → 100644
| 1 | +package com.cnlive.media.ui.activity; | ||
| 2 | + | ||
| 3 | +import android.Manifest; | ||
| 4 | +import android.annotation.TargetApi; | ||
| 5 | +import android.app.Activity; | ||
| 6 | +import android.app.Dialog; | ||
| 7 | +import android.content.ContentResolver; | ||
| 8 | +import android.content.ContentValues; | ||
| 9 | +import android.content.Context; | ||
| 10 | +import android.content.Intent; | ||
| 11 | +import android.content.pm.PackageManager; | ||
| 12 | +import android.database.Cursor; | ||
| 13 | +import android.graphics.Bitmap; | ||
| 14 | +import android.hardware.Camera; | ||
| 15 | +import android.net.Uri; | ||
| 16 | +import android.os.Build; | ||
| 17 | +import android.os.Bundle; | ||
| 18 | +import android.os.Environment; | ||
| 19 | +import android.provider.MediaStore; | ||
| 20 | +import android.text.TextUtils; | ||
| 21 | +import android.util.Log; | ||
| 22 | +import android.view.View; | ||
| 23 | +import android.view.WindowManager; | ||
| 24 | +import android.widget.ImageView; | ||
| 25 | +import android.widget.Toast; | ||
| 26 | + | ||
| 27 | +import androidx.appcompat.app.AppCompatActivity; | ||
| 28 | +import androidx.core.app.ActivityCompat; | ||
| 29 | +import androidx.core.content.FileProvider; | ||
| 30 | + | ||
| 31 | +import com.cnlive.libs.base.observable.NotifyTrtcAnswerObservable; | ||
| 32 | +import com.cnlive.libs.base.util.AlertUtil; | ||
| 33 | +import com.cnlive.libs.util.data.okio.BufferedSource; | ||
| 34 | +import com.cnlive.libs.util.data.okio.Okio; | ||
| 35 | +import com.cnlive.libs.util.data.okio.Sink; | ||
| 36 | +import com.cnlive.media.PickerConfig; | ||
| 37 | +import com.cnlive.media.R; | ||
| 38 | +import com.cnlive.media.media.entity.Media; | ||
| 39 | +import com.cnlive.media.model.CircleChoose; | ||
| 40 | +import com.cnlive.media.model.CircleData; | ||
| 41 | +import com.cnlive.media.model.ImagePickerOptions; | ||
| 42 | +import com.cnlive.media.ui.adapter.RecyclerviewAdapter; | ||
| 43 | +import com.cnlive.media.ui.widget.record.JCameraView; | ||
| 44 | +import com.cnlive.media.ui.widget.record.listener.ClickListener; | ||
| 45 | +import com.cnlive.media.ui.widget.record.listener.JCameraListener; | ||
| 46 | +import com.cnlive.media.utils.AlertDialogUtils; | ||
| 47 | +import com.cnlive.media.utils.AndroidQUtil; | ||
| 48 | +import com.cnlive.media.utils.FileUtils; | ||
| 49 | +import com.cnlive.media.utils.MediaUtils; | ||
| 50 | +import com.cnlive.media.utils.PermissionChecker; | ||
| 51 | +import com.cnlive.media.utils.album.AlbumProcessUtil; | ||
| 52 | +import com.cnlive.media.utils.album.OnSaveCallback; | ||
| 53 | +import com.cnlive.media.utils.observable.MediaAddObservable; | ||
| 54 | +import com.cnlive.media.utils.observable.MeidaResultObservable; | ||
| 55 | +import com.google.gson.Gson; | ||
| 56 | + | ||
| 57 | +import org.greenrobot.eventbus.EventBus; | ||
| 58 | + | ||
| 59 | +import java.io.File; | ||
| 60 | +import java.io.IOException; | ||
| 61 | +import java.io.OutputStream; | ||
| 62 | +import java.util.ArrayList; | ||
| 63 | +import java.util.List; | ||
| 64 | + | ||
| 65 | +import io.reactivex.Observable; | ||
| 66 | +import io.reactivex.ObservableOnSubscribe; | ||
| 67 | +import io.reactivex.Observer; | ||
| 68 | +import io.reactivex.android.schedulers.AndroidSchedulers; | ||
| 69 | +import io.reactivex.disposables.Disposable; | ||
| 70 | +import io.reactivex.schedulers.Schedulers; | ||
| 71 | + | ||
| 72 | +/** | ||
| 73 | + * 类介绍(必填): | ||
| 74 | + * | ||
| 75 | + * @author Lynn | ||
| 76 | + */ | ||
| 77 | + | ||
| 78 | +public class DiyCameraActivity extends AppCompatActivity implements RecyclerviewAdapter.MyClickListener, java.util.Observer { | ||
| 79 | + | ||
| 80 | + private final int GET_PERMISSION_REQUEST = 100; //权限申请自定义码 | ||
| 81 | + private JCameraView jCameraView; | ||
| 82 | + private boolean granted = false; | ||
| 83 | + private ImagePickerOptions mOptions; | ||
| 84 | + private String cachePath; | ||
| 85 | + private int resultCode; | ||
| 86 | + private int maxTime; | ||
| 87 | + private ArrayList<Media> oldlist; | ||
| 88 | + private int shootMode = 0; | ||
| 89 | + // private RecyclerView circleview; | ||
| 90 | + private String endurl = ""; | ||
| 91 | + private int enddutain = 0; | ||
| 92 | + private ImageView cameraback; | ||
| 93 | + private String sendcircle; | ||
| 94 | + private boolean frontCamera; | ||
| 95 | + public boolean isNeedAudio = true; | ||
| 96 | + //是否没有申请权限 | ||
| 97 | + public boolean isNeverAsk; | ||
| 98 | + //是否是直接跳转相机 | ||
| 99 | + public boolean isJumpCamera; | ||
| 100 | + private Dialog permissionsDialog; | ||
| 101 | + private CircleData.ReleaseVideoTypeListBean relea; | ||
| 102 | + public static String[] permissionsRecord = Build.VERSION.SDK_INT >= 33 ? | ||
| 103 | + new String[]{ | ||
| 104 | + Manifest.permission.CAMERA, | ||
| 105 | + Manifest.permission.RECORD_AUDIO, | ||
| 106 | + "android.permission.READ_MEDIA_IMAGES", | ||
| 107 | + "android.permission.READ_MEDIA_AUDIO", | ||
| 108 | + "android.permission.READ_MEDIA_VIDEO"} : | ||
| 109 | + new String[]{ | ||
| 110 | + Manifest.permission.CAMERA, | ||
| 111 | + Manifest.permission.RECORD_AUDIO, | ||
| 112 | + Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 113 | + Manifest.permission.WRITE_EXTERNAL_STORAGE}; | ||
| 114 | + public static String[] permissionsRecordNoAudio = Build.VERSION.SDK_INT >= 33 ? | ||
| 115 | + new String[]{ | ||
| 116 | + Manifest.permission.CAMERA, | ||
| 117 | + Manifest.permission.RECORD_AUDIO, | ||
| 118 | + "android.permission.READ_MEDIA_IMAGES", | ||
| 119 | + "android.permission.READ_MEDIA_AUDIO", | ||
| 120 | + "android.permission.READ_MEDIA_VIDEO"} : | ||
| 121 | + new String[]{ | ||
| 122 | + Manifest.permission.CAMERA, | ||
| 123 | + Manifest.permission.RECORD_AUDIO, | ||
| 124 | + Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 125 | + Manifest.permission.WRITE_EXTERNAL_STORAGE}; | ||
| 126 | + | ||
| 127 | + // private List<CircleData.ReleaseVideoTypeListBean> releaseVideoTypeListBeans; | ||
| 128 | + | ||
| 129 | + public static void start(Activity context, ArrayList<Media> list, ImagePickerOptions mOptions, int resultCode) { | ||
| 130 | + Intent starter = new Intent(context, DiyCameraActivity.class); | ||
| 131 | + starter.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | ||
| 132 | + starter.putExtra(PickerConfig.RESULT_CODE, resultCode); | ||
| 133 | + starter.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true); | ||
| 134 | + starter.putParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS, list); | ||
| 135 | + context.startActivityForResult(starter, 200); | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + public static void start(Activity context, ArrayList<Media> list, int resultCode, String sendcircle) { | ||
| 139 | + Intent starter = new Intent(context, DiyCameraActivity.class); | ||
| 140 | + starter.putExtra(PickerConfig.RESULT_CODE, resultCode); | ||
| 141 | + starter.putParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS, list); | ||
| 142 | + starter.putExtra("sendcircle", sendcircle); | ||
| 143 | + context.startActivityForResult(starter, 200); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + | ||
| 147 | + @Override | ||
| 148 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 149 | + super.onCreate(savedInstanceState); | ||
| 150 | + setContentView(R.layout.camera_intent); | ||
| 151 | + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); | ||
| 152 | + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); | ||
| 153 | + NotifyTrtcAnswerObservable.newInstance().addObserver(this); | ||
| 154 | + MeidaResultObservable.getInstance().addObserver(this); | ||
| 155 | + mOptions = getIntent().getParcelableExtra(PickerConfig.INTENT_KEY_OPTIONS); | ||
| 156 | + | ||
| 157 | +// shootMode = getIntent().getIntExtra(PickerConfig.CAMERA_SELECT_MODE, 0); | ||
| 158 | + shootMode = mOptions.getJumpCameraMode(); | ||
| 159 | +// cachePath = getIntent().getStringExtra(PickerConfig.CACHE_PATH); | ||
| 160 | + isJumpCamera = getIntent().getBooleanExtra(PickerConfig.WHERE_JUMP_CAMERA, false); | ||
| 161 | + if (TextUtils.isEmpty(mOptions.getCachePath())) { | ||
| 162 | + if (AndroidQUtil.isAndroidQ()) { | ||
| 163 | + cachePath = getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo"; | ||
| 164 | + } else { | ||
| 165 | + cachePath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerVideo"; | ||
| 166 | + } | ||
| 167 | + } else { | ||
| 168 | + if (AndroidQUtil.isAndroidQ()) { | ||
| 169 | + cachePath = getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo"; | ||
| 170 | + } else { | ||
| 171 | + cachePath = mOptions.getCachePath(); | ||
| 172 | + } | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + if (mOptions.getJumpCameraMode() == PickerConfig.CAMERA_MODE_PIC) { | ||
| 176 | + isNeedAudio = false; | ||
| 177 | + } else { | ||
| 178 | + isNeedAudio = true; | ||
| 179 | + } | ||
| 180 | + resultCode = getIntent().getIntExtra(PickerConfig.RESULT_CODE, PickerConfig.DEFAULT_RESULT_CODE); | ||
| 181 | + maxTime = mOptions.getMaxTime() + 900;//录制时长增加900毫秒,解决部分手机只显示时间少一秒问题 | ||
| 182 | + oldlist = getIntent().getParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS); | ||
| 183 | + if (oldlist == null) oldlist = new ArrayList<Media>(); | ||
| 184 | + sendcircle = getIntent().getStringExtra("sendcircle"); | ||
| 185 | +// onlineanswer = getIntent().hasExtra(PickerConfig.ONLINE_ANSWER) ? getIntent().getStringExtra(PickerConfig.ONLINE_ANSWER) : ""; | ||
| 186 | + frontCamera = mOptions.isFrontCamera(); | ||
| 187 | + jCameraView = (JCameraView) findViewById(R.id.jcameraview); | ||
| 188 | + // circleview = findViewById(R.id.recyclerView); | ||
| 189 | + cameraback = findViewById(R.id.cameraback); | ||
| 190 | + // circleview.setVisibility(View.GONE); | ||
| 191 | + cameraback.setVisibility(View.GONE); | ||
| 192 | + relea = new Gson().fromJson(sendcircle, CircleData.ReleaseVideoTypeListBean.class); | ||
| 193 | + /* if (relea==null){ | ||
| 194 | + releaseVideoTypeListBeans = new ArrayList<CircleData.ReleaseVideoTypeListBean>(); | ||
| 195 | + }else { | ||
| 196 | + releaseVideoTypeListBeans = Arrays.asList(relea); | ||
| 197 | + }*/ | ||
| 198 | + // LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false); | ||
| 199 | + // layoutManager.setSmoothScrollbarEnabled(false); | ||
| 200 | + // circleview.setNestedScrollingEnabled(false); | ||
| 201 | + // circleview.setLayoutManager(layoutManager); | ||
| 202 | + // circleview.setAdapter(new RecyclerviewAdapter(getContext(),releaseVideoTypeListBeans,this)); | ||
| 203 | + if (maxTime > 5_000) jCameraView.setDuration(maxTime); | ||
| 204 | + //设置视频保存路径 | ||
| 205 | + jCameraView.setSaveVideoPath(cachePath); | ||
| 206 | + | ||
| 207 | + if (frontCamera) { | ||
| 208 | + jCameraView.setFront(Camera.CameraInfo.CAMERA_FACING_FRONT); | ||
| 209 | + } else { | ||
| 210 | + jCameraView.setFront(Camera.CameraInfo.CAMERA_FACING_BACK); | ||
| 211 | + } | ||
| 212 | + if (shootMode == JCameraView.BUTTON_STATE_ONLY_RECORDER) { | ||
| 213 | + jCameraView.setFeatures(JCameraView.BUTTON_STATE_ONLY_RECORDER); | ||
| 214 | + } else if (shootMode == JCameraView.BUTTON_STATE_ONLY_CAPTURE || (oldlist != null && oldlist.size() > 0)) { | ||
| 215 | + jCameraView.setFeatures(JCameraView.BUTTON_STATE_ONLY_CAPTURE); | ||
| 216 | + } else { | ||
| 217 | + jCameraView.setFeatures(JCameraView.BUTTON_STATE_BOTH); | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + | ||
| 221 | + //JCameraView监听 | ||
| 222 | + jCameraView.setJCameraLisenter(new JCameraListener() { | ||
| 223 | + @Override | ||
| 224 | + public void captureSuccess(Bitmap bitmap) { | ||
| 225 | + savePic(DiyCameraActivity.this, bitmap); | ||
| 226 | +// Observable.create((ObservableOnSubscribe<String>) emitter -> { | ||
| 227 | +// if (bitmap != null) { | ||
| 228 | +// String filePath; | ||
| 229 | +// if (AndroidQUtil.isAndroidQ()) { | ||
| 230 | +// String name = System.currentTimeMillis() + ".png"; | ||
| 231 | +// filePath = AndroidQUtil.saveSignImageBox(DiyCameraActivity.this, name, bitmap); | ||
| 232 | +// } else { | ||
| 233 | +// filePath = FileUtils.saveBitmap(DiyCameraActivity.this, cachePath, bitmap); | ||
| 234 | +// | ||
| 235 | +// } | ||
| 236 | +// emitter.onNext(filePath); | ||
| 237 | +// } else { | ||
| 238 | +// emitter.onError(new Throwable("")); | ||
| 239 | +// } | ||
| 240 | +// | ||
| 241 | +// }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() { | ||
| 242 | +// @Override | ||
| 243 | +// public void onSubscribe(Disposable d) { | ||
| 244 | +// | ||
| 245 | +// } | ||
| 246 | +// | ||
| 247 | +// @Override | ||
| 248 | +// public void onNext(String path) { | ||
| 249 | +// | ||
| 250 | +// if (!TextUtils.isEmpty(path)) { | ||
| 251 | +// //获取图片bitmap | ||
| 252 | +// Media media; | ||
| 253 | +// | ||
| 254 | +// Intent intent = new Intent(); | ||
| 255 | +// if (AndroidQUtil.isAndroidQ()) { | ||
| 256 | +// File file = new File(path); | ||
| 257 | +// media = new Media(path, file.getName(), 0, 1, file.length(), 0, "", Uri.fromFile(file).toString()); | ||
| 258 | +// } else { | ||
| 259 | +// File file = new File(path); | ||
| 260 | +// media = new Media(file.getPath(), file.getName(), 0, 1, file.length(), 0, "", ""); | ||
| 261 | +// } | ||
| 262 | +// oldlist.add(media); | ||
| 263 | +// intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, oldlist); | ||
| 264 | +// intent.putExtra("isCircleVideo", "nocircle"); | ||
| 265 | +// setResult(resultCode, intent); | ||
| 266 | +// finish(); | ||
| 267 | +// } else { | ||
| 268 | +// Toast.makeText(DiyCameraActivity.this, "文件异常", Toast.LENGTH_SHORT).show(); | ||
| 269 | +// } | ||
| 270 | +// | ||
| 271 | +// } | ||
| 272 | +// | ||
| 273 | +// @Override | ||
| 274 | +// public void onError(Throwable e) { | ||
| 275 | +// Toast.makeText(DiyCameraActivity.this, "文件异常", Toast.LENGTH_SHORT).show(); | ||
| 276 | +// } | ||
| 277 | +// | ||
| 278 | +// @Override | ||
| 279 | +// public void onComplete() { | ||
| 280 | +// | ||
| 281 | +// } | ||
| 282 | +// }); | ||
| 283 | + | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + @Override | ||
| 287 | + public void recordSuccess(String url, int duration) { | ||
| 288 | + enddutain = duration; | ||
| 289 | + endurl = url; | ||
| 290 | + saveVideo(DiyCameraActivity.this, url); | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + @Override | ||
| 294 | + public void recordEnd(String url, int duration) { | ||
| 295 | + if (relea != null) { | ||
| 296 | + // jCameraView.setButtonVisiblity(); | ||
| 297 | + // circleview.setVisibility(View.GONE); | ||
| 298 | + cameraback.setVisibility(View.VISIBLE); | ||
| 299 | + } | ||
| 300 | + endurl = url; | ||
| 301 | + enddutain = duration; | ||
| 302 | + } | ||
| 303 | + }); | ||
| 304 | + cameraback.setOnClickListener(new View.OnClickListener() { | ||
| 305 | + @Override | ||
| 306 | + public void onClick(View v) { | ||
| 307 | + finish(); | ||
| 308 | + } | ||
| 309 | + }); | ||
| 310 | + | ||
| 311 | + jCameraView.setLeftClickListener(new ClickListener() { | ||
| 312 | + @Override | ||
| 313 | + public void onClick() { | ||
| 314 | + finish(); | ||
| 315 | + } | ||
| 316 | + }); | ||
| 317 | + | ||
| 318 | + jCameraView.setRightClickListener(new ClickListener() { | ||
| 319 | + @Override | ||
| 320 | + public void onClick() { | ||
| 321 | + if (!"".equals(endurl)) { | ||
| 322 | + saveVideo(DiyCameraActivity.this, endurl); | ||
| 323 | + } | ||
| 324 | + } | ||
| 325 | + }); | ||
| 326 | + | ||
| 327 | + //6.0动态权限获取 | ||
| 328 | + checkPermisssion(); | ||
| 329 | + if (granted) { | ||
| 330 | + jCameraView.onResume(); | ||
| 331 | + } | ||
| 332 | + } | ||
| 333 | + | ||
| 334 | + | ||
| 335 | + @Override | ||
| 336 | + protected void onStart() { | ||
| 337 | + super.onStart(); | ||
| 338 | + //全屏显示 | ||
| 339 | + if (Build.VERSION.SDK_INT >= 19) { | ||
| 340 | + View decorView = getWindow().getDecorView(); | ||
| 341 | + decorView.setSystemUiVisibility( | ||
| 342 | + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||
| 343 | + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||
| 344 | + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | ||
| 345 | + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | ||
| 346 | + | View.SYSTEM_UI_FLAG_FULLSCREEN | ||
| 347 | + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); | ||
| 348 | + } else { | ||
| 349 | + View decorView = getWindow().getDecorView(); | ||
| 350 | + int option = View.SYSTEM_UI_FLAG_FULLSCREEN; | ||
| 351 | + decorView.setSystemUiVisibility(option); | ||
| 352 | + } | ||
| 353 | + } | ||
| 354 | + | ||
| 355 | + @Override | ||
| 356 | + protected void onResume() { | ||
| 357 | + super.onResume(); | ||
| 358 | + if (isNeverAsk) { | ||
| 359 | + isNeverAsk = false; | ||
| 360 | + //永久拒绝后,返回页面时检测权限并初始化 | ||
| 361 | + checkPermisssion(); | ||
| 362 | + } | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | + @Override | ||
| 366 | + protected void onPause() { | ||
| 367 | + super.onPause(); | ||
| 368 | + // jCameraView.onStop(); | ||
| 369 | + // jCameraView.onDestroy(); | ||
| 370 | + } | ||
| 371 | + | ||
| 372 | + | ||
| 373 | + @Override | ||
| 374 | + protected void onStop() { | ||
| 375 | + super.onStop(); | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + @Override | ||
| 379 | + protected void onDestroy() { | ||
| 380 | + jCameraView.onStop(); | ||
| 381 | + jCameraView.onDestroy(); | ||
| 382 | + super.onDestroy(); | ||
| 383 | + NotifyTrtcAnswerObservable.newInstance().deleteObserver(this); | ||
| 384 | + MeidaResultObservable.getInstance().deleteObserver(this); | ||
| 385 | + } | ||
| 386 | + | ||
| 387 | + @Override | ||
| 388 | + public void update(java.util.Observable o, Object arg) { | ||
| 389 | + if (o instanceof MeidaResultObservable) { | ||
| 390 | + Media media = (Media) arg; | ||
| 391 | + if (isJumpCamera) { | ||
| 392 | + if (oldlist == null) | ||
| 393 | + oldlist = new ArrayList<Media>(); | ||
| 394 | + oldlist.add(media); | ||
| 395 | + Intent intent = new Intent(); | ||
| 396 | + intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, oldlist); | ||
| 397 | + setResult(resultCode, intent); | ||
| 398 | + finish(); | ||
| 399 | + } else { | ||
| 400 | + finish(); | ||
| 401 | + } | ||
| 402 | + } else if (o instanceof NotifyTrtcAnswerObservable) { | ||
| 403 | + AlertUtil.showDeftToast(this, "通话已接通,待通话结束再进入。"); | ||
| 404 | + finish(); | ||
| 405 | + } | ||
| 406 | + | ||
| 407 | + } | ||
| 408 | + | ||
| 409 | + @TargetApi(23) | ||
| 410 | + @Override | ||
| 411 | + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { | ||
| 412 | + super.onRequestPermissionsResult(requestCode, permissions, grantResults); | ||
| 413 | + | ||
| 414 | + if (requestCode == GET_PERMISSION_REQUEST) { | ||
| 415 | + | ||
| 416 | + boolean[] hasPermissions = onRequestPermissions(requestCode, permissions, grantResults); | ||
| 417 | + if (hasPermissions[0]) { | ||
| 418 | + checkPermisssion(); | ||
| 419 | + } else if (hasPermissions[1]) { //权限永久拒绝的处理 | ||
| 420 | + showPermissionPerpetual(requestCode); | ||
| 421 | + } else { //权限没有全部同意 | ||
| 422 | + if (isNeedAudio) { | ||
| 423 | + showPermission(permissionsRecord, GET_PERMISSION_REQUEST); | ||
| 424 | + } else { | ||
| 425 | + showPermission(permissionsRecordNoAudio, GET_PERMISSION_REQUEST); | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + } | ||
| 429 | + } | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + //检测权限 | ||
| 433 | + public void checkPermisssion() { | ||
| 434 | + boolean hasPermissions; | ||
| 435 | + if (isNeedAudio) { | ||
| 436 | + hasPermissions = checkPermissions(this, permissionsRecord, GET_PERMISSION_REQUEST, true); | ||
| 437 | + } else { | ||
| 438 | + hasPermissions = checkPermissions(this, permissionsRecordNoAudio, GET_PERMISSION_REQUEST, true); | ||
| 439 | + } | ||
| 440 | + if (hasPermissions) { | ||
| 441 | +// mActivity.getSupportFragmentManager().beginTransaction().replace(R.id.pre_frame, RecordFragment.newInstance()).addToBackStack("").commitAllowingStateLoss(); | ||
| 442 | + jCameraView.onResume(); | ||
| 443 | + } | ||
| 444 | + | ||
| 445 | + } | ||
| 446 | + | ||
| 447 | + public boolean[] onRequestPermissions(int requestCode, String[] permissions, int[] grantResults) { | ||
| 448 | + | ||
| 449 | + boolean result = true; | ||
| 450 | + boolean isNeverAsk = false; | ||
| 451 | + | ||
| 452 | + int length = grantResults.length; | ||
| 453 | + for (int i = 0; i < length; i++) { | ||
| 454 | + String permission = permissions[i]; | ||
| 455 | + int grandResult = grantResults[i]; | ||
| 456 | + if (grandResult == PackageManager.PERMISSION_DENIED) { | ||
| 457 | + result = false; | ||
| 458 | + if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) | ||
| 459 | + isNeverAsk = true; | ||
| 460 | + } | ||
| 461 | + } | ||
| 462 | + | ||
| 463 | + return new boolean[]{result, isNeverAsk}; | ||
| 464 | + } | ||
| 465 | + | ||
| 466 | + public void showPermission(String[] needList, int requestCode) { | ||
| 467 | + if (permissionsDialog != null) permissionsDialog.dismiss(); | ||
| 468 | + permissionsDialog = AlertDialogUtils.showTwoButtonDialog( | ||
| 469 | + this, | ||
| 470 | + getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel), | ||
| 471 | + getString(R.string.dialog_imagepicker_permission_confirm), | ||
| 472 | + getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message), | ||
| 473 | + R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() { | ||
| 474 | + @Override | ||
| 475 | + public void onClickLeft(Dialog dialog) { | ||
| 476 | + dialog.dismiss(); | ||
| 477 | + showMessage("无法获取存读取权限,您的app将无法正常使用"); | ||
| 478 | + finish(); | ||
| 479 | + } | ||
| 480 | + | ||
| 481 | + @Override | ||
| 482 | + public void onClickRight(Dialog dialog) { | ||
| 483 | + dialog.dismiss(); | ||
| 484 | + ActivityCompat.requestPermissions(DiyCameraActivity.this, needList, requestCode); | ||
| 485 | + } | ||
| 486 | + }); | ||
| 487 | + } | ||
| 488 | + | ||
| 489 | + public void showMessage(String message) { | ||
| 490 | + | ||
| 491 | + if (TextUtils.isEmpty(message)) return; | ||
| 492 | + runOnUiThread(new Runnable() { | ||
| 493 | + @Override | ||
| 494 | + public void run() { | ||
| 495 | + AlertUtil.showDeftToast(DiyCameraActivity.this, message); | ||
| 496 | + } | ||
| 497 | + }); | ||
| 498 | + | ||
| 499 | + | ||
| 500 | + } | ||
| 501 | + | ||
| 502 | + public void showPermissionPerpetual(int requestCode) { | ||
| 503 | + | ||
| 504 | + if (permissionsDialog != null) permissionsDialog.dismiss(); | ||
| 505 | + permissionsDialog = AlertDialogUtils.showTwoButtonDialog( | ||
| 506 | + this, | ||
| 507 | + getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel), | ||
| 508 | + getString(R.string.dialog_imagepicker_permission_confirm), | ||
| 509 | + getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message), | ||
| 510 | + R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() { | ||
| 511 | + @Override | ||
| 512 | + public void onClickLeft(Dialog dialog) { | ||
| 513 | + dialog.dismiss(); | ||
| 514 | + showMessage("无法获取存读取权限,您的app将无法正常使用"); | ||
| 515 | + finish(); | ||
| 516 | + } | ||
| 517 | + | ||
| 518 | + @Override | ||
| 519 | + public void onClickRight(Dialog dialog) { | ||
| 520 | + dialog.dismiss(); | ||
| 521 | + PermissionChecker.settingPermissionActivity(DiyCameraActivity.this, requestCode); | ||
| 522 | + isNeverAsk = true; | ||
| 523 | + } | ||
| 524 | + }); | ||
| 525 | + | ||
| 526 | + } | ||
| 527 | + | ||
| 528 | + public boolean checkPermissions(Activity activity, String[] permissions, int requestCode, boolean request) { | ||
| 529 | + //Android6.0以下默认有权限 | ||
| 530 | + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) | ||
| 531 | + return true; | ||
| 532 | + | ||
| 533 | + List<String> needList = new ArrayList<>(); | ||
| 534 | + boolean needShowRationale = false; | ||
| 535 | + | ||
| 536 | + for (String permisson : permissions) { | ||
| 537 | + if (TextUtils.isEmpty(permisson)) continue; | ||
| 538 | + if (ActivityCompat.checkSelfPermission(activity, permisson) | ||
| 539 | + != PackageManager.PERMISSION_GRANTED) { | ||
| 540 | + needList.add(permisson); | ||
| 541 | + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permisson)) | ||
| 542 | + needShowRationale = true; | ||
| 543 | + } | ||
| 544 | + } | ||
| 545 | + | ||
| 546 | + if (needList.size() != 0) { | ||
| 547 | + final int count = needList.size(); | ||
| 548 | + String[] needArray = needList.toArray(new String[count]); | ||
| 549 | + if (needShowRationale) { | ||
| 550 | + showPermission(needArray, requestCode); | ||
| 551 | + } else if (request) { | ||
| 552 | + ActivityCompat.requestPermissions(activity, needArray, requestCode); | ||
| 553 | + } | ||
| 554 | + return false; | ||
| 555 | + } else { | ||
| 556 | + return true; | ||
| 557 | + } | ||
| 558 | + } | ||
| 559 | + | ||
| 560 | + | ||
| 561 | + @Override | ||
| 562 | + public void clickListener(View v) { | ||
| 563 | +// Intent intent = new Intent(); | ||
| 564 | +// if (!"".equals(endurl)) { | ||
| 565 | +// File file = new File(endurl); | ||
| 566 | +// ArrayList<Media> medias = new ArrayList<>(); | ||
| 567 | +// Media media = new Media(file.getPath(), file.getName(), enddutain, 3, file.length(), 0, "", enddutain); | ||
| 568 | +// medias.add(media); | ||
| 569 | +// oldlist.add(media); | ||
| 570 | +// CircleData.ReleaseVideoTypeListBean releaseVideoTypeListBean = releaseVideoTypeListBeans.get((Integer) v.getTag()); | ||
| 571 | +// intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, oldlist); | ||
| 572 | +// intent.putExtra("isCircleVideo", "cancircle"); | ||
| 573 | +// EventBus.getDefault().postSticky(new CircleChoose(releaseVideoTypeListBean)); | ||
| 574 | +// setResult(resultCode, intent); | ||
| 575 | +// finish(); | ||
| 576 | +// } | ||
| 577 | + } | ||
| 578 | + | ||
| 579 | + public void savePic(DiyCameraActivity mActivity, Bitmap preBitmap) { | ||
| 580 | + | ||
| 581 | + AlbumProcessUtil.saveBitmap(mActivity, preBitmap, new OnSaveCallback() { | ||
| 582 | + @Override | ||
| 583 | + public void onSuccess(String path) { | ||
| 584 | + File file = new File(path); | ||
| 585 | + if (file != null && file.exists() && file.canRead() && file.canWrite()) { | ||
| 586 | + | ||
| 587 | + Uri uri = FileProvider.getUriForFile(mActivity, mActivity.getApplicationContext().getPackageName() + ".fileprovider", file); | ||
| 588 | + Media media = new Media(path, file.getName(), System.currentTimeMillis(), 1, file.length(), (int) System.currentTimeMillis(), file.getParent(), uri.toString()); | ||
| 589 | + media.setSelect(false); | ||
| 590 | + media.setReturnUri(mActivity.mOptions.isReturnUri()); | ||
| 591 | + if (preBitmap != null && preBitmap.getHeight() > 0 && preBitmap.getWidth() > 0) { | ||
| 592 | + media.setImgHeight(preBitmap.getHeight()); | ||
| 593 | + media.setImgWidth(preBitmap.getWidth()); | ||
| 594 | + media.setLongImg(MediaUtils.isLongImg(preBitmap.getWidth(), preBitmap.getHeight())); | ||
| 595 | + } | ||
| 596 | + if (mActivity.mOptions.needCrop) { | ||
| 597 | + ImageCropActivity.start(mActivity, path, mActivity.mOptions); | ||
| 598 | + } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) { | ||
| 599 | + MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 600 | + mActivity.finish(); | ||
| 601 | + } else if (mActivity.isJumpCamera) { | ||
| 602 | + if (mActivity.oldlist == null) | ||
| 603 | + mActivity.oldlist = new ArrayList<Media>(); | ||
| 604 | + mActivity.oldlist.add(media); | ||
| 605 | + Intent intent = new Intent(); | ||
| 606 | + intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, mActivity.oldlist); | ||
| 607 | + mActivity.setResult(mActivity.resultCode, intent); | ||
| 608 | + mActivity.finish(); | ||
| 609 | + } else { | ||
| 610 | + MediaAddObservable.getInstance().addMedia(media); | ||
| 611 | + mActivity.finish(); | ||
| 612 | + } | ||
| 613 | + | ||
| 614 | + } else { | ||
| 615 | + getOnBackPressedDispatcher().onBackPressed(); | ||
| 616 | + } | ||
| 617 | + } | ||
| 618 | + | ||
| 619 | + @Override | ||
| 620 | + public void onFail(String message) { | ||
| 621 | + showMessage("图片保存异常"); | ||
| 622 | + } | ||
| 623 | + }); | ||
| 624 | + } | ||
| 625 | + | ||
| 626 | + public void saveVideo(DiyCameraActivity mActivity, String path) { | ||
| 627 | + if (TextUtils.isEmpty(path) || mActivity == null) return; | ||
| 628 | +// Intent intent = new Intent(); | ||
| 629 | + File file = new File(path); | ||
| 630 | + Uri uri = FileProvider.getUriForFile(mActivity, mActivity.getApplicationContext().getPackageName() + ".fileprovider", file); | ||
| 631 | + Media media = new Media(path, file.getName(), System.currentTimeMillis(), 3, file.length(), (int) System.currentTimeMillis(), file.getParent(), enddutain, uri.toString()); | ||
| 632 | +// media.setImgWidth(mMediaFile.getVideoWidth()); | ||
| 633 | +// media.setImgHeight(mMediaFile.getVideoHeight()); | ||
| 634 | + media.setSelect(false); | ||
| 635 | + ArrayList<Media> medias = new ArrayList<>(); | ||
| 636 | + | ||
| 637 | + | ||
| 638 | + medias.add(media); | ||
| 639 | +// oldlist.add(media); | ||
| 640 | +// intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, oldlist); | ||
| 641 | + // intent.putExtra("isCircleVideo","nocircle"); | ||
| 642 | +// intent.putExtra("isCircleVideo", "cancircle"); | ||
| 643 | + EventBus.getDefault().postSticky(new CircleChoose(relea)); | ||
| 644 | +// setResult(resultCode, intent); | ||
| 645 | + | ||
| 646 | + media.setReturnUri(mActivity.mOptions.isReturnUri()); | ||
| 647 | + if (mActivity.isJumpCamera) { | ||
| 648 | + MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 649 | + } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) { | ||
| 650 | + MeidaResultObservable.getInstance().finishMedia(true, media); | ||
| 651 | + finish(); | ||
| 652 | + } else { | ||
| 653 | + MediaAddObservable.getInstance().addMedia(media); | ||
| 654 | + finish(); | ||
| 655 | + } | ||
| 656 | + } | ||
| 657 | + | ||
| 658 | +} |
lib_media/src/main/java/com/cnlive/media/ui/activity/RecordActivity.java
| 1 | -package com.cnlive.media.ui.activity; | ||
| 2 | - | ||
| 3 | -import android.Manifest; | ||
| 4 | -import android.app.Dialog; | ||
| 5 | -import android.content.Context; | ||
| 6 | -import android.content.Intent; | ||
| 7 | -import android.graphics.Bitmap; | ||
| 8 | -import android.graphics.Color; | ||
| 9 | -import android.os.Build; | ||
| 10 | -import android.os.Bundle; | ||
| 11 | -import android.view.WindowManager; | ||
| 12 | - | ||
| 13 | -import androidx.annotation.NonNull; | ||
| 14 | -import androidx.fragment.app.Fragment; | ||
| 15 | - | ||
| 16 | -import com.cnlive.libs.base.frame.activity.MvpBindingActivity; | ||
| 17 | -import com.cnlive.libs.base.observable.NotifyTrtcAnswerObservable; | ||
| 18 | -import com.cnlive.libs.base.util.AlertUtil; | ||
| 19 | -import com.cnlive.media.PickerConfig; | ||
| 20 | -import com.cnlive.media.R; | ||
| 21 | -import com.cnlive.media.databinding.ActivityRecordBinding; | ||
| 22 | -import com.cnlive.media.frame.presenter.RecordPresenter; | ||
| 23 | -import com.cnlive.media.frame.view.RecordView; | ||
| 24 | -import com.cnlive.media.media.entity.Media; | ||
| 25 | -import com.cnlive.media.model.ImagePickerOptions; | ||
| 26 | -import com.cnlive.media.ui.fragment.RecordPreviewFragment; | ||
| 27 | -import com.cnlive.media.utils.QiniuVideoUtil; | ||
| 28 | -import com.cnlive.media.utils.observable.MeidaResultObservable; | ||
| 29 | - | ||
| 30 | -import java.util.ArrayList; | ||
| 31 | -import java.util.Observable; | ||
| 32 | -import java.util.Observer; | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -/** | ||
| 36 | - * 作 者 : wkq | ||
| 37 | - * <p> | ||
| 38 | - * 时 间 : 2020/9/22 13:31 | ||
| 39 | - * <p> | ||
| 40 | - * 名 字 : RecordActivity | ||
| 41 | - * <p> | ||
| 42 | - * 简 介 :录像 拍照页面 | ||
| 43 | - */ | ||
| 44 | -public class RecordActivity extends MvpBindingActivity<RecordView, RecordPresenter, Object, ActivityRecordBinding> implements Observer { | ||
| 45 | - | ||
| 46 | - | ||
| 47 | - public ImagePickerOptions mOptions; | ||
| 48 | - public Bitmap preBitmap; | ||
| 49 | - public String videoPath; | ||
| 50 | - public int resultCode; | ||
| 51 | - //是否是直接跳转相机 | ||
| 52 | - public boolean isJumpCamera; | ||
| 53 | - //权限申请弹窗 | ||
| 54 | - public Dialog dialog; | ||
| 55 | - public int PERMISISSION_CODE_ASK = 10010; | ||
| 56 | - //是否没有申请权限 | ||
| 57 | - public boolean isNeverAsk; | ||
| 58 | - public ArrayList<Media> selectMedia; | ||
| 59 | - // 是否需要录音权限 | ||
| 60 | - public boolean isNeedAudio = true; | ||
| 61 | - public static String[] permissionsRecord = Build.VERSION.SDK_INT >= 33 ? | ||
| 62 | - new String[]{ | ||
| 63 | - Manifest.permission.CAMERA, | ||
| 64 | - Manifest.permission.RECORD_AUDIO, | ||
| 65 | - "android.permission.READ_MEDIA_IMAGES", | ||
| 66 | - "android.permission.READ_MEDIA_AUDIO", | ||
| 67 | - "android.permission.READ_MEDIA_VIDEO"} : | ||
| 68 | - new String[]{ | ||
| 69 | - Manifest.permission.CAMERA, | ||
| 70 | - Manifest.permission.RECORD_AUDIO, | ||
| 71 | - Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 72 | - Manifest.permission.WRITE_EXTERNAL_STORAGE}; | ||
| 73 | - public static String[] permissionsRecordNoAudio = Build.VERSION.SDK_INT >= 33 ? | ||
| 74 | - new String[]{ | ||
| 75 | - Manifest.permission.CAMERA, | ||
| 76 | - Manifest.permission.RECORD_AUDIO, | ||
| 77 | - "android.permission.READ_MEDIA_IMAGES", | ||
| 78 | - "android.permission.READ_MEDIA_AUDIO", | ||
| 79 | - "android.permission.READ_MEDIA_VIDEO"} : | ||
| 80 | - new String[]{ | ||
| 81 | - Manifest.permission.CAMERA, | ||
| 82 | - Manifest.permission.RECORD_AUDIO, | ||
| 83 | - Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 84 | - Manifest.permission.WRITE_EXTERNAL_STORAGE}; | ||
| 85 | - | ||
| 86 | - public static void newInstance(Context context, ImagePickerOptions mOptions) { | ||
| 87 | - Intent intent = new Intent(); | ||
| 88 | - intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | ||
| 89 | - intent.setClass(context, RecordActivity.class); | ||
| 90 | - context.startActivity(intent); | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - @Override | ||
| 94 | - protected int getLayoutId() { | ||
| 95 | - return R.layout.activity_record; | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - @Override | ||
| 99 | - protected void onCreate(Bundle savedInstanceState) { | ||
| 100 | - super.onCreate(savedInstanceState); | ||
| 101 | - this.getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT); | ||
| 102 | - //设置全屏,不延伸到刘海屏 | ||
| 103 | - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); | ||
| 104 | - if (getSupportActionBar() != null) getSupportActionBar().hide(); | ||
| 105 | - NotifyTrtcAnswerObservable.newInstance().addObserver(this); | ||
| 106 | - QiniuVideoUtil.chcekInitState(this, state -> { | ||
| 107 | - if (state == 0) { | ||
| 108 | - getMvpView().showMessage("功能维护中"); | ||
| 109 | - onBackPressed(); | ||
| 110 | - } else if (state == 1) { | ||
| 111 | - if (savedInstanceState != null) { | ||
| 112 | - mOptions = savedInstanceState.getParcelable(PickerConfig.INTENT_KEY_OPTIONS); | ||
| 113 | - resultCode = savedInstanceState.getInt(PickerConfig.RESULT_CODE, resultCode); | ||
| 114 | - isJumpCamera = savedInstanceState.getBoolean(PickerConfig.WHERE_JUMP_CAMERA, isJumpCamera); | ||
| 115 | - } else { | ||
| 116 | - resultCode = getIntent().getIntExtra(PickerConfig.RESULT_CODE, 0); | ||
| 117 | - isJumpCamera = getIntent().getBooleanExtra(PickerConfig.WHERE_JUMP_CAMERA, false); | ||
| 118 | - selectMedia = getIntent().getParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS); | ||
| 119 | - mOptions = getIntent().getParcelableExtra(PickerConfig.INTENT_KEY_OPTIONS); | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - MeidaResultObservable.getInstance().addObserver(this); | ||
| 123 | - if (mOptions != null) { | ||
| 124 | - if (mOptions.getJumpCameraMode() == PickerConfig.CAMERA_MODE_PIC) { | ||
| 125 | - isNeedAudio = false; | ||
| 126 | - } else { | ||
| 127 | - isNeedAudio = true; | ||
| 128 | - } | ||
| 129 | - } else { | ||
| 130 | - getMvpView().showMessage("初始化异常"); | ||
| 131 | - onBackPressed(); | ||
| 132 | - } | ||
| 133 | - | ||
| 134 | - if (getMvpView() != null) getMvpView().initView(); | ||
| 135 | - } else { | ||
| 136 | - getMvpView().showMessage("网络故障"); | ||
| 137 | - onBackPressed(); | ||
| 138 | - } | ||
| 139 | - | ||
| 140 | - }); | ||
| 141 | - } | ||
| 142 | - | ||
| 143 | - @Override | ||
| 144 | - protected void onSaveInstanceState(Bundle outState) { | ||
| 145 | - if (mOptions != null) outState.putParcelable(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | ||
| 146 | - outState.putInt(PickerConfig.RESULT_CODE, resultCode); | ||
| 147 | - outState.putBoolean(PickerConfig.WHERE_JUMP_CAMERA, isJumpCamera); | ||
| 148 | - if (selectMedia != null) | ||
| 149 | - outState.putParcelableArrayList(PickerConfig.WHERE_JUMP_CAMERA_SELECTS, selectMedia); | ||
| 150 | - super.onSaveInstanceState(outState); | ||
| 151 | - } | ||
| 152 | - | ||
| 153 | - public void showPreViewImg(Bitmap plbitMap) { | ||
| 154 | - runOnUiThread(new Runnable() { | ||
| 155 | - @Override | ||
| 156 | - public void run() { | ||
| 157 | - preBitmap = plbitMap; | ||
| 158 | - getSupportFragmentManager().beginTransaction().add(R.id.pre_frame, RecordPreviewFragment.newInstance(0, "")).addToBackStack("").commitAllowingStateLoss(); | ||
| 159 | - } | ||
| 160 | - }); | ||
| 161 | - | ||
| 162 | - } | ||
| 163 | - | ||
| 164 | - public void showVideo(String path) { | ||
| 165 | - runOnUiThread(new Runnable() { | ||
| 166 | - @Override | ||
| 167 | - public void run() { | ||
| 168 | - getSupportFragmentManager().beginTransaction().replace(R.id.pre_frame, RecordPreviewFragment.newInstance(1, path)).addToBackStack("").commitAllowingStateLoss(); | ||
| 169 | - } | ||
| 170 | - }); | ||
| 171 | - | ||
| 172 | - } | ||
| 173 | - | ||
| 174 | - @Override | ||
| 175 | - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, | ||
| 176 | - @NonNull int[] grantResults) { | ||
| 177 | - super.onRequestPermissionsResult(requestCode, permissions, grantResults); | ||
| 178 | - if (requestCode == PERMISISSION_CODE_ASK) { | ||
| 179 | - | ||
| 180 | - boolean[] hasPermissions = getPresenter().onRequestPermissionsResult(this, requestCode, permissions, grantResults); | ||
| 181 | - if (hasPermissions[0]) { | ||
| 182 | - if (getMvpView() != null) { //权限正常 | ||
| 183 | - getMvpView().checkPermisssion(); | ||
| 184 | - } | ||
| 185 | - } else if (hasPermissions[1]) { //权限永久拒绝的处理 | ||
| 186 | - getMvpView().showPermissionPerpetual(requestCode); | ||
| 187 | - } else { //权限没有全部同意 | ||
| 188 | - if (isNeedAudio) { | ||
| 189 | - getMvpView().showPermission(permissionsRecord, PERMISISSION_CODE_ASK); | ||
| 190 | - } else { | ||
| 191 | - getMvpView().showPermission(permissionsRecordNoAudio, PERMISISSION_CODE_ASK); | ||
| 192 | - } | ||
| 193 | - | ||
| 194 | - } | ||
| 195 | - } | ||
| 196 | - | ||
| 197 | - } | ||
| 198 | - | ||
| 199 | - @Override | ||
| 200 | - protected void onResume() { | ||
| 201 | - super.onResume(); | ||
| 202 | - if (isNeverAsk) { | ||
| 203 | - isNeverAsk = false; | ||
| 204 | - //永久拒绝后,返回页面时检测权限并初始化 | ||
| 205 | - getMvpView().checkPermisssion(); | ||
| 206 | - } | ||
| 207 | - } | ||
| 208 | - | ||
| 209 | - @Override | ||
| 210 | - protected void onPause() { | ||
| 211 | - super.onPause(); | ||
| 212 | - } | ||
| 213 | - | ||
| 214 | - @Override | ||
| 215 | - protected void onDestroy() { | ||
| 216 | - super.onDestroy(); | ||
| 217 | - MeidaResultObservable.getInstance().deleteObserver(this); | ||
| 218 | - NotifyTrtcAnswerObservable.newInstance().deleteObserver(this); | ||
| 219 | - if (preBitmap != null) { | ||
| 220 | - // glide 加载维护了 bitmap 回收 | ||
| 221 | -// if (!preBitmap.isRecycled()){ | ||
| 222 | -// preBitmap.recycle(); | 1 | +//package com.cnlive.media.ui.activity; |
| 2 | +// | ||
| 3 | +//import android.Manifest; | ||
| 4 | +//import android.app.Dialog; | ||
| 5 | +//import android.content.Context; | ||
| 6 | +//import android.content.Intent; | ||
| 7 | +//import android.graphics.Bitmap; | ||
| 8 | +//import android.graphics.Color; | ||
| 9 | +//import android.os.Build; | ||
| 10 | +//import android.os.Bundle; | ||
| 11 | +//import android.view.WindowManager; | ||
| 12 | +// | ||
| 13 | +//import androidx.annotation.NonNull; | ||
| 14 | +//import androidx.fragment.app.Fragment; | ||
| 15 | +// | ||
| 16 | +//import com.cnlive.libs.base.frame.activity.MvpBindingActivity; | ||
| 17 | +//import com.cnlive.libs.base.observable.NotifyTrtcAnswerObservable; | ||
| 18 | +//import com.cnlive.libs.base.util.AlertUtil; | ||
| 19 | +//import com.cnlive.media.PickerConfig; | ||
| 20 | +//import com.cnlive.media.R; | ||
| 21 | +//import com.cnlive.media.databinding.ActivityRecordBinding; | ||
| 22 | +//import com.cnlive.media.frame.presenter.RecordPresenter; | ||
| 23 | +//import com.cnlive.media.frame.view.RecordView; | ||
| 24 | +//import com.cnlive.media.media.entity.Media; | ||
| 25 | +//import com.cnlive.media.model.ImagePickerOptions; | ||
| 26 | +//import com.cnlive.media.ui.fragment.RecordPreviewFragment; | ||
| 27 | +//import com.cnlive.media.utils.QiniuVideoUtil; | ||
| 28 | +//import com.cnlive.media.utils.observable.MeidaResultObservable; | ||
| 29 | +// | ||
| 30 | +//import java.util.ArrayList; | ||
| 31 | +//import java.util.Observable; | ||
| 32 | +//import java.util.Observer; | ||
| 33 | +// | ||
| 34 | +// | ||
| 35 | +///** | ||
| 36 | +// * 作 者 : wkq | ||
| 37 | +// * <p> | ||
| 38 | +// * 时 间 : 2020/9/22 13:31 | ||
| 39 | +// * <p> | ||
| 40 | +// * 名 字 : RecordActivity | ||
| 41 | +// * <p> | ||
| 42 | +// * 简 介 :录像 拍照页面 | ||
| 43 | +// */ | ||
| 44 | +//public class RecordActivity extends MvpBindingActivity<RecordView, RecordPresenter, Object, ActivityRecordBinding> implements Observer { | ||
| 45 | +// | ||
| 46 | +// | ||
| 47 | +// public ImagePickerOptions mOptions; | ||
| 48 | +// public Bitmap preBitmap; | ||
| 49 | +// public String videoPath; | ||
| 50 | +// public int resultCode; | ||
| 51 | +// //是否是直接跳转相机 | ||
| 52 | +// public boolean isJumpCamera; | ||
| 53 | +// //权限申请弹窗 | ||
| 54 | +// public Dialog dialog; | ||
| 55 | +// public int PERMISISSION_CODE_ASK = 10010; | ||
| 56 | +// //是否没有申请权限 | ||
| 57 | +// public boolean isNeverAsk; | ||
| 58 | +// public ArrayList<Media> selectMedia; | ||
| 59 | +// // 是否需要录音权限 | ||
| 60 | +// public boolean isNeedAudio = true; | ||
| 61 | +// public static String[] permissionsRecord = Build.VERSION.SDK_INT >= 33 ? | ||
| 62 | +// new String[]{ | ||
| 63 | +// Manifest.permission.CAMERA, | ||
| 64 | +// Manifest.permission.RECORD_AUDIO, | ||
| 65 | +// "android.permission.READ_MEDIA_IMAGES", | ||
| 66 | +// "android.permission.READ_MEDIA_AUDIO", | ||
| 67 | +// "android.permission.READ_MEDIA_VIDEO"} : | ||
| 68 | +// new String[]{ | ||
| 69 | +// Manifest.permission.CAMERA, | ||
| 70 | +// Manifest.permission.RECORD_AUDIO, | ||
| 71 | +// Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 72 | +// Manifest.permission.WRITE_EXTERNAL_STORAGE}; | ||
| 73 | +// public static String[] permissionsRecordNoAudio = Build.VERSION.SDK_INT >= 33 ? | ||
| 74 | +// new String[]{ | ||
| 75 | +// Manifest.permission.CAMERA, | ||
| 76 | +// Manifest.permission.RECORD_AUDIO, | ||
| 77 | +// "android.permission.READ_MEDIA_IMAGES", | ||
| 78 | +// "android.permission.READ_MEDIA_AUDIO", | ||
| 79 | +// "android.permission.READ_MEDIA_VIDEO"} : | ||
| 80 | +// new String[]{ | ||
| 81 | +// Manifest.permission.CAMERA, | ||
| 82 | +// Manifest.permission.RECORD_AUDIO, | ||
| 83 | +// Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 84 | +// Manifest.permission.WRITE_EXTERNAL_STORAGE}; | ||
| 85 | +// | ||
| 86 | +// public static void newInstance(Context context, ImagePickerOptions mOptions) { | ||
| 87 | +// Intent intent = new Intent(); | ||
| 88 | +// intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | ||
| 89 | +// intent.setClass(context, RecordActivity.class); | ||
| 90 | +// context.startActivity(intent); | ||
| 91 | +// } | ||
| 92 | +// | ||
| 93 | +// @Override | ||
| 94 | +// protected int getLayoutId() { | ||
| 95 | +// return R.layout.activity_record; | ||
| 96 | +// } | ||
| 97 | +// | ||
| 98 | +// @Override | ||
| 99 | +// protected void onCreate(Bundle savedInstanceState) { | ||
| 100 | +// super.onCreate(savedInstanceState); | ||
| 101 | +// this.getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT); | ||
| 102 | +// //设置全屏,不延伸到刘海屏 | ||
| 103 | +// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); | ||
| 104 | +// if (getSupportActionBar() != null) getSupportActionBar().hide(); | ||
| 105 | +// NotifyTrtcAnswerObservable.newInstance().addObserver(this); | ||
| 106 | +// QiniuVideoUtil.chcekInitState(this, state -> { | ||
| 107 | +// if (state == 0) { | ||
| 108 | +// getMvpView().showMessage("功能维护中"); | ||
| 109 | +// onBackPressed(); | ||
| 110 | +// } else if (state == 1) { | ||
| 111 | +// if (savedInstanceState != null) { | ||
| 112 | +// mOptions = savedInstanceState.getParcelable(PickerConfig.INTENT_KEY_OPTIONS); | ||
| 113 | +// resultCode = savedInstanceState.getInt(PickerConfig.RESULT_CODE, resultCode); | ||
| 114 | +// isJumpCamera = savedInstanceState.getBoolean(PickerConfig.WHERE_JUMP_CAMERA, isJumpCamera); | ||
| 115 | +// } else { | ||
| 116 | +// resultCode = getIntent().getIntExtra(PickerConfig.RESULT_CODE, 0); | ||
| 117 | +// isJumpCamera = getIntent().getBooleanExtra(PickerConfig.WHERE_JUMP_CAMERA, false); | ||
| 118 | +// selectMedia = getIntent().getParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS); | ||
| 119 | +// mOptions = getIntent().getParcelableExtra(PickerConfig.INTENT_KEY_OPTIONS); | ||
| 120 | +// } | ||
| 121 | +// | ||
| 122 | +// MeidaResultObservable.getInstance().addObserver(this); | ||
| 123 | +// if (mOptions != null) { | ||
| 124 | +// if (mOptions.getJumpCameraMode() == PickerConfig.CAMERA_MODE_PIC) { | ||
| 125 | +// isNeedAudio = false; | ||
| 126 | +// } else { | ||
| 127 | +// isNeedAudio = true; | ||
| 128 | +// } | ||
| 129 | +// } else { | ||
| 130 | +// getMvpView().showMessage("初始化异常"); | ||
| 131 | +// onBackPressed(); | ||
| 132 | +// } | ||
| 133 | +// | ||
| 134 | +// if (getMvpView() != null) getMvpView().initView(); | ||
| 135 | +// } else { | ||
| 136 | +// getMvpView().showMessage("网络故障"); | ||
| 137 | +// onBackPressed(); | ||
| 223 | // } | 138 | // } |
| 224 | - preBitmap = null; | ||
| 225 | - } | ||
| 226 | - | ||
| 227 | - } | ||
| 228 | - | ||
| 229 | - | ||
| 230 | - @Override | ||
| 231 | - public void update(Observable o, Object arg) { | ||
| 232 | - if (o instanceof MeidaResultObservable) { | ||
| 233 | - Media media = (Media) arg; | ||
| 234 | - if (isJumpCamera) { | ||
| 235 | - if (selectMedia == null) | ||
| 236 | - selectMedia = new ArrayList<Media>(); | ||
| 237 | - selectMedia.add(media); | ||
| 238 | - Intent intent = new Intent(); | ||
| 239 | - intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, selectMedia); | ||
| 240 | - setResult(resultCode, intent); | ||
| 241 | - finish(); | ||
| 242 | - } else { | ||
| 243 | - finish(); | ||
| 244 | - } | ||
| 245 | - } else if (o instanceof NotifyTrtcAnswerObservable) { | ||
| 246 | - AlertUtil.showDeftToast(this, "通话已接通,待通话结束再进入。"); | ||
| 247 | - finish(); | ||
| 248 | - } | ||
| 249 | - | ||
| 250 | - } | ||
| 251 | - | ||
| 252 | - | ||
| 253 | - @Override | ||
| 254 | - public void onBackPressed() { | ||
| 255 | - Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.pre_frame); | ||
| 256 | - if (currentFragment == null) { | ||
| 257 | - finish(); | ||
| 258 | - } else { | ||
| 259 | - if (currentFragment instanceof RecordPreviewFragment) { | ||
| 260 | - getSupportFragmentManager().popBackStack(); | ||
| 261 | - } else { | ||
| 262 | - finish(); | ||
| 263 | - } | ||
| 264 | - } | ||
| 265 | - | ||
| 266 | - } | ||
| 267 | - | ||
| 268 | - | ||
| 269 | -} | 139 | +// |
| 140 | +// }); | ||
| 141 | +// } | ||
| 142 | +// | ||
| 143 | +// @Override | ||
| 144 | +// protected void onSaveInstanceState(Bundle outState) { | ||
| 145 | +// if (mOptions != null) outState.putParcelable(PickerConfig.INTENT_KEY_OPTIONS, mOptions); | ||
| 146 | +// outState.putInt(PickerConfig.RESULT_CODE, resultCode); | ||
| 147 | +// outState.putBoolean(PickerConfig.WHERE_JUMP_CAMERA, isJumpCamera); | ||
| 148 | +// if (selectMedia != null) | ||
| 149 | +// outState.putParcelableArrayList(PickerConfig.WHERE_JUMP_CAMERA_SELECTS, selectMedia); | ||
| 150 | +// super.onSaveInstanceState(outState); | ||
| 151 | +// } | ||
| 152 | +// | ||
| 153 | +// public void showPreViewImg(Bitmap plbitMap) { | ||
| 154 | +// runOnUiThread(new Runnable() { | ||
| 155 | +// @Override | ||
| 156 | +// public void run() { | ||
| 157 | +// preBitmap = plbitMap; | ||
| 158 | +// getSupportFragmentManager().beginTransaction().add(R.id.pre_frame, RecordPreviewFragment.newInstance(0, "")).addToBackStack("").commitAllowingStateLoss(); | ||
| 159 | +// } | ||
| 160 | +// }); | ||
| 161 | +// | ||
| 162 | +// } | ||
| 163 | +// | ||
| 164 | +// public void showVideo(String path) { | ||
| 165 | +// runOnUiThread(new Runnable() { | ||
| 166 | +// @Override | ||
| 167 | +// public void run() { | ||
| 168 | +// getSupportFragmentManager().beginTransaction().replace(R.id.pre_frame, RecordPreviewFragment.newInstance(1, path)).addToBackStack("").commitAllowingStateLoss(); | ||
| 169 | +// } | ||
| 170 | +// }); | ||
| 171 | +// | ||
| 172 | +// } | ||
| 173 | +// | ||
| 174 | +// @Override | ||
| 175 | +// public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, | ||
| 176 | +// @NonNull int[] grantResults) { | ||
| 177 | +// super.onRequestPermissionsResult(requestCode, permissions, grantResults); | ||
| 178 | +// if (requestCode == PERMISISSION_CODE_ASK) { | ||
| 179 | +// | ||
| 180 | +// boolean[] hasPermissions = getPresenter().onRequestPermissionsResult(this, requestCode, permissions, grantResults); | ||
| 181 | +// if (hasPermissions[0]) { | ||
| 182 | +// if (getMvpView() != null) { //权限正常 | ||
| 183 | +// getMvpView().checkPermisssion(); | ||
| 184 | +// } | ||
| 185 | +// } else if (hasPermissions[1]) { //权限永久拒绝的处理 | ||
| 186 | +// getMvpView().showPermissionPerpetual(requestCode); | ||
| 187 | +// } else { //权限没有全部同意 | ||
| 188 | +// if (isNeedAudio) { | ||
| 189 | +// getMvpView().showPermission(permissionsRecord, PERMISISSION_CODE_ASK); | ||
| 190 | +// } else { | ||
| 191 | +// getMvpView().showPermission(permissionsRecordNoAudio, PERMISISSION_CODE_ASK); | ||
| 192 | +// } | ||
| 193 | +// | ||
| 194 | +// } | ||
| 195 | +// } | ||
| 196 | +// | ||
| 197 | +// } | ||
| 198 | +// | ||
| 199 | +// @Override | ||
| 200 | +// protected void onResume() { | ||
| 201 | +// super.onResume(); | ||
| 202 | +// if (isNeverAsk) { | ||
| 203 | +// isNeverAsk = false; | ||
| 204 | +// //永久拒绝后,返回页面时检测权限并初始化 | ||
| 205 | +// getMvpView().checkPermisssion(); | ||
| 206 | +// } | ||
| 207 | +// } | ||
| 208 | +// | ||
| 209 | +// @Override | ||
| 210 | +// protected void onPause() { | ||
| 211 | +// super.onPause(); | ||
| 212 | +// } | ||
| 213 | +// | ||
| 214 | +// @Override | ||
| 215 | +// protected void onDestroy() { | ||
| 216 | +// super.onDestroy(); | ||
| 217 | +// MeidaResultObservable.getInstance().deleteObserver(this); | ||
| 218 | +// NotifyTrtcAnswerObservable.newInstance().deleteObserver(this); | ||
| 219 | +// if (preBitmap != null) { | ||
| 220 | +// // glide 加载维护了 bitmap 回收 | ||
| 221 | +//// if (!preBitmap.isRecycled()){ | ||
| 222 | +//// preBitmap.recycle(); | ||
| 223 | +//// } | ||
| 224 | +// preBitmap = null; | ||
| 225 | +// } | ||
| 226 | +// | ||
| 227 | +// } | ||
| 228 | +// | ||
| 229 | +// | ||
| 230 | +// @Override | ||
| 231 | +// public void update(Observable o, Object arg) { | ||
| 232 | +// if (o instanceof MeidaResultObservable) { | ||
| 233 | +// Media media = (Media) arg; | ||
| 234 | +// if (isJumpCamera) { | ||
| 235 | +// if (selectMedia == null) | ||
| 236 | +// selectMedia = new ArrayList<Media>(); | ||
| 237 | +// selectMedia.add(media); | ||
| 238 | +// Intent intent = new Intent(); | ||
| 239 | +// intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, selectMedia); | ||
| 240 | +// setResult(resultCode, intent); | ||
| 241 | +// finish(); | ||
| 242 | +// } else { | ||
| 243 | +// finish(); | ||
| 244 | +// } | ||
| 245 | +// } else if (o instanceof NotifyTrtcAnswerObservable) { | ||
| 246 | +// AlertUtil.showDeftToast(this, "通话已接通,待通话结束再进入。"); | ||
| 247 | +// finish(); | ||
| 248 | +// } | ||
| 249 | +// | ||
| 250 | +// } | ||
| 251 | +// | ||
| 252 | +// | ||
| 253 | +// @Override | ||
| 254 | +// public void onBackPressed() { | ||
| 255 | +// Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.pre_frame); | ||
| 256 | +// if (currentFragment == null) { | ||
| 257 | +// finish(); | ||
| 258 | +// } else { | ||
| 259 | +// if (currentFragment instanceof RecordPreviewFragment) { | ||
| 260 | +// getSupportFragmentManager().popBackStack(); | ||
| 261 | +// } else { | ||
| 262 | +// finish(); | ||
| 263 | +// } | ||
| 264 | +// } | ||
| 265 | +// | ||
| 266 | +// } | ||
| 267 | +// | ||
| 268 | +// | ||
| 269 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/adapter/RecyclerviewAdapter.java
0 → 100644
| 1 | +package com.cnlive.media.ui.adapter; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.view.LayoutInflater; | ||
| 5 | +import android.view.View; | ||
| 6 | +import android.view.ViewGroup; | ||
| 7 | +import android.widget.ImageView; | ||
| 8 | + | ||
| 9 | +import androidx.annotation.NonNull; | ||
| 10 | +import androidx.recyclerview.widget.RecyclerView; | ||
| 11 | + | ||
| 12 | +import com.bumptech.glide.Glide; | ||
| 13 | +import com.cnlive.media.R; | ||
| 14 | +import com.cnlive.media.model.CircleData; | ||
| 15 | + | ||
| 16 | +import java.util.List; | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * Author by Yuansiwen.com, Date on 2018/12/25. | ||
| 20 | + * PS: Not easy to write code, please indicate. | ||
| 21 | + */ | ||
| 22 | +public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.ViewHolder> implements View.OnClickListener { | ||
| 23 | + | ||
| 24 | + private Context context; | ||
| 25 | + private List<CircleData.ReleaseVideoTypeListBean> data; | ||
| 26 | + private MyClickListener mListener; | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + public void onClick(View v) { | ||
| 30 | + mListener.clickListener(v); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public interface MyClickListener{ | ||
| 34 | + public void clickListener(View v); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public RecyclerviewAdapter(Context context, List<CircleData.ReleaseVideoTypeListBean> data, MyClickListener listener){ | ||
| 38 | + this.context = context; | ||
| 39 | + this.data = data; | ||
| 40 | + mListener = listener; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | ||
| 45 | + View view = LayoutInflater.from(context).inflate(R.layout.list_item_circl,parent,false); | ||
| 46 | + return new ViewHolder(view); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @Override | ||
| 50 | + public void onBindViewHolder(@NonNull ViewHolder holder, final int position) { | ||
| 51 | + Glide.with(context).load(data.get(position).getPic()).into(holder.userimage); | ||
| 52 | + holder.userimage.setOnClickListener(this); | ||
| 53 | + holder.userimage.setTag(position); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + @Override | ||
| 57 | + public int getItemCount() { | ||
| 58 | + return data.size(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + public class ViewHolder extends RecyclerView.ViewHolder{ | ||
| 62 | + private ImageView userimage; | ||
| 63 | + | ||
| 64 | + public ViewHolder(View itemView) { | ||
| 65 | + super(itemView); | ||
| 66 | + userimage = itemView.findViewById(R.id.userImage); | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | +} |
lib_media/src/main/java/com/cnlive/media/ui/fragment/RecordFragment.java
| 1 | -package com.cnlive.media.ui.fragment; | ||
| 2 | - | ||
| 3 | -import android.Manifest; | ||
| 4 | -import android.content.Context; | ||
| 5 | -import android.content.pm.PackageManager; | ||
| 6 | -import android.graphics.Bitmap; | ||
| 7 | -import android.media.AudioManager; | ||
| 8 | -import android.os.Build; | ||
| 9 | -import android.os.Bundle; | ||
| 10 | -import android.text.TextUtils; | ||
| 11 | -import android.util.Log; | ||
| 12 | -import android.view.View; | ||
| 13 | - | ||
| 14 | -import androidx.activity.OnBackPressedCallback; | ||
| 15 | -import androidx.annotation.Nullable; | ||
| 16 | -import androidx.core.app.ActivityCompat; | ||
| 17 | - | ||
| 18 | -import com.cnlive.libs.base.frame.fragment.MvpBindingFragment; | ||
| 19 | -import com.cnlive.libs.base.util.DoublePressed; | ||
| 20 | -import com.cnlive.libs.util.Config; | ||
| 21 | -import com.cnlive.media.R; | ||
| 22 | -import com.cnlive.media.databinding.FragmentRecordBinding; | ||
| 23 | -import com.cnlive.media.frame.presenter.RecordFragmentPresenter; | ||
| 24 | -import com.cnlive.media.frame.view.RecordFragmentView; | ||
| 25 | -import com.cnlive.media.ui.widget.record.observable.RecordCameraViewObservable; | ||
| 26 | -import com.qiniu.pili.droid.shortvideo.PLCaptureFrameListener; | ||
| 27 | -import com.qiniu.pili.droid.shortvideo.PLShortVideoRecorder; | ||
| 28 | -import com.qiniu.pili.droid.shortvideo.PLVideoFrame; | ||
| 29 | -import com.qiniu.pili.droid.shortvideo.PLVideoSaveListener; | ||
| 30 | - | ||
| 31 | -import java.util.Observable; | ||
| 32 | -import java.util.Observer; | ||
| 33 | - | ||
| 34 | -/** | ||
| 35 | - * 作 者 : wkq | ||
| 36 | - * <p> | ||
| 37 | - * 时 间 : 2020/10/29 10:04 | ||
| 38 | - * <p> | ||
| 39 | - * 名 字 : RecordFragment | ||
| 40 | - * <p> | ||
| 41 | - * 简 介 : 录制操作页面 | ||
| 42 | - */ | ||
| 43 | -public class RecordFragment extends MvpBindingFragment<RecordFragmentView, RecordFragmentPresenter, Object, FragmentRecordBinding> implements Observer { | ||
| 44 | - | ||
| 45 | - | ||
| 46 | - public static RecordFragment newInstance() { | ||
| 47 | - | ||
| 48 | - RecordFragment fragment = new RecordFragment(); | ||
| 49 | - Bundle bundle = new Bundle(); | ||
| 50 | - fragment.setArguments(bundle); | ||
| 51 | - return fragment; | ||
| 52 | - | ||
| 53 | - } | ||
| 54 | - | ||
| 55 | - // 处理 返回事件的监听 | ||
| 56 | - public OnBackPressedCallback callback = new OnBackPressedCallback(true) { | ||
| 57 | - @Override | ||
| 58 | - public void handleOnBackPressed() { | ||
| 59 | - callback.setEnabled(false); | ||
| 60 | - requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 61 | - } | ||
| 62 | - }; | ||
| 63 | - | ||
| 64 | - public PLShortVideoRecorder plShortVideoRecorder; | ||
| 65 | - public boolean isFlash; | ||
| 66 | - //准备就绪 | ||
| 67 | - public boolean isReady; | ||
| 68 | - //录制中 | ||
| 69 | - public boolean isRecordIng; | ||
| 70 | - | ||
| 71 | - public boolean permission = false; | ||
| 72 | - | ||
| 73 | - @Override | ||
| 74 | - protected int getLayoutId() { | ||
| 75 | - return R.layout.fragment_record; | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - private boolean checkPermission() { | ||
| 79 | - if (getActivity() == null) return false; | ||
| 80 | - | ||
| 81 | - boolean hasPermisson = true; | ||
| 82 | - | ||
| 83 | - for (String permisson : Build.VERSION.SDK_INT >= 33 ? | ||
| 84 | - new String[]{ | ||
| 85 | - Manifest.permission.CAMERA, | ||
| 86 | - Manifest.permission.RECORD_AUDIO, | ||
| 87 | - "android.permission.READ_MEDIA_IMAGES", | ||
| 88 | - "android.permission.READ_MEDIA_AUDIO", | ||
| 89 | - "android.permission.READ_MEDIA_VIDEO"} : | ||
| 90 | - new String[]{ | ||
| 91 | - Manifest.permission.CAMERA, | ||
| 92 | - Manifest.permission.RECORD_AUDIO, | ||
| 93 | - Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 94 | - Manifest.permission.WRITE_EXTERNAL_STORAGE}) { | ||
| 95 | - if (ActivityCompat.checkSelfPermission(getActivity(), permisson) != PackageManager.PERMISSION_GRANTED) { | ||
| 96 | - hasPermisson = false; | ||
| 97 | - break; | ||
| 98 | - } | ||
| 99 | - } | ||
| 100 | - return hasPermisson; | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - @Override | ||
| 104 | - public void onCreate(Bundle savedInstanceState) { | ||
| 105 | - super.onCreate(savedInstanceState); | ||
| 106 | - permission = checkPermission(); | ||
| 107 | - } | ||
| 108 | - | ||
| 109 | - @Override | ||
| 110 | - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | ||
| 111 | - super.onViewCreated(view, savedInstanceState); | ||
| 112 | - if (!permission) return; | ||
| 113 | - RecordCameraViewObservable.newInstance().addObserver(this); | ||
| 114 | - if (getMvpView() != null) getMvpView().initView(); | ||
| 115 | - requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - @Override | ||
| 119 | - public void onSaveInstanceState(Bundle outState) { | ||
| 120 | - super.onSaveInstanceState(outState); | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - @Override | ||
| 124 | - public void onResume() { | ||
| 125 | - super.onResume(); | ||
| 126 | - if (!permission) return; | ||
| 127 | - | ||
| 128 | - if (isFlash && getMvpView() != null) getMvpView().processFlash(isFlash); | ||
| 129 | - if (plShortVideoRecorder != null) { | ||
| 130 | - plShortVideoRecorder.resume(); | ||
| 131 | - plShortVideoRecorder.deleteLastSection(); | ||
| 132 | - } | ||
| 133 | - } | ||
| 134 | - | ||
| 135 | - @Override | ||
| 136 | - public void onPause() { | ||
| 137 | - super.onPause(); | ||
| 138 | - if (!permission) return; | ||
| 139 | - | ||
| 140 | - isRecordIng = false; | ||
| 141 | - if (plShortVideoRecorder != null) { | ||
| 142 | - binding.rcControl.resetRecord(); | ||
| 143 | - plShortVideoRecorder.pause(); | ||
| 144 | - isFlash = false; | ||
| 145 | - getMvpView().processFlash(isFlash); | ||
| 146 | - } | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | - @Override | ||
| 150 | - public void onDestroy() { | ||
| 151 | - super.onDestroy(); | ||
| 152 | - if (!permission) return; | ||
| 153 | - | ||
| 154 | - RecordCameraViewObservable.newInstance().deleteObserver(this); | ||
| 155 | - if (plShortVideoRecorder != null) { | ||
| 156 | - plShortVideoRecorder.destroy(); | ||
| 157 | - } | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - | ||
| 161 | - @Override | ||
| 162 | - public void update(Observable o, Object arg) { | ||
| 163 | - if (o instanceof RecordCameraViewObservable) { | ||
| 164 | - int state = (int) arg; | ||
| 165 | - if (plShortVideoRecorder == null || getMvpView() == null) return; | ||
| 166 | - //闪光灯 | ||
| 167 | - if (state == RecordCameraViewObservable.CLICK_FLASH) { | ||
| 168 | - if (isRecordIng) { | ||
| 169 | - getMvpView().showMesage("录制中..."); | ||
| 170 | - } else { | ||
| 171 | - if (plShortVideoRecorder.isFlashSupport()) { | ||
| 172 | - isFlash = (!isFlash); | ||
| 173 | - plShortVideoRecorder.setFlashEnabled(isFlash); | ||
| 174 | - getMvpView().processFlash(isFlash); | ||
| 175 | - } else { | ||
| 176 | - isFlash = false; | ||
| 177 | - getMvpView().processFlash(false); | ||
| 178 | - getMvpView().showMesage("暂不支持闪光灯"); | ||
| 179 | - } | ||
| 180 | - } | ||
| 181 | - | ||
| 182 | - } else if (state == RecordCameraViewObservable.CLICK_SWITCH) { | ||
| 183 | - if (isRecordIng) { | ||
| 184 | - //设置前后摄像头 | ||
| 185 | - getMvpView().showMesage("录制中..."); | ||
| 186 | - | ||
| 187 | - } else { | ||
| 188 | - if (DoublePressed.onDoublePressed()) return; | ||
| 189 | - plShortVideoRecorder.switchCamera(); | ||
| 190 | - getMvpView().processFlash(false); | ||
| 191 | - } | ||
| 192 | - } else if (state == RecordCameraViewObservable.CLICK_FINISH) { | ||
| 193 | - requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 194 | - } else if (state == RecordCameraViewObservable.CLICK_TAKE) { | ||
| 195 | - //拍照 | ||
| 196 | - if (isReady) { | ||
| 197 | - plShortVideoRecorder.captureFrame(new PLCaptureFrameListener() { | ||
| 198 | - @Override | ||
| 199 | - public void onFrameCaptured(PLVideoFrame plVideoFrame) { | ||
| 200 | - Bitmap plbitMap = plVideoFrame.toBitmap(); | ||
| 201 | - | ||
| 202 | - if (plbitMap != null && plbitMap.getByteCount() > 0) { | ||
| 203 | - getMvpView().getActivity().showPreViewImg(plbitMap); | ||
| 204 | - } else { | ||
| 205 | - getMvpView().showMesage("图片拍摄异常"); | ||
| 206 | - } | ||
| 207 | - } | ||
| 208 | - }); | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - | ||
| 212 | - } else if (state == RecordCameraViewObservable.CLICK_RECODE_START) { | ||
| 213 | - //视频录制开始 | ||
| 214 | - if (isReady) { | ||
| 215 | - requestAudioFocus(); | ||
| 216 | - isRecordIng = true; | ||
| 217 | - plShortVideoRecorder.deleteAllSections(); | ||
| 218 | - plShortVideoRecorder.beginSection(); | ||
| 219 | - } else { | ||
| 220 | - isRecordIng = false; | ||
| 221 | - getMvpView().showMesage("相机还未准备完成,请稍后"); | ||
| 222 | - } | ||
| 223 | - } else if (state == RecordCameraViewObservable.CLICK_RECODE_FINISH) { | ||
| 224 | - //录制完成 | ||
| 225 | - abandonAudioFocus(); | ||
| 226 | - plShortVideoRecorder.endSection(); | ||
| 227 | - plShortVideoRecorder.concatSections(new PLVideoSaveListener() { | ||
| 228 | - //视频保存完成 | ||
| 229 | - @Override | ||
| 230 | - public void onSaveVideoSuccess(String s) { | ||
| 231 | - if (!TextUtils.isEmpty(s)) { | ||
| 232 | - isRecordIng = false; | ||
| 233 | - getMvpView().getActivity().showVideo(s); | ||
| 234 | - } else { | ||
| 235 | - getMvpView().showMesage("视频录制异常"); | ||
| 236 | - } | ||
| 237 | - } | ||
| 238 | - | ||
| 239 | - @Override | ||
| 240 | - public void onSaveVideoFailed(int i) { | ||
| 241 | - isRecordIng = false; | ||
| 242 | - if (getMvpView() != null) getMvpView().showMesage("视频录制失败"); | ||
| 243 | - } | ||
| 244 | - | ||
| 245 | - @Override | ||
| 246 | - public void onSaveVideoCanceled() { | ||
| 247 | - | ||
| 248 | - } | ||
| 249 | - | ||
| 250 | - @Override | ||
| 251 | - public void onProgressUpdate(float v) { | ||
| 252 | - | ||
| 253 | - } | ||
| 254 | - }); | ||
| 255 | - | ||
| 256 | - } else if (state == RecordCameraViewObservable.CLICK_RECODE_ERR) { | ||
| 257 | - isRecordIng = false; | ||
| 258 | - plShortVideoRecorder.endSection(); | ||
| 259 | - } | ||
| 260 | - } | ||
| 261 | - } | ||
| 262 | - | ||
| 263 | - private boolean mAudioFocus; | ||
| 264 | - | ||
| 265 | - /** | ||
| 266 | - * 录音时获取音频焦点(关闭第三方音乐) | ||
| 267 | - */ | ||
| 268 | - private void requestAudioFocus() { | ||
| 269 | - if (mAudioFocus) return; | ||
| 270 | - AudioManager audioManager = (AudioManager) Config.getContext().getSystemService(Context.AUDIO_SERVICE); | ||
| 271 | - if (audioManager == null) return; | ||
| 272 | - | ||
| 273 | - int result = audioManager.requestAudioFocus(null, | ||
| 274 | - AudioManager.STREAM_MUSIC, // Use the music stream. | ||
| 275 | - AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); | ||
| 276 | - if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { | ||
| 277 | - mAudioFocus = true; | ||
| 278 | - } else { | ||
| 279 | - Log.e("media picker record", "AudioManager request Audio Focus result = " + result); | ||
| 280 | - } | ||
| 281 | - } | ||
| 282 | - | ||
| 283 | - /** | ||
| 284 | - * 录音结束恢复音频焦点 | ||
| 285 | - */ | ||
| 286 | - private void abandonAudioFocus() { | ||
| 287 | - if (!mAudioFocus) return; | ||
| 288 | - AudioManager audioManager = (AudioManager) Config.getContext().getSystemService(Context.AUDIO_SERVICE); | ||
| 289 | - if (audioManager == null) return; | ||
| 290 | - audioManager.abandonAudioFocus(null); | ||
| 291 | - mAudioFocus = false; | ||
| 292 | - } | ||
| 293 | -} | 1 | +//package com.cnlive.media.ui.fragment; |
| 2 | +// | ||
| 3 | +//import android.Manifest; | ||
| 4 | +//import android.content.Context; | ||
| 5 | +//import android.content.pm.PackageManager; | ||
| 6 | +//import android.graphics.Bitmap; | ||
| 7 | +//import android.media.AudioManager; | ||
| 8 | +//import android.os.Build; | ||
| 9 | +//import android.os.Bundle; | ||
| 10 | +//import android.text.TextUtils; | ||
| 11 | +//import android.util.Log; | ||
| 12 | +//import android.view.View; | ||
| 13 | +// | ||
| 14 | +//import androidx.activity.OnBackPressedCallback; | ||
| 15 | +//import androidx.annotation.Nullable; | ||
| 16 | +//import androidx.core.app.ActivityCompat; | ||
| 17 | +// | ||
| 18 | +//import com.cnlive.libs.base.frame.fragment.MvpBindingFragment; | ||
| 19 | +//import com.cnlive.libs.base.util.DoublePressed; | ||
| 20 | +//import com.cnlive.libs.util.Config; | ||
| 21 | +//import com.cnlive.media.R; | ||
| 22 | +//import com.cnlive.media.databinding.FragmentRecordBinding; | ||
| 23 | +//import com.cnlive.media.frame.presenter.RecordFragmentPresenter; | ||
| 24 | +//import com.cnlive.media.frame.view.RecordFragmentView; | ||
| 25 | +//import com.cnlive.media.ui.widget.record.observable.RecordCameraViewObservable; | ||
| 26 | +//import com.qiniu.pili.droid.shortvideo.PLCaptureFrameListener; | ||
| 27 | +//import com.qiniu.pili.droid.shortvideo.PLShortVideoRecorder; | ||
| 28 | +//import com.qiniu.pili.droid.shortvideo.PLVideoFrame; | ||
| 29 | +//import com.qiniu.pili.droid.shortvideo.PLVideoSaveListener; | ||
| 30 | +// | ||
| 31 | +//import java.util.Observable; | ||
| 32 | +//import java.util.Observer; | ||
| 33 | +// | ||
| 34 | +///** | ||
| 35 | +// * 作 者 : wkq | ||
| 36 | +// * <p> | ||
| 37 | +// * 时 间 : 2020/10/29 10:04 | ||
| 38 | +// * <p> | ||
| 39 | +// * 名 字 : RecordFragment | ||
| 40 | +// * <p> | ||
| 41 | +// * 简 介 : 录制操作页面 | ||
| 42 | +// */ | ||
| 43 | +//public class RecordFragment extends MvpBindingFragment<RecordFragmentView, RecordFragmentPresenter, Object, FragmentRecordBinding> implements Observer { | ||
| 44 | +// | ||
| 45 | +// | ||
| 46 | +// public static RecordFragment newInstance() { | ||
| 47 | +// | ||
| 48 | +// RecordFragment fragment = new RecordFragment(); | ||
| 49 | +// Bundle bundle = new Bundle(); | ||
| 50 | +// fragment.setArguments(bundle); | ||
| 51 | +// return fragment; | ||
| 52 | +// | ||
| 53 | +// } | ||
| 54 | +// | ||
| 55 | +// // 处理 返回事件的监听 | ||
| 56 | +// public OnBackPressedCallback callback = new OnBackPressedCallback(true) { | ||
| 57 | +// @Override | ||
| 58 | +// public void handleOnBackPressed() { | ||
| 59 | +// callback.setEnabled(false); | ||
| 60 | +// requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 61 | +// } | ||
| 62 | +// }; | ||
| 63 | +// | ||
| 64 | +// public PLShortVideoRecorder plShortVideoRecorder; | ||
| 65 | +// public boolean isFlash; | ||
| 66 | +// //准备就绪 | ||
| 67 | +// public boolean isReady; | ||
| 68 | +// //录制中 | ||
| 69 | +// public boolean isRecordIng; | ||
| 70 | +// | ||
| 71 | +// public boolean permission = false; | ||
| 72 | +// | ||
| 73 | +// @Override | ||
| 74 | +// protected int getLayoutId() { | ||
| 75 | +// return R.layout.fragment_record; | ||
| 76 | +// } | ||
| 77 | +// | ||
| 78 | +// private boolean checkPermission() { | ||
| 79 | +// if (getActivity() == null) return false; | ||
| 80 | +// | ||
| 81 | +// boolean hasPermisson = true; | ||
| 82 | +// | ||
| 83 | +// for (String permisson : Build.VERSION.SDK_INT >= 33 ? | ||
| 84 | +// new String[]{ | ||
| 85 | +// Manifest.permission.CAMERA, | ||
| 86 | +// Manifest.permission.RECORD_AUDIO, | ||
| 87 | +// "android.permission.READ_MEDIA_IMAGES", | ||
| 88 | +// "android.permission.READ_MEDIA_AUDIO", | ||
| 89 | +// "android.permission.READ_MEDIA_VIDEO"} : | ||
| 90 | +// new String[]{ | ||
| 91 | +// Manifest.permission.CAMERA, | ||
| 92 | +// Manifest.permission.RECORD_AUDIO, | ||
| 93 | +// Manifest.permission.READ_EXTERNAL_STORAGE, | ||
| 94 | +// Manifest.permission.WRITE_EXTERNAL_STORAGE}) { | ||
| 95 | +// if (ActivityCompat.checkSelfPermission(getActivity(), permisson) != PackageManager.PERMISSION_GRANTED) { | ||
| 96 | +// hasPermisson = false; | ||
| 97 | +// break; | ||
| 98 | +// } | ||
| 99 | +// } | ||
| 100 | +// return hasPermisson; | ||
| 101 | +// } | ||
| 102 | +// | ||
| 103 | +// @Override | ||
| 104 | +// public void onCreate(Bundle savedInstanceState) { | ||
| 105 | +// super.onCreate(savedInstanceState); | ||
| 106 | +// permission = checkPermission(); | ||
| 107 | +// } | ||
| 108 | +// | ||
| 109 | +// @Override | ||
| 110 | +// public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | ||
| 111 | +// super.onViewCreated(view, savedInstanceState); | ||
| 112 | +// if (!permission) return; | ||
| 113 | +// RecordCameraViewObservable.newInstance().addObserver(this); | ||
| 114 | +// if (getMvpView() != null) getMvpView().initView(); | ||
| 115 | +// requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); | ||
| 116 | +// } | ||
| 117 | +// | ||
| 118 | +// @Override | ||
| 119 | +// public void onSaveInstanceState(Bundle outState) { | ||
| 120 | +// super.onSaveInstanceState(outState); | ||
| 121 | +// } | ||
| 122 | +// | ||
| 123 | +// @Override | ||
| 124 | +// public void onResume() { | ||
| 125 | +// super.onResume(); | ||
| 126 | +// if (!permission) return; | ||
| 127 | +// | ||
| 128 | +// if (isFlash && getMvpView() != null) getMvpView().processFlash(isFlash); | ||
| 129 | +// if (plShortVideoRecorder != null) { | ||
| 130 | +// plShortVideoRecorder.resume(); | ||
| 131 | +// plShortVideoRecorder.deleteLastSection(); | ||
| 132 | +// } | ||
| 133 | +// } | ||
| 134 | +// | ||
| 135 | +// @Override | ||
| 136 | +// public void onPause() { | ||
| 137 | +// super.onPause(); | ||
| 138 | +// if (!permission) return; | ||
| 139 | +// | ||
| 140 | +// isRecordIng = false; | ||
| 141 | +// if (plShortVideoRecorder != null) { | ||
| 142 | +// binding.rcControl.resetRecord(); | ||
| 143 | +// plShortVideoRecorder.pause(); | ||
| 144 | +// isFlash = false; | ||
| 145 | +// getMvpView().processFlash(isFlash); | ||
| 146 | +// } | ||
| 147 | +// } | ||
| 148 | +// | ||
| 149 | +// @Override | ||
| 150 | +// public void onDestroy() { | ||
| 151 | +// super.onDestroy(); | ||
| 152 | +// if (!permission) return; | ||
| 153 | +// | ||
| 154 | +// RecordCameraViewObservable.newInstance().deleteObserver(this); | ||
| 155 | +// if (plShortVideoRecorder != null) { | ||
| 156 | +// plShortVideoRecorder.destroy(); | ||
| 157 | +// } | ||
| 158 | +// } | ||
| 159 | +// | ||
| 160 | +// | ||
| 161 | +// @Override | ||
| 162 | +// public void update(Observable o, Object arg) { | ||
| 163 | +// if (o instanceof RecordCameraViewObservable) { | ||
| 164 | +// int state = (int) arg; | ||
| 165 | +// if (plShortVideoRecorder == null || getMvpView() == null) return; | ||
| 166 | +// //闪光灯 | ||
| 167 | +// if (state == RecordCameraViewObservable.CLICK_FLASH) { | ||
| 168 | +// if (isRecordIng) { | ||
| 169 | +// getMvpView().showMesage("录制中..."); | ||
| 170 | +// } else { | ||
| 171 | +// if (plShortVideoRecorder.isFlashSupport()) { | ||
| 172 | +// isFlash = (!isFlash); | ||
| 173 | +// plShortVideoRecorder.setFlashEnabled(isFlash); | ||
| 174 | +// getMvpView().processFlash(isFlash); | ||
| 175 | +// } else { | ||
| 176 | +// isFlash = false; | ||
| 177 | +// getMvpView().processFlash(false); | ||
| 178 | +// getMvpView().showMesage("暂不支持闪光灯"); | ||
| 179 | +// } | ||
| 180 | +// } | ||
| 181 | +// | ||
| 182 | +// } else if (state == RecordCameraViewObservable.CLICK_SWITCH) { | ||
| 183 | +// if (isRecordIng) { | ||
| 184 | +// //设置前后摄像头 | ||
| 185 | +// getMvpView().showMesage("录制中..."); | ||
| 186 | +// | ||
| 187 | +// } else { | ||
| 188 | +// if (DoublePressed.onDoublePressed()) return; | ||
| 189 | +// plShortVideoRecorder.switchCamera(); | ||
| 190 | +// getMvpView().processFlash(false); | ||
| 191 | +// } | ||
| 192 | +// } else if (state == RecordCameraViewObservable.CLICK_FINISH) { | ||
| 193 | +// requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 194 | +// } else if (state == RecordCameraViewObservable.CLICK_TAKE) { | ||
| 195 | +// //拍照 | ||
| 196 | +// if (isReady) { | ||
| 197 | +// plShortVideoRecorder.captureFrame(new PLCaptureFrameListener() { | ||
| 198 | +// @Override | ||
| 199 | +// public void onFrameCaptured(PLVideoFrame plVideoFrame) { | ||
| 200 | +// Bitmap plbitMap = plVideoFrame.toBitmap(); | ||
| 201 | +// | ||
| 202 | +// if (plbitMap != null && plbitMap.getByteCount() > 0) { | ||
| 203 | +// getMvpView().getActivity().showPreViewImg(plbitMap); | ||
| 204 | +// } else { | ||
| 205 | +// getMvpView().showMesage("图片拍摄异常"); | ||
| 206 | +// } | ||
| 207 | +// } | ||
| 208 | +// }); | ||
| 209 | +// } | ||
| 210 | +// | ||
| 211 | +// | ||
| 212 | +// } else if (state == RecordCameraViewObservable.CLICK_RECODE_START) { | ||
| 213 | +// //视频录制开始 | ||
| 214 | +// if (isReady) { | ||
| 215 | +// requestAudioFocus(); | ||
| 216 | +// isRecordIng = true; | ||
| 217 | +// plShortVideoRecorder.deleteAllSections(); | ||
| 218 | +// plShortVideoRecorder.beginSection(); | ||
| 219 | +// } else { | ||
| 220 | +// isRecordIng = false; | ||
| 221 | +// getMvpView().showMesage("相机还未准备完成,请稍后"); | ||
| 222 | +// } | ||
| 223 | +// } else if (state == RecordCameraViewObservable.CLICK_RECODE_FINISH) { | ||
| 224 | +// //录制完成 | ||
| 225 | +// abandonAudioFocus(); | ||
| 226 | +// plShortVideoRecorder.endSection(); | ||
| 227 | +// plShortVideoRecorder.concatSections(new PLVideoSaveListener() { | ||
| 228 | +// //视频保存完成 | ||
| 229 | +// @Override | ||
| 230 | +// public void onSaveVideoSuccess(String s) { | ||
| 231 | +// if (!TextUtils.isEmpty(s)) { | ||
| 232 | +// isRecordIng = false; | ||
| 233 | +// getMvpView().getActivity().showVideo(s); | ||
| 234 | +// } else { | ||
| 235 | +// getMvpView().showMesage("视频录制异常"); | ||
| 236 | +// } | ||
| 237 | +// } | ||
| 238 | +// | ||
| 239 | +// @Override | ||
| 240 | +// public void onSaveVideoFailed(int i) { | ||
| 241 | +// isRecordIng = false; | ||
| 242 | +// if (getMvpView() != null) getMvpView().showMesage("视频录制失败"); | ||
| 243 | +// } | ||
| 244 | +// | ||
| 245 | +// @Override | ||
| 246 | +// public void onSaveVideoCanceled() { | ||
| 247 | +// | ||
| 248 | +// } | ||
| 249 | +// | ||
| 250 | +// @Override | ||
| 251 | +// public void onProgressUpdate(float v) { | ||
| 252 | +// | ||
| 253 | +// } | ||
| 254 | +// }); | ||
| 255 | +// | ||
| 256 | +// } else if (state == RecordCameraViewObservable.CLICK_RECODE_ERR) { | ||
| 257 | +// isRecordIng = false; | ||
| 258 | +// plShortVideoRecorder.endSection(); | ||
| 259 | +// } | ||
| 260 | +// } | ||
| 261 | +// } | ||
| 262 | +// | ||
| 263 | +// private boolean mAudioFocus; | ||
| 264 | +// | ||
| 265 | +// /** | ||
| 266 | +// * 录音时获取音频焦点(关闭第三方音乐) | ||
| 267 | +// */ | ||
| 268 | +// private void requestAudioFocus() { | ||
| 269 | +// if (mAudioFocus || getActivity() == null) return; | ||
| 270 | +// AudioManager audioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); | ||
| 271 | +// if (audioManager == null) return; | ||
| 272 | +// | ||
| 273 | +// int result = audioManager.requestAudioFocus(null, | ||
| 274 | +// AudioManager.STREAM_MUSIC, // Use the music stream. | ||
| 275 | +// AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); | ||
| 276 | +// if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { | ||
| 277 | +// mAudioFocus = true; | ||
| 278 | +// } else { | ||
| 279 | +// Log.e("media picker record", "AudioManager request Audio Focus result = " + result); | ||
| 280 | +// } | ||
| 281 | +// } | ||
| 282 | +// | ||
| 283 | +// /** | ||
| 284 | +// * 录音结束恢复音频焦点 | ||
| 285 | +// */ | ||
| 286 | +// private void abandonAudioFocus() { | ||
| 287 | +// if (!mAudioFocus) return; | ||
| 288 | +// AudioManager audioManager = (AudioManager) Config.getContext().getSystemService(Context.AUDIO_SERVICE); | ||
| 289 | +// if (audioManager == null) return; | ||
| 290 | +// audioManager.abandonAudioFocus(null); | ||
| 291 | +// mAudioFocus = false; | ||
| 292 | +// } | ||
| 293 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/fragment/RecordPreviewFragment.java
| 1 | -package com.cnlive.media.ui.fragment; | ||
| 2 | - | ||
| 3 | -import android.content.ContentValues; | ||
| 4 | -import android.content.Context; | ||
| 5 | -import android.content.Intent; | ||
| 6 | -import android.net.Uri; | ||
| 7 | -import android.os.Bundle; | ||
| 8 | -import android.provider.MediaStore; | ||
| 9 | -import android.util.Log; | ||
| 10 | -import android.view.View; | ||
| 11 | - | ||
| 12 | -import androidx.activity.OnBackPressedCallback; | ||
| 13 | -import androidx.annotation.Nullable; | ||
| 14 | -import androidx.core.content.FileProvider; | ||
| 15 | - | ||
| 16 | -import com.cnlive.libs.base.frame.fragment.MvpBindingFragment; | ||
| 17 | -import com.cnlive.libs.base.util.AlertUtil; | ||
| 18 | -import com.cnlive.libs.base.util.DoublePressed; | ||
| 19 | -import com.cnlive.media.R; | ||
| 20 | -import com.cnlive.media.databinding.FragmentRecordPreviewBinding; | ||
| 21 | -import com.cnlive.media.frame.presenter.RecordPreviewPresenter; | ||
| 22 | -import com.cnlive.media.frame.view.RecordPreviewView; | ||
| 23 | -import com.cnlive.media.ui.activity.RecordActivity; | ||
| 24 | -import com.cnlive.media.utils.AndroidQUtil; | ||
| 25 | - | ||
| 26 | -import java.io.File; | ||
| 27 | - | ||
| 28 | -/** | ||
| 29 | - * 作 者 : wkq | ||
| 30 | - * <p> | ||
| 31 | - * 时 间 : 2020/9/28 9:34 | ||
| 32 | - * <p> | ||
| 33 | - * 名 字 : RecordPreviewFragment | ||
| 34 | - * <p> | ||
| 35 | - * 简 介 : | ||
| 36 | - */ | ||
| 37 | -public class RecordPreviewFragment extends MvpBindingFragment<RecordPreviewView, RecordPreviewPresenter, Object, FragmentRecordPreviewBinding> implements View.OnClickListener { | ||
| 38 | - | ||
| 39 | - //类型 0 是图片 1 是视频 | ||
| 40 | - public int type; | ||
| 41 | - //路径 | ||
| 42 | - public String path; | ||
| 43 | - // 处理 返回事件的监听 | ||
| 44 | - public OnBackPressedCallback callback = new OnBackPressedCallback(true) { | ||
| 45 | - @Override | ||
| 46 | - public void handleOnBackPressed() { | ||
| 47 | - callback.setEnabled(false); | ||
| 48 | - requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 49 | - } | ||
| 50 | - }; | ||
| 51 | - private RecordActivity mActivity; | ||
| 52 | - | ||
| 53 | - | ||
| 54 | - public static RecordPreviewFragment newInstance(int type, String path) { | ||
| 55 | - | ||
| 56 | - Bundle args = new Bundle(); | ||
| 57 | - | ||
| 58 | - RecordPreviewFragment fragment = new RecordPreviewFragment(); | ||
| 59 | - args.putInt("type", type); | ||
| 60 | - args.putString("path", path); | ||
| 61 | - fragment.setArguments(args); | ||
| 62 | - return fragment; | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - @Override | ||
| 66 | - protected int getLayoutId() { | ||
| 67 | - return R.layout.fragment_record_preview; | ||
| 68 | - } | ||
| 69 | - | ||
| 70 | - @Override | ||
| 71 | - public void onCreate(Bundle savedInstanceState) { | ||
| 72 | - super.onCreate(savedInstanceState); | ||
| 73 | - type = (int) getArguments().get("type"); | ||
| 74 | - path = (String) getArguments().get("path"); | ||
| 75 | - requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - @Override | ||
| 79 | - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | ||
| 80 | - super.onViewCreated(view, savedInstanceState); | ||
| 81 | - mActivity = (RecordActivity) getActivity(); | ||
| 82 | - binding.setOnClick(this); | ||
| 83 | - if (getMvpView() != null) getMvpView().initView(mActivity); | ||
| 84 | - | ||
| 85 | - } | ||
| 86 | - | ||
| 87 | - @Override | ||
| 88 | - public void onResume() { | ||
| 89 | - super.onResume(); | ||
| 90 | - if (type == 1 && getMvpView() != null) { | ||
| 91 | - getMvpView().initPre(); | ||
| 92 | - } | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - @Override | ||
| 96 | - public void onPause() { | ||
| 97 | - super.onPause(); | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | - @Override | ||
| 101 | - public void onDestroy() { | ||
| 102 | - super.onDestroy(); | ||
| 103 | - if (callback != null) callback.remove(); | ||
| 104 | - } | ||
| 105 | - | ||
| 106 | - @Override | ||
| 107 | - public void onClick(View v) { | ||
| 108 | - if (v.getId() == R.id.play_control_iv) { | ||
| 109 | - try { | ||
| 110 | - Uri uri = FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".fileprovider", new File(path)); | ||
| 111 | - Intent intent = new Intent(Intent.ACTION_VIEW); | ||
| 112 | - intent.setDataAndType(uri, "video/*"); | ||
| 113 | - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | ||
| 114 | - if (getActivity().getPackageManager().queryIntentActivities(intent, 0).isEmpty()) { | ||
| 115 | - getMvpView().showMessage("未检测到播放器"); | ||
| 116 | - } else { | ||
| 117 | - startActivity(intent); | ||
| 118 | - } | ||
| 119 | - } catch (Exception e) { | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - } else if (v.getId() == R.id.tb_cancel) { | ||
| 123 | - requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 124 | - } else if (v.getId() == R.id.tb_ok) { | ||
| 125 | - if (getMvpView() == null || DoublePressed.onDoublePressed()) return; | ||
| 126 | - if (type == 0) { | ||
| 127 | - getMvpView().savePic(mActivity); | ||
| 128 | - } else if (type == 1) { | ||
| 129 | - getMvpView().saveVideo(mActivity); | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | - | ||
| 133 | - } | ||
| 134 | - | ||
| 135 | - } | ||
| 136 | -} | 1 | +//package com.cnlive.media.ui.fragment; |
| 2 | +// | ||
| 3 | +//import android.content.ContentValues; | ||
| 4 | +//import android.content.Context; | ||
| 5 | +//import android.content.Intent; | ||
| 6 | +//import android.net.Uri; | ||
| 7 | +//import android.os.Bundle; | ||
| 8 | +//import android.provider.MediaStore; | ||
| 9 | +//import android.util.Log; | ||
| 10 | +//import android.view.View; | ||
| 11 | +// | ||
| 12 | +//import androidx.activity.OnBackPressedCallback; | ||
| 13 | +//import androidx.annotation.Nullable; | ||
| 14 | +//import androidx.core.content.FileProvider; | ||
| 15 | +// | ||
| 16 | +//import com.cnlive.libs.base.frame.fragment.MvpBindingFragment; | ||
| 17 | +//import com.cnlive.libs.base.util.AlertUtil; | ||
| 18 | +//import com.cnlive.libs.base.util.DoublePressed; | ||
| 19 | +//import com.cnlive.media.R; | ||
| 20 | +//import com.cnlive.media.databinding.FragmentRecordPreviewBinding; | ||
| 21 | +//import com.cnlive.media.frame.presenter.RecordPreviewPresenter; | ||
| 22 | +//import com.cnlive.media.frame.view.RecordPreviewView; | ||
| 23 | +//import com.cnlive.media.ui.activity.RecordActivity; | ||
| 24 | +//import com.cnlive.media.utils.AndroidQUtil; | ||
| 25 | +// | ||
| 26 | +//import java.io.File; | ||
| 27 | +// | ||
| 28 | +///** | ||
| 29 | +// * 作 者 : wkq | ||
| 30 | +// * <p> | ||
| 31 | +// * 时 间 : 2020/9/28 9:34 | ||
| 32 | +// * <p> | ||
| 33 | +// * 名 字 : RecordPreviewFragment | ||
| 34 | +// * <p> | ||
| 35 | +// * 简 介 : | ||
| 36 | +// */ | ||
| 37 | +//public class RecordPreviewFragment extends MvpBindingFragment<RecordPreviewView, RecordPreviewPresenter, Object, FragmentRecordPreviewBinding> implements View.OnClickListener { | ||
| 38 | +// | ||
| 39 | +// //类型 0 是图片 1 是视频 | ||
| 40 | +// public int type; | ||
| 41 | +// //路径 | ||
| 42 | +// public String path; | ||
| 43 | +// // 处理 返回事件的监听 | ||
| 44 | +// public OnBackPressedCallback callback = new OnBackPressedCallback(true) { | ||
| 45 | +// @Override | ||
| 46 | +// public void handleOnBackPressed() { | ||
| 47 | +// callback.setEnabled(false); | ||
| 48 | +// requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 49 | +// } | ||
| 50 | +// }; | ||
| 51 | +// private RecordActivity mActivity; | ||
| 52 | +// | ||
| 53 | +// | ||
| 54 | +// public static RecordPreviewFragment newInstance(int type, String path) { | ||
| 55 | +// | ||
| 56 | +// Bundle args = new Bundle(); | ||
| 57 | +// | ||
| 58 | +// RecordPreviewFragment fragment = new RecordPreviewFragment(); | ||
| 59 | +// args.putInt("type", type); | ||
| 60 | +// args.putString("path", path); | ||
| 61 | +// fragment.setArguments(args); | ||
| 62 | +// return fragment; | ||
| 63 | +// } | ||
| 64 | +// | ||
| 65 | +// @Override | ||
| 66 | +// protected int getLayoutId() { | ||
| 67 | +// return R.layout.fragment_record_preview; | ||
| 68 | +// } | ||
| 69 | +// | ||
| 70 | +// @Override | ||
| 71 | +// public void onCreate(Bundle savedInstanceState) { | ||
| 72 | +// super.onCreate(savedInstanceState); | ||
| 73 | +// type = (int) getArguments().get("type"); | ||
| 74 | +// path = (String) getArguments().get("path"); | ||
| 75 | +// requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); | ||
| 76 | +// } | ||
| 77 | +// | ||
| 78 | +// @Override | ||
| 79 | +// public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | ||
| 80 | +// super.onViewCreated(view, savedInstanceState); | ||
| 81 | +// mActivity = (RecordActivity) getActivity(); | ||
| 82 | +// binding.setOnClick(this); | ||
| 83 | +// if (getMvpView() != null) getMvpView().initView(mActivity); | ||
| 84 | +// | ||
| 85 | +// } | ||
| 86 | +// | ||
| 87 | +// @Override | ||
| 88 | +// public void onResume() { | ||
| 89 | +// super.onResume(); | ||
| 90 | +// if (type == 1 && getMvpView() != null) { | ||
| 91 | +// getMvpView().initPre(); | ||
| 92 | +// } | ||
| 93 | +// } | ||
| 94 | +// | ||
| 95 | +// @Override | ||
| 96 | +// public void onPause() { | ||
| 97 | +// super.onPause(); | ||
| 98 | +// } | ||
| 99 | +// | ||
| 100 | +// @Override | ||
| 101 | +// public void onDestroy() { | ||
| 102 | +// super.onDestroy(); | ||
| 103 | +// if (callback != null) callback.remove(); | ||
| 104 | +// } | ||
| 105 | +// | ||
| 106 | +// @Override | ||
| 107 | +// public void onClick(View v) { | ||
| 108 | +// if (v.getId() == R.id.play_control_iv) { | ||
| 109 | +// try { | ||
| 110 | +// Uri uri = FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".fileprovider", new File(path)); | ||
| 111 | +// Intent intent = new Intent(Intent.ACTION_VIEW); | ||
| 112 | +// intent.setDataAndType(uri, "video/*"); | ||
| 113 | +// intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | ||
| 114 | +// if (getActivity().getPackageManager().queryIntentActivities(intent, 0).isEmpty()) { | ||
| 115 | +// getMvpView().showMessage("未检测到播放器"); | ||
| 116 | +// } else { | ||
| 117 | +// startActivity(intent); | ||
| 118 | +// } | ||
| 119 | +// } catch (Exception e) { | ||
| 120 | +// } | ||
| 121 | +// | ||
| 122 | +// } else if (v.getId() == R.id.tb_cancel) { | ||
| 123 | +// requireActivity().getOnBackPressedDispatcher().onBackPressed(); | ||
| 124 | +// } else if (v.getId() == R.id.tb_ok) { | ||
| 125 | +// if (getMvpView() == null || DoublePressed.onDoublePressed()) return; | ||
| 126 | +// if (type == 0) { | ||
| 127 | +// getMvpView().savePic(mActivity); | ||
| 128 | +// } else if (type == 1) { | ||
| 129 | +// getMvpView().saveVideo(mActivity); | ||
| 130 | +// } | ||
| 131 | +// | ||
| 132 | +// | ||
| 133 | +// } | ||
| 134 | +// | ||
| 135 | +// } | ||
| 136 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/CameraInterface.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record; | ||
| 2 | + | ||
| 3 | +import static android.graphics.Bitmap.createBitmap; | ||
| 4 | + | ||
| 5 | +import android.animation.AnimatorSet; | ||
| 6 | +import android.animation.ObjectAnimator; | ||
| 7 | +import android.content.Context; | ||
| 8 | +import android.graphics.Bitmap; | ||
| 9 | +import android.graphics.BitmapFactory; | ||
| 10 | +import android.graphics.ImageFormat; | ||
| 11 | +import android.graphics.Matrix; | ||
| 12 | +import android.graphics.Rect; | ||
| 13 | +import android.graphics.RectF; | ||
| 14 | +import android.hardware.Camera; | ||
| 15 | +import android.hardware.Sensor; | ||
| 16 | +import android.hardware.SensorEvent; | ||
| 17 | +import android.hardware.SensorEventListener; | ||
| 18 | +import android.hardware.SensorManager; | ||
| 19 | +import android.media.MediaRecorder; | ||
| 20 | +import android.os.Build; | ||
| 21 | +import android.os.Environment; | ||
| 22 | +import android.util.Log; | ||
| 23 | +import android.view.Surface; | ||
| 24 | +import android.view.SurfaceHolder; | ||
| 25 | +import android.widget.ImageView; | ||
| 26 | + | ||
| 27 | +import com.cnlive.media.ui.widget.record.listener.ErrorListener; | ||
| 28 | +import com.cnlive.media.utils.AngleUtil; | ||
| 29 | +import com.cnlive.media.utils.CameraParamUtil; | ||
| 30 | +import com.cnlive.media.utils.DeviceUtil; | ||
| 31 | +import com.cnlive.media.utils.FileUtil; | ||
| 32 | +import com.cnlive.media.utils.LogUtil; | ||
| 33 | +import com.cnlive.media.utils.ScreenUtils; | ||
| 34 | + | ||
| 35 | +import java.io.File; | ||
| 36 | +import java.io.IOException; | ||
| 37 | +import java.util.ArrayList; | ||
| 38 | +import java.util.List; | ||
| 39 | + | ||
| 40 | +/** | ||
| 41 | + * ===================================== | ||
| 42 | + * 作 者: 陈嘉桐 | ||
| 43 | + * 版 本:1.1.4 | ||
| 44 | + * 创建日期:2017/4/25 | ||
| 45 | + * 描 述:camera操作单例 | ||
| 46 | + * ===================================== | ||
| 47 | + */ | ||
| 48 | +@SuppressWarnings("deprecation") | ||
| 49 | +public class CameraInterface implements Camera.PreviewCallback { | ||
| 50 | + | ||
| 51 | + private static final String TAG = "CJT"; | ||
| 52 | + | ||
| 53 | + private volatile static CameraInterface mCameraInterface; | ||
| 54 | + | ||
| 55 | + public static void destroyCameraInterface() { | ||
| 56 | + if (mCameraInterface != null) { | ||
| 57 | + mCameraInterface = null; | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + private Camera mCamera; | ||
| 62 | + private Camera.Parameters mParams; | ||
| 63 | + private boolean isPreviewing = false; | ||
| 64 | + | ||
| 65 | + private int SELECTED_CAMERA = -1; | ||
| 66 | + private int CAMERA_POST_POSITION = -1; | ||
| 67 | + private int CAMERA_FRONT_POSITION = -1; | ||
| 68 | + | ||
| 69 | + private SurfaceHolder mHolder = null; | ||
| 70 | + private float screenProp = -1.0f; | ||
| 71 | + | ||
| 72 | + private boolean isRecorder = false; | ||
| 73 | + private MediaRecorder mediaRecorder; | ||
| 74 | + private String videoFileName; | ||
| 75 | + private String saveVideoPath; | ||
| 76 | + private String videoFileAbsPath; | ||
| 77 | + | ||
| 78 | + private ErrorListener errorLisenter; | ||
| 79 | + | ||
| 80 | + private ImageView mSwitchView; | ||
| 81 | + private ImageView mFlashLamp; | ||
| 82 | + | ||
| 83 | + private int preview_width; | ||
| 84 | + private int preview_height; | ||
| 85 | + | ||
| 86 | + private int angle = 0; | ||
| 87 | + private int cameraAngle = 90;//摄像头角度 默认为90度 | ||
| 88 | + private int rotation = 0; | ||
| 89 | + private byte[] firstFrame_data; | ||
| 90 | + | ||
| 91 | + public static final int TYPE_RECORDER = 0x090; | ||
| 92 | + public static final int TYPE_CAPTURE = 0x091; | ||
| 93 | + private int nowScaleRate = 0; | ||
| 94 | + private int recordScleRate = 0; | ||
| 95 | + | ||
| 96 | + //视频质量 | ||
| 97 | + private int mediaQuality = JCameraView.MEDIA_QUALITY_HIGH; | ||
| 98 | + | ||
| 99 | + //获取CameraInterface单例 | ||
| 100 | + public static synchronized CameraInterface getInstance() { | ||
| 101 | + if (mCameraInterface == null) | ||
| 102 | + synchronized (CameraInterface.class) { | ||
| 103 | + if (mCameraInterface == null) | ||
| 104 | + mCameraInterface = new CameraInterface(); | ||
| 105 | + } | ||
| 106 | + return mCameraInterface; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + public void setSwitchView(ImageView mSwitchView, ImageView mFlashLamp) { | ||
| 110 | + this.mSwitchView = mSwitchView; | ||
| 111 | + this.mFlashLamp = mFlashLamp; | ||
| 112 | + if (mSwitchView != null) { | ||
| 113 | + cameraAngle = CameraParamUtil.getInstance().getCameraDisplayOrientation(mSwitchView.getContext(), | ||
| 114 | + SELECTED_CAMERA); | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + private SensorEventListener sensorEventListener = new SensorEventListener() { | ||
| 119 | + public void onSensorChanged(SensorEvent event) { | ||
| 120 | + if (Sensor.TYPE_ACCELEROMETER != event.sensor.getType()) { | ||
| 121 | + return; | ||
| 122 | + } | ||
| 123 | + float[] values = event.values; | ||
| 124 | + angle = AngleUtil.getSensorAngle(values[0], values[1]); | ||
| 125 | + rotationAnimation(); | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + public void onAccuracyChanged(Sensor sensor, int accuracy) { | ||
| 129 | + } | ||
| 130 | + }; | ||
| 131 | + | ||
| 132 | + //切换摄像头icon跟随手机角度进行旋转 | ||
| 133 | + private void rotationAnimation() { | ||
| 134 | + if (mSwitchView == null) { | ||
| 135 | + return; | ||
| 136 | + } | ||
| 137 | + if (rotation != angle) { | ||
| 138 | + int start_rotaion = 0; | ||
| 139 | + int end_rotation = 0; | ||
| 140 | + switch (rotation) { | ||
| 141 | + case 0: | ||
| 142 | + start_rotaion = 0; | ||
| 143 | + switch (angle) { | ||
| 144 | + case 90: | ||
| 145 | + end_rotation = -90; | ||
| 146 | + break; | ||
| 147 | + case 270: | ||
| 148 | + end_rotation = 90; | ||
| 149 | + break; | ||
| 150 | + } | ||
| 151 | + break; | ||
| 152 | + case 90: | ||
| 153 | + start_rotaion = -90; | ||
| 154 | + switch (angle) { | ||
| 155 | + case 0: | ||
| 156 | + end_rotation = 0; | ||
| 157 | + break; | ||
| 158 | + case 180: | ||
| 159 | + end_rotation = -180; | ||
| 160 | + break; | ||
| 161 | + } | ||
| 162 | + break; | ||
| 163 | + case 180: | ||
| 164 | + start_rotaion = 180; | ||
| 165 | + switch (angle) { | ||
| 166 | + case 90: | ||
| 167 | + end_rotation = 270; | ||
| 168 | + break; | ||
| 169 | + case 270: | ||
| 170 | + end_rotation = 90; | ||
| 171 | + break; | ||
| 172 | + } | ||
| 173 | + break; | ||
| 174 | + case 270: | ||
| 175 | + start_rotaion = 90; | ||
| 176 | + switch (angle) { | ||
| 177 | + case 0: | ||
| 178 | + end_rotation = 0; | ||
| 179 | + break; | ||
| 180 | + case 180: | ||
| 181 | + end_rotation = 180; | ||
| 182 | + break; | ||
| 183 | + } | ||
| 184 | + break; | ||
| 185 | + } | ||
| 186 | + ObjectAnimator animC = ObjectAnimator.ofFloat(mSwitchView, "rotation", start_rotaion, end_rotation); | ||
| 187 | +// ObjectAnimator animF = ObjectAnimator.ofFloat(mFlashLamp, "rotation", start_rotaion, end_rotation); | ||
| 188 | + AnimatorSet set = new AnimatorSet(); | ||
| 189 | + set.playTogether(animC); | ||
| 190 | + set.setDuration(500); | ||
| 191 | + set.start(); | ||
| 192 | + rotation = angle; | ||
| 193 | + } | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + @SuppressWarnings("ResultOfMethodCallIgnored") | ||
| 197 | + void setSaveVideoPath(String saveVideoPath) { | ||
| 198 | + this.saveVideoPath = saveVideoPath; | ||
| 199 | + File file = new File(saveVideoPath); | ||
| 200 | + if (!file.exists()) { | ||
| 201 | + file.mkdirs(); | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + | ||
| 206 | + public void setZoom(float zoom, int type) { | ||
| 207 | + if (mCamera == null) { | ||
| 208 | + return; | ||
| 209 | + } | ||
| 210 | + try { | ||
| 211 | + if (mParams == null) { | ||
| 212 | + mParams = mCamera.getParameters(); | ||
| 213 | + } | ||
| 214 | + if (!mParams.isZoomSupported() || !mParams.isSmoothZoomSupported()) { | ||
| 215 | + return; | ||
| 216 | + } | ||
| 217 | + switch (type) { | ||
| 218 | + case TYPE_RECORDER: | ||
| 219 | + //如果不是录制视频中,上滑不会缩放 | ||
| 220 | + if (!isRecorder) { | ||
| 221 | + return; | ||
| 222 | + } | ||
| 223 | + if (zoom >= 0) { | ||
| 224 | + //每移动50个像素缩放一个级别 | ||
| 225 | + int scaleRate = (int) (zoom / 40); | ||
| 226 | + if (scaleRate <= mParams.getMaxZoom() && scaleRate >= nowScaleRate && recordScleRate != scaleRate) { | ||
| 227 | + mParams.setZoom(scaleRate); | ||
| 228 | + mCamera.setParameters(mParams); | ||
| 229 | + recordScleRate = scaleRate; | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + break; | ||
| 233 | + case TYPE_CAPTURE: | ||
| 234 | + if (isRecorder) { | ||
| 235 | + return; | ||
| 236 | + } | ||
| 237 | + //每移动50个像素缩放一个级别 | ||
| 238 | + int scaleRate = (int) (zoom / 50); | ||
| 239 | + if (scaleRate < mParams.getMaxZoom()) { | ||
| 240 | + nowScaleRate += scaleRate; | ||
| 241 | + if (nowScaleRate < 0) { | ||
| 242 | + nowScaleRate = 0; | ||
| 243 | + } else if (nowScaleRate > mParams.getMaxZoom()) { | ||
| 244 | + nowScaleRate = mParams.getMaxZoom(); | ||
| 245 | + } | ||
| 246 | + mParams.setZoom(nowScaleRate); | ||
| 247 | + mCamera.setParameters(mParams); | ||
| 248 | + } | ||
| 249 | + LogUtil.i("setZoom = " + nowScaleRate); | ||
| 250 | + break; | ||
| 251 | + } | ||
| 252 | + } catch (Exception ignored) { | ||
| 253 | + | ||
| 254 | + } | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + void setMediaQuality(int quality) { | ||
| 258 | + this.mediaQuality = quality; | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + | ||
| 262 | + @Override | ||
| 263 | + public void onPreviewFrame(byte[] data, Camera camera) { | ||
| 264 | + firstFrame_data = data; | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + public void setFlashMode(String flashMode) { | ||
| 268 | + if (mCamera == null) | ||
| 269 | + return; | ||
| 270 | + try { | ||
| 271 | + | ||
| 272 | + Camera.Parameters parameters = mCamera.getParameters(); | ||
| 273 | + List<String> flashModes = parameters.getSupportedFlashModes(); | ||
| 274 | + if (flashModes == null) { | ||
| 275 | + return; | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + if (flashMode.contains(Camera.Parameters.FLASH_MODE_ON)) { | ||
| 279 | + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON); | ||
| 280 | + mCamera.setParameters(parameters); | ||
| 281 | + } else if (flashMode.contains(Camera.Parameters.FLASH_MODE_OFF)) { | ||
| 282 | + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); | ||
| 283 | + mCamera.setParameters(parameters); | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + return; | ||
| 287 | + } catch (Exception e) { | ||
| 288 | + Log.e("Camera", "闪光灯异常", e); | ||
| 289 | + } | ||
| 290 | + return; | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + public int getSelectedCamera() { | ||
| 294 | + return SELECTED_CAMERA; | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + public interface CameraOpenOverCallback { | ||
| 298 | + void cameraHasOpened(); | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + private CameraInterface() { | ||
| 302 | + findAvailableCameras(); | ||
| 303 | + SELECTED_CAMERA = CAMERA_POST_POSITION; | ||
| 304 | + saveVideoPath = ""; | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + | ||
| 308 | + /** | ||
| 309 | + * open Camera | ||
| 310 | + */ | ||
| 311 | + void doOpenCamera(CameraOpenOverCallback callback, int id) { | ||
| 312 | + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { | ||
| 313 | + if (!CheckPermission.isCameraUseable(id) && this.errorLisenter != null) { | ||
| 314 | + this.errorLisenter.onError(); | ||
| 315 | + return; | ||
| 316 | + } | ||
| 317 | + } | ||
| 318 | + if (mCamera == null) { | ||
| 319 | + openCamera(id); | ||
| 320 | + } | ||
| 321 | + callback.cameraHasOpened(); | ||
| 322 | + } | ||
| 323 | + | ||
| 324 | + private void setFlashModel() { | ||
| 325 | + mParams = mCamera.getParameters(); | ||
| 326 | + mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); //设置camera参数为Torch模式 | ||
| 327 | + mCamera.setParameters(mParams); | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + private synchronized boolean openCamera(int id) { | ||
| 331 | + try { | ||
| 332 | + this.mCamera = Camera.open(id); | ||
| 333 | + } catch (Exception e) { | ||
| 334 | + if (this.errorLisenter != null) this.errorLisenter.onError(); | ||
| 335 | + Log.e("CJT", "enable shutter sound faild", e); | ||
| 336 | + } | ||
| 337 | + | ||
| 338 | + try { | ||
| 339 | + if (Build.VERSION.SDK_INT > 17 && this.mCamera != null) { | ||
| 340 | + this.mCamera.enableShutterSound(false); | ||
| 341 | + } | ||
| 342 | + } catch (Exception e) { | ||
| 343 | + Log.e("CJT", "enable shutter sound faild", e); | ||
| 344 | + } | ||
| 345 | + | ||
| 346 | + return mCamera != null; | ||
| 347 | + } | ||
| 348 | + | ||
| 349 | + public synchronized boolean switchCamera(SurfaceHolder holder, float screenProp) { | ||
| 350 | + if (SELECTED_CAMERA == CAMERA_POST_POSITION) { | ||
| 351 | + SELECTED_CAMERA = CAMERA_FRONT_POSITION; | ||
| 352 | + } else { | ||
| 353 | + SELECTED_CAMERA = CAMERA_POST_POSITION; | ||
| 354 | + } | ||
| 355 | + doDestroyCamera(); | ||
| 356 | + LogUtil.i("open start"); | ||
| 357 | + openCamera(SELECTED_CAMERA); | ||
| 358 | + if (Build.VERSION.SDK_INT > 17 && this.mCamera != null) { | ||
| 359 | + try { | ||
| 360 | + this.mCamera.enableShutterSound(false); | ||
| 361 | + } catch (Exception e) { | ||
| 362 | + e.printStackTrace(); | ||
| 363 | + } | ||
| 364 | + } | ||
| 365 | + LogUtil.i("open end"); | ||
| 366 | + return doStartPreview(holder, screenProp); | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + /** | ||
| 370 | + * doStartPreview | ||
| 371 | + */ | ||
| 372 | + public boolean doStartPreview(SurfaceHolder holder, float screenProp) { | ||
| 373 | + if (isPreviewing) { | ||
| 374 | + LogUtil.i("doStartPreview isPreviewing"); | ||
| 375 | + } | ||
| 376 | + if (this.screenProp < 0) { | ||
| 377 | + this.screenProp = screenProp; | ||
| 378 | + } | ||
| 379 | + if (holder == null) { | ||
| 380 | + return false; | ||
| 381 | + } | ||
| 382 | + this.mHolder = holder; | ||
| 383 | + if (mCamera != null) { | ||
| 384 | + try { | ||
| 385 | + mParams = mCamera.getParameters(); | ||
| 386 | + Camera.Size previewSize = CameraParamUtil.getInstance().getPreviewSize(mParams | ||
| 387 | + .getSupportedPreviewSizes(), 1000, screenProp); | ||
| 388 | + Camera.Size pictureSize = CameraParamUtil.getInstance().getPictureSize(mParams | ||
| 389 | + .getSupportedPictureSizes(), 1200, screenProp); | ||
| 390 | + | ||
| 391 | + mParams.setPreviewSize(previewSize.width, previewSize.height); | ||
| 392 | + | ||
| 393 | + preview_width = previewSize.width; | ||
| 394 | + preview_height = previewSize.height; | ||
| 395 | + | ||
| 396 | + mParams.setPictureSize(pictureSize.width, pictureSize.height); | ||
| 397 | + | ||
| 398 | + if (CameraParamUtil.getInstance().isSupportedFocusMode( | ||
| 399 | + mParams.getSupportedFocusModes(), | ||
| 400 | + Camera.Parameters.FOCUS_MODE_AUTO)) { | ||
| 401 | + mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); | ||
| 402 | + } | ||
| 403 | + | ||
| 404 | + | ||
| 405 | + List<Camera.Size> sizeList = mParams.getSupportedPreviewSizes(); | ||
| 406 | + Camera.Size optionSize = getOptimalPreviewSize(sizeList, preview_width - 200, preview_height - 200); | ||
| 407 | + mParams.setPreviewSize(optionSize.width, optionSize.height); | ||
| 408 | + if (CameraParamUtil.getInstance().isSupportedPictureFormats(mParams.getSupportedPictureFormats(), | ||
| 409 | + ImageFormat.JPEG)) { | ||
| 410 | + mParams.setPictureFormat(ImageFormat.JPEG); | ||
| 411 | + mParams.setJpegQuality(100); | ||
| 412 | + } | ||
| 413 | + mCamera.setParameters(mParams); | ||
| 414 | + //通过SurfaceView显示预览 | ||
| 415 | + mCamera.setPreviewDisplay(mHolder); | ||
| 416 | + mCamera.setDisplayOrientation(cameraAngle); | ||
| 417 | + mCamera.setPreviewCallback(this); //每一帧回调 | ||
| 418 | + //开始预览 | ||
| 419 | + mCamera.startPreview(); | ||
| 420 | + isPreviewing = true; | ||
| 421 | + Log.i(TAG, "=== Start Preview ==="); | ||
| 422 | + return true; | ||
| 423 | + } catch (Exception e) { | ||
| 424 | + Log.e("Camera", "开启预览异常", e); | ||
| 425 | + } | ||
| 426 | + } | ||
| 427 | + return false; | ||
| 428 | + } | ||
| 429 | + | ||
| 430 | + | ||
| 431 | + private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { | ||
| 432 | + final double ASPECT_TOLERANCE = 0.1; | ||
| 433 | + double targetRatio = (double) w / h; | ||
| 434 | + if (sizes == null) return null; | ||
| 435 | + | ||
| 436 | + Camera.Size optimalSize = null; | ||
| 437 | + double minDiff = Double.MAX_VALUE; | ||
| 438 | + int targetHeight = h; | ||
| 439 | + | ||
| 440 | + for (Camera.Size size : sizes) { | ||
| 441 | + double ratio = (double) size.width / size.height; | ||
| 442 | + if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; | ||
| 443 | + if (Math.abs(size.height - targetHeight) < minDiff) { | ||
| 444 | + optimalSize = size; | ||
| 445 | + minDiff = Math.abs(size.height - targetHeight); | ||
| 446 | + } | ||
| 447 | + } | ||
| 448 | + if (optimalSize == null) { | ||
| 449 | + minDiff = Double.MAX_VALUE; | ||
| 450 | + for (Camera.Size size : sizes) { | ||
| 451 | + if (Math.abs(size.height - targetHeight) < minDiff) { | ||
| 452 | + optimalSize = size; | ||
| 453 | + minDiff = Math.abs(size.height - targetHeight); | ||
| 454 | + } | ||
| 455 | + } | ||
| 456 | + } | ||
| 457 | + return optimalSize; | ||
| 458 | + } | ||
| 459 | + | ||
| 460 | + | ||
| 461 | + /** | ||
| 462 | + * 停止预览 | ||
| 463 | + */ | ||
| 464 | + public void doStopPreview() { | ||
| 465 | + if (null != mCamera) { | ||
| 466 | + try { | ||
| 467 | + mCamera.setPreviewCallback(null); | ||
| 468 | + mCamera.stopPreview(); | ||
| 469 | + //这句要在stopPreview后执行,不然会卡顿或者花屏 | ||
| 470 | + mCamera.setPreviewDisplay(null); | ||
| 471 | + isPreviewing = false; | ||
| 472 | + mCamera.lock(); | ||
| 473 | + Log.i(TAG, "=== Stop Preview ==="); | ||
| 474 | + } catch (Exception e) { | ||
| 475 | + Log.e("Camera", "", e); | ||
| 476 | + } | ||
| 477 | + } | ||
| 478 | + } | ||
| 479 | + | ||
| 480 | + /** | ||
| 481 | + * 销毁Camera | ||
| 482 | + */ | ||
| 483 | + boolean doDestroyCamera() { | ||
| 484 | + errorLisenter = null; | ||
| 485 | + if (null != mCamera) { | ||
| 486 | + try { | ||
| 487 | + mCamera.setPreviewCallback(null); | ||
| 488 | + mSwitchView = null; | ||
| 489 | +// mFlashLamp = null; | ||
| 490 | + mCamera.stopPreview(); | ||
| 491 | + //这句要在stopPreview后执行,不然会卡顿或者花屏 | ||
| 492 | + mCamera.setPreviewDisplay(null); | ||
| 493 | + mHolder = null; | ||
| 494 | + isPreviewing = false; | ||
| 495 | + mCamera.lock(); | ||
| 496 | + mCamera.release(); | ||
| 497 | + mCamera = null; | ||
| 498 | +// destroyCameraInterface(); | ||
| 499 | + Log.i(TAG, "=== Destroy Camera ==="); | ||
| 500 | + return true; | ||
| 501 | + } catch (Exception e) { | ||
| 502 | + Log.e("Camera", "", e); | ||
| 503 | + } | ||
| 504 | + return false; | ||
| 505 | + } else { | ||
| 506 | + Log.i(TAG, "=== Camera Null==="); | ||
| 507 | + } | ||
| 508 | + return true; | ||
| 509 | + } | ||
| 510 | + | ||
| 511 | + /** | ||
| 512 | + * 拍照 | ||
| 513 | + */ | ||
| 514 | + private int nowAngle; | ||
| 515 | + | ||
| 516 | + public boolean takePicture(TakePictureCallback callback) { | ||
| 517 | + if (mCamera == null) { | ||
| 518 | + return false; | ||
| 519 | + } | ||
| 520 | + switch (cameraAngle) { | ||
| 521 | + case 90: | ||
| 522 | + nowAngle = Math.abs(angle + cameraAngle) % 360; | ||
| 523 | + break; | ||
| 524 | + case 270: | ||
| 525 | + nowAngle = Math.abs(cameraAngle - angle); | ||
| 526 | + break; | ||
| 527 | + } | ||
| 528 | +// | ||
| 529 | + Log.i("CJT", angle + " = " + cameraAngle + " = " + nowAngle); | ||
| 530 | + try { | ||
| 531 | + mCamera.takePicture(null, null, new Camera.PictureCallback() { | ||
| 532 | + @Override | ||
| 533 | + public void onPictureTaken(byte[] data, Camera camera) { | ||
| 534 | + Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); | ||
| 535 | + Matrix matrix = new Matrix(); | ||
| 536 | + if (SELECTED_CAMERA == CAMERA_POST_POSITION) { | ||
| 537 | + matrix.setRotate(nowAngle); | ||
| 538 | + } else if (SELECTED_CAMERA == CAMERA_FRONT_POSITION) { | ||
| 539 | + matrix.setRotate(360 - nowAngle); | ||
| 540 | + matrix.postScale(-1, 1); | ||
| 541 | + } | ||
| 542 | + | ||
| 543 | + bitmap = createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); | ||
| 544 | + if (callback != null) { | ||
| 545 | + if (nowAngle == 90 || nowAngle == 270) { | ||
| 546 | + callback.captureResult(bitmap, true); | ||
| 547 | + } else { | ||
| 548 | + callback.captureResult(bitmap, false); | ||
| 549 | + } | ||
| 550 | + } | ||
| 551 | + } | ||
| 552 | + }); | ||
| 553 | + return true; | ||
| 554 | + } catch (Exception e) { | ||
| 555 | + Log.e("Camera", "拍摄异常", e); | ||
| 556 | + } | ||
| 557 | + return false; | ||
| 558 | + } | ||
| 559 | + | ||
| 560 | + //启动录像 | ||
| 561 | + public boolean startRecord(Surface surface, float screenProp, ErrorCallback callback, Context context) { | ||
| 562 | + if (mCamera == null) return false; | ||
| 563 | + mCamera.setPreviewCallback(null); | ||
| 564 | + final int nowAngle = (angle + 90) % 360; | ||
| 565 | + //获取第一帧图片 | ||
| 566 | +// Camera.Parameters parameters = mCamera.getParameters(); | ||
| 567 | +// int width = parameters.getPreviewSize().width; | ||
| 568 | +// int height = parameters.getPreviewSize().height; | ||
| 569 | +// YuvImage yuv = new YuvImage(firstFrame_data, parameters.getPreviewFormat(), width, height, null); | ||
| 570 | +// ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
| 571 | +// yuv.compressToJpeg(new Rect(0, 0, width, height), 50, out); | ||
| 572 | +// Matrix matrix = new Matrix(); | ||
| 573 | +// if (SELECTED_CAMERA == CAMERA_POST_POSITION) { | ||
| 574 | +// matrix.setRotate(nowAngle); | ||
| 575 | +// } else if (SELECTED_CAMERA == CAMERA_FRONT_POSITION) { | ||
| 576 | +// matrix.setRotate(270); | ||
| 577 | +// } | ||
| 578 | + | ||
| 579 | + if (isRecorder) { | ||
| 580 | + return true; | ||
| 581 | + } | ||
| 582 | + if (mCamera == null) { | ||
| 583 | + openCamera(SELECTED_CAMERA); | ||
| 584 | + } | ||
| 585 | + if (mCamera == null) { | ||
| 586 | + return false; | ||
| 587 | + } | ||
| 588 | + if (mediaRecorder == null) { | ||
| 589 | + mediaRecorder = new MediaRecorder(); | ||
| 590 | + } | ||
| 591 | + if (mParams == null) { | ||
| 592 | + mParams = mCamera.getParameters(); | ||
| 593 | + } | ||
| 594 | + List<String> focusModes = mParams.getSupportedFocusModes(); | ||
| 595 | + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { | ||
| 596 | + mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); | ||
| 597 | + } | ||
| 598 | + try { | ||
| 599 | + mCamera.setParameters(mParams); | ||
| 600 | + } catch (Exception e) { | ||
| 601 | + | ||
| 602 | + } | ||
| 603 | + try { | ||
| 604 | + mCamera.unlock(); | ||
| 605 | + } catch (Exception e) { | ||
| 606 | + | ||
| 607 | + } | ||
| 608 | + try { | ||
| 609 | + mediaRecorder.reset(); | ||
| 610 | + mediaRecorder.setCamera(mCamera); | ||
| 611 | + mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); | ||
| 612 | + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); | ||
| 613 | + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); | ||
| 614 | + mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); | ||
| 615 | + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); | ||
| 616 | + | ||
| 617 | + | ||
| 618 | + Camera.Size videoSize; | ||
| 619 | + if (mParams.getSupportedVideoSizes() == null) { | ||
| 620 | + videoSize = CameraParamUtil.getInstance().getPreviewSize(mParams.getSupportedPreviewSizes(), 600, | ||
| 621 | + screenProp); | ||
| 622 | + } else { | ||
| 623 | + videoSize = CameraParamUtil.getInstance().getPreviewSize(mParams.getSupportedVideoSizes(), 600, | ||
| 624 | + screenProp); | ||
| 625 | + } | ||
| 626 | + Log.i(TAG, "setVideoSize width = " + videoSize.width + "height = " + videoSize.height); | ||
| 627 | + if (videoSize.width == videoSize.height) { | ||
| 628 | + mediaRecorder.setVideoSize(preview_width, preview_height); | ||
| 629 | + } else { | ||
| 630 | + mediaRecorder.setVideoSize(videoSize.width, videoSize.height); | ||
| 631 | + } | ||
| 632 | +// if (SELECTED_CAMERA == CAMERA_FRONT_POSITION) { | ||
| 633 | +// mediaRecorder.setOrientationHint(270); | ||
| 634 | +// } else { | ||
| 635 | +// mediaRecorder.setOrientationHint(nowAngle); | ||
| 636 | +//// mediaRecorder.setOrientationHint(90); | ||
| 637 | +// } | ||
| 638 | + | ||
| 639 | + if (SELECTED_CAMERA == CAMERA_FRONT_POSITION) { | ||
| 640 | + //手机预览倒立的处理 | ||
| 641 | + if (cameraAngle == 270) { | ||
| 642 | + //横屏 | ||
| 643 | + if (nowAngle == 0) { | ||
| 644 | + mediaRecorder.setOrientationHint(180); | ||
| 645 | + } else if (nowAngle == 270) { | ||
| 646 | + mediaRecorder.setOrientationHint(270); | ||
| 647 | + } else { | ||
| 648 | + mediaRecorder.setOrientationHint(90); | ||
| 649 | + } | ||
| 650 | + } else { | ||
| 651 | + if (nowAngle == 90) { | ||
| 652 | + mediaRecorder.setOrientationHint(270); | ||
| 653 | + } else if (nowAngle == 270) { | ||
| 654 | + mediaRecorder.setOrientationHint(90); | ||
| 655 | + } else { | ||
| 656 | + mediaRecorder.setOrientationHint(nowAngle); | ||
| 657 | + } | ||
| 658 | + } | ||
| 659 | + } else { | ||
| 660 | + mediaRecorder.setOrientationHint(nowAngle); | ||
| 661 | + } | ||
| 662 | + | ||
| 663 | + | ||
| 664 | + if (DeviceUtil.isHuaWeiRongyao()) { | ||
| 665 | + mediaRecorder.setVideoEncodingBitRate(4 * 100000); | ||
| 666 | + } else { | ||
| 667 | + mediaRecorder.setVideoEncodingBitRate(mediaQuality); | ||
| 668 | + } | ||
| 669 | + mediaRecorder.setPreviewDisplay(surface); | ||
| 670 | + | ||
| 671 | + videoFileName = "video_" + System.currentTimeMillis() + ".mp4"; | ||
| 672 | + if (saveVideoPath.equals("")) { | ||
| 673 | + saveVideoPath = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ? context.getExternalFilesDir("") : Environment.getExternalStorageDirectory()).getPath(); | ||
| 674 | + } | ||
| 675 | + videoFileAbsPath = saveVideoPath + File.separator + videoFileName; | ||
| 676 | + mediaRecorder.setOutputFile(videoFileAbsPath); | ||
| 677 | + | ||
| 678 | + mediaRecorder.prepare(); | ||
| 679 | + mediaRecorder.start(); | ||
| 680 | + isRecorder = true; | ||
| 681 | + return true; | ||
| 682 | + } catch (IllegalStateException e) { | ||
| 683 | + e.printStackTrace(); | ||
| 684 | + Log.i("CJT", "startRecord IllegalStateException"); | ||
| 685 | + if (this.errorLisenter != null) { | ||
| 686 | + this.errorLisenter.onError(); | ||
| 687 | + } | ||
| 688 | + } catch (IOException e) { | ||
| 689 | + e.printStackTrace(); | ||
| 690 | + Log.i("CJT", "startRecord IOException"); | ||
| 691 | + if (this.errorLisenter != null) { | ||
| 692 | + this.errorLisenter.onError(); | ||
| 693 | + } | ||
| 694 | + } catch (RuntimeException e) { | ||
| 695 | + Log.i("CJT", "startRecord RuntimeException"); | ||
| 696 | + } catch (Exception e) { | ||
| 697 | + Log.i("CJT", "startRecord Exception"); | ||
| 698 | + } | ||
| 699 | + return false; | ||
| 700 | + } | ||
| 701 | + | ||
| 702 | + public void onDestroy() { | ||
| 703 | + if (isRecorder) { | ||
| 704 | + return; | ||
| 705 | + } | ||
| 706 | + if (mediaRecorder != null) { | ||
| 707 | + mediaRecorder.setOnErrorListener(null); | ||
| 708 | + mediaRecorder.setOnInfoListener(null); | ||
| 709 | + mediaRecorder.setPreviewDisplay(null); | ||
| 710 | + try { | ||
| 711 | + mediaRecorder.stop(); | ||
| 712 | + } catch (RuntimeException e) { | ||
| 713 | + e.printStackTrace(); | ||
| 714 | + mediaRecorder = null; | ||
| 715 | + mediaRecorder = new MediaRecorder(); | ||
| 716 | + } finally { | ||
| 717 | + if (mediaRecorder != null) mediaRecorder.release(); | ||
| 718 | + mediaRecorder = null; | ||
| 719 | + isRecorder = false; | ||
| 720 | + } | ||
| 721 | + } | ||
| 722 | + doStopPreview(); | ||
| 723 | + } | ||
| 724 | + | ||
| 725 | + //停止录像 | ||
| 726 | + public void stopRecord(boolean isShort, StopRecordCallback callback) { | ||
| 727 | + if (!isRecorder) { | ||
| 728 | + return; | ||
| 729 | + } | ||
| 730 | + if (mediaRecorder != null) { | ||
| 731 | + mediaRecorder.setOnErrorListener(null); | ||
| 732 | + mediaRecorder.setOnInfoListener(null); | ||
| 733 | + mediaRecorder.setPreviewDisplay(null); | ||
| 734 | + try { | ||
| 735 | + mediaRecorder.stop(); | ||
| 736 | + } catch (RuntimeException e) { | ||
| 737 | + e.printStackTrace(); | ||
| 738 | + mediaRecorder = null; | ||
| 739 | + mediaRecorder = new MediaRecorder(); | ||
| 740 | + } finally { | ||
| 741 | + if (mediaRecorder != null) { | ||
| 742 | + mediaRecorder.release(); | ||
| 743 | + } | ||
| 744 | + mediaRecorder = null; | ||
| 745 | + isRecorder = false; | ||
| 746 | + } | ||
| 747 | + if (isShort) { | ||
| 748 | + if (FileUtil.deleteFile(videoFileAbsPath)) { | ||
| 749 | + callback.recordResult(null); | ||
| 750 | + } | ||
| 751 | + return; | ||
| 752 | + } | ||
| 753 | + doStopPreview(); | ||
| 754 | + String fileName = saveVideoPath + File.separator + videoFileName; | ||
| 755 | + callback.recordResult(fileName); | ||
| 756 | + } | ||
| 757 | + } | ||
| 758 | + | ||
| 759 | + private void findAvailableCameras() { | ||
| 760 | + Camera.CameraInfo info = new Camera.CameraInfo(); | ||
| 761 | + int cameraNum = Camera.getNumberOfCameras(); | ||
| 762 | + for (int i = 0; i < cameraNum; i++) { | ||
| 763 | + //TODO 存在异常隐患 | ||
| 764 | + try { | ||
| 765 | + Camera.getCameraInfo(i, info); | ||
| 766 | + } catch (Exception e) { | ||
| 767 | + Log.e("CameraInterface", "相机信息获取异常", e); | ||
| 768 | + continue; | ||
| 769 | + } | ||
| 770 | + switch (info.facing) { | ||
| 771 | + case Camera.CameraInfo.CAMERA_FACING_FRONT: | ||
| 772 | + CAMERA_FRONT_POSITION = info.facing; | ||
| 773 | + break; | ||
| 774 | + case Camera.CameraInfo.CAMERA_FACING_BACK: | ||
| 775 | + CAMERA_POST_POSITION = info.facing; | ||
| 776 | + break; | ||
| 777 | + } | ||
| 778 | + } | ||
| 779 | + } | ||
| 780 | + | ||
| 781 | + private int handlerTime = 0; | ||
| 782 | + | ||
| 783 | + public boolean handleFocus(final Context context, final float x, final float y, final FocusCallback callback) { | ||
| 784 | + if (mCamera == null) { | ||
| 785 | + return false; | ||
| 786 | + } | ||
| 787 | + try { | ||
| 788 | + final Camera.Parameters params = mCamera.getParameters(); | ||
| 789 | + Rect focusRect = calculateTapArea(x, y, 1f, context); | ||
| 790 | + mCamera.cancelAutoFocus(); | ||
| 791 | + if (params.getMaxNumFocusAreas() > 0) { | ||
| 792 | + List<Camera.Area> focusAreas = new ArrayList<>(); | ||
| 793 | + focusAreas.add(new Camera.Area(focusRect, 800)); | ||
| 794 | + params.setFocusAreas(focusAreas); | ||
| 795 | + } else { | ||
| 796 | + Log.i(TAG, "focus areas not supported"); | ||
| 797 | + callback.focusSuccess(); | ||
| 798 | + return false; | ||
| 799 | + } | ||
| 800 | + final String currentFocusMode = params.getFocusMode(); | ||
| 801 | + | ||
| 802 | + params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); | ||
| 803 | + mCamera.setParameters(params); | ||
| 804 | + mCamera.autoFocus(new Camera.AutoFocusCallback() { | ||
| 805 | + @Override | ||
| 806 | + public void onAutoFocus(boolean success, Camera camera) { | ||
| 807 | + if (success || handlerTime > 10) { | ||
| 808 | + Camera.Parameters params = camera.getParameters(); | ||
| 809 | + params.setFocusMode(currentFocusMode); | ||
| 810 | + camera.setParameters(params); | ||
| 811 | + handlerTime = 0; | ||
| 812 | + callback.focusSuccess(); | ||
| 813 | + } else { | ||
| 814 | + handlerTime++; | ||
| 815 | + handleFocus(context, x, y, callback); | ||
| 816 | + } | ||
| 817 | + } | ||
| 818 | + }); | ||
| 819 | + return true; | ||
| 820 | + } catch (Exception e) { | ||
| 821 | + Log.e(TAG, "autoFocus failer"); | ||
| 822 | + } | ||
| 823 | + return false; | ||
| 824 | + } | ||
| 825 | + | ||
| 826 | + | ||
| 827 | + private static Rect calculateTapArea(float x, float y, float coefficient, Context context) { | ||
| 828 | + float focusAreaSize = 300; | ||
| 829 | + int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue(); | ||
| 830 | + int centerX = (int) (x / ScreenUtils.getScreenWidth(context) * 2000 - 1000); | ||
| 831 | + int centerY = (int) (y / ScreenUtils.getScreenHeight(context) * 2000 - 1000); | ||
| 832 | + int left = clamp(centerX - areaSize / 2, -1000, 1000); | ||
| 833 | + int top = clamp(centerY - areaSize / 2, -1000, 1000); | ||
| 834 | + RectF rectF = new RectF(left, top, left + areaSize, top + areaSize); | ||
| 835 | + return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF | ||
| 836 | + .bottom)); | ||
| 837 | + } | ||
| 838 | + | ||
| 839 | + private static int clamp(int x, int min, int max) { | ||
| 840 | + if (x > max) { | ||
| 841 | + return max; | ||
| 842 | + } | ||
| 843 | + if (x < min) { | ||
| 844 | + return min; | ||
| 845 | + } | ||
| 846 | + return x; | ||
| 847 | + } | ||
| 848 | + | ||
| 849 | + void setErrorLinsenter(ErrorListener errorLisenter) { | ||
| 850 | + this.errorLisenter = errorLisenter; | ||
| 851 | + } | ||
| 852 | + | ||
| 853 | + | ||
| 854 | + public interface StopRecordCallback { | ||
| 855 | + void recordResult(String url); | ||
| 856 | + } | ||
| 857 | + | ||
| 858 | + interface ErrorCallback { | ||
| 859 | + void onError(); | ||
| 860 | + } | ||
| 861 | + | ||
| 862 | + public interface TakePictureCallback { | ||
| 863 | + void captureResult(Bitmap bitmap, boolean isVertical); | ||
| 864 | + } | ||
| 865 | + | ||
| 866 | + public interface FocusCallback { | ||
| 867 | + void focusSuccess(); | ||
| 868 | + | ||
| 869 | + } | ||
| 870 | + | ||
| 871 | + | ||
| 872 | + void registerSensorManager(Context context) { | ||
| 873 | + SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); | ||
| 874 | + if (sm == null) return; | ||
| 875 | + Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); | ||
| 876 | + sm.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); | ||
| 877 | + } | ||
| 878 | + | ||
| 879 | + void unregisterSensorManager(Context context) { | ||
| 880 | + SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); | ||
| 881 | + if (sm == null) return; | ||
| 882 | + sm.unregisterListener(sensorEventListener); | ||
| 883 | + } | ||
| 884 | + | ||
| 885 | + void isPreview(boolean res) { | ||
| 886 | + this.isPreviewing = res; | ||
| 887 | + } | ||
| 888 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/CaptureLayout.java
| 1 | -//package com.cnlive.media.ui.widget.record; | ||
| 2 | -// | ||
| 3 | -//import android.animation.Animator; | ||
| 4 | -//import android.animation.AnimatorListenerAdapter; | ||
| 5 | -//import android.animation.AnimatorSet; | ||
| 6 | -//import android.animation.ObjectAnimator; | ||
| 7 | -//import android.content.Context; | ||
| 8 | -//import android.content.res.Configuration; | ||
| 9 | -//import android.content.res.Resources; | ||
| 10 | -//import android.util.AttributeSet; | ||
| 11 | -//import android.view.Gravity; | ||
| 12 | -//import android.view.View; | ||
| 13 | -//import android.widget.FrameLayout; | ||
| 14 | -//import android.widget.ImageView; | ||
| 15 | -//import android.widget.TextView; | ||
| 16 | -// | ||
| 17 | -//import com.cnlive.libs.base.util.DoublePressed; | ||
| 18 | -//import CaptureListener; | ||
| 19 | -//import ClickListener; | ||
| 20 | -//import ReturnListener; | ||
| 21 | -//import TypeListener; | ||
| 22 | -// | ||
| 23 | -// | ||
| 24 | -//import static CaptureButton.BUTTON_STATE_BOTH; | ||
| 25 | -//import static CaptureButton.BUTTON_STATE_ONLY_CAPTURE; | ||
| 26 | -//import static CaptureButton.BUTTON_STATE_ONLY_RECORDER; | ||
| 27 | -// | ||
| 28 | -// | ||
| 29 | -//public class CaptureLayout extends FrameLayout { | ||
| 30 | -// private boolean isErrorState = false; | ||
| 31 | -// private CaptureListener captureLisenter; //拍照按钮监听 | ||
| 32 | -// private TypeListener typeLisenter; //拍照或录制后接结果按钮监听 | ||
| 33 | -// private ReturnListener returnListener; //退出按钮监听 | ||
| 34 | -// private ClickListener leftClickListener; //左边按钮监听 | ||
| 35 | -// private ClickListener rightClickListener; //右边按钮监听 | ||
| 36 | -// | ||
| 37 | -// public void setTypeLisenter(TypeListener typeLisenter) { | ||
| 38 | -// this.typeLisenter = typeLisenter; | ||
| 39 | -// } | ||
| 40 | -// | ||
| 41 | -// public void setCaptureLisenter(CaptureListener captureLisenter) { | ||
| 42 | -// this.captureLisenter = captureLisenter; | ||
| 43 | -// } | ||
| 44 | -// | ||
| 45 | -// public void setReturnLisenter(ReturnListener returnListener) { | ||
| 46 | -// this.returnListener = returnListener; | ||
| 47 | -// } | ||
| 48 | -// | ||
| 49 | -// private CaptureButton btn_capture; //拍照按钮 | ||
| 50 | -// private TypeButton btn_confirm; //确认按钮 | ||
| 51 | -// private TypeButton btn_cancel; //取消按钮 | ||
| 52 | -// private ReturnButton btn_return; //返回按钮 | ||
| 53 | -// private ImageView iv_custom_left; //左边自定义按钮 | ||
| 54 | -// private ImageView iv_custom_right; //右边自定义按钮 | ||
| 55 | -// private TextView txt_tip; //提示文本 | ||
| 56 | -// | ||
| 57 | -// private int layout_width; | ||
| 58 | -// private int layout_height; | ||
| 59 | -// private int button_size; | ||
| 60 | -// private int iconLeft = 0; | ||
| 61 | -// private int iconRight = 0; | ||
| 62 | -// | ||
| 63 | -// private boolean isFirst = true; | ||
| 64 | -// | ||
| 65 | -// public CaptureLayout(Context context) { | ||
| 66 | -// this(context, null); | ||
| 67 | -// } | ||
| 68 | -// | ||
| 69 | -// public CaptureLayout(Context context, AttributeSet attrs) { | ||
| 70 | -// this(context, attrs, 0); | ||
| 71 | -// } | ||
| 72 | -// | ||
| 73 | -// public CaptureLayout(Context context, AttributeSet attrs, int defStyleAttr) { | ||
| 74 | -// super(context, attrs, defStyleAttr); | ||
| 75 | -// if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { | ||
| 76 | -// layout_width = dip2px(250); | ||
| 77 | -// } else { | ||
| 78 | -// layout_width = dip2px(250); | ||
| 79 | -// } | ||
| 80 | -// layout_height = dip2px(150); | ||
| 81 | -// button_size = dip2px(50); | ||
| 82 | -// initView(); | ||
| 83 | -// initEvent(); | ||
| 84 | -// } | ||
| 85 | -// | ||
| 86 | -// @Override | ||
| 87 | -// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 88 | -// super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 89 | -// setMeasuredDimension(layout_width, layout_height); | ||
| 90 | -// } | ||
| 91 | -// | ||
| 92 | -// public void initEvent() { | ||
| 93 | -// iv_custom_right.setVisibility(GONE); | ||
| 94 | -// btn_cancel.setVisibility(GONE); | ||
| 95 | -// btn_confirm.setVisibility(GONE); | ||
| 96 | -// } | ||
| 97 | -// | ||
| 98 | -// public void startTypeBtnAnimator() { | ||
| 99 | -// if (checkErrorState()) return; | ||
| 100 | -// //拍照录制结果后的动画 | ||
| 101 | -// if (this.iconLeft != 0) | ||
| 102 | -// iv_custom_left.setVisibility(GONE); | ||
| 103 | -// else | ||
| 104 | -// btn_return.setVisibility(GONE); | ||
| 105 | -// if (this.iconRight != 0) | ||
| 106 | -// iv_custom_right.setVisibility(GONE); | ||
| 107 | -// btn_capture.setVisibility(GONE); | ||
| 108 | -// btn_cancel.setVisibility(VISIBLE); | ||
| 109 | -// btn_confirm.setVisibility(VISIBLE); | ||
| 110 | -// btn_cancel.setClickable(false); | ||
| 111 | -// btn_confirm.setClickable(false); | ||
| 112 | -// ObjectAnimator animator_cancel = ObjectAnimator.ofFloat(btn_cancel, "translationX", layout_width / 4, 0); | ||
| 113 | -// ObjectAnimator animator_confirm = ObjectAnimator.ofFloat(btn_confirm, "translationX", -layout_width / 4, 0); | ||
| 114 | -// | ||
| 115 | -// AnimatorSet set = new AnimatorSet(); | ||
| 116 | -// set.playTogether(animator_cancel, animator_confirm); | ||
| 117 | -// set.addListener(new AnimatorListenerAdapter() { | ||
| 118 | -// @Override | ||
| 119 | -// public void onAnimationEnd(Animator animation) { | ||
| 120 | -// super.onAnimationEnd(animation); | ||
| 121 | -// btn_cancel.setClickable(true); | ||
| 122 | -// btn_confirm.setClickable(true); | ||
| 123 | -// } | ||
| 124 | -// }); | ||
| 125 | -// set.setDuration(200); | ||
| 126 | -// set.start(); | ||
| 127 | -// } | ||
| 128 | -// private void initView() { | ||
| 129 | -// setWillNotDraw(false); | ||
| 130 | -// //拍照按钮 | ||
| 131 | -// btn_capture = new CaptureButton(getContext(), button_size); | ||
| 132 | -// LayoutParams btn_capture_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 133 | -// btn_capture_param.gravity = Gravity.CENTER; | ||
| 134 | -// // btn_capture_param.setMargins(0,0,0,dip2px(-4)); | ||
| 135 | -// btn_capture.setLayoutParams(btn_capture_param); | ||
| 136 | -// btn_capture.setCaptureLisenter(new CaptureListener() { | ||
| 137 | -// @Override | ||
| 138 | -// public void takePictures() { | ||
| 139 | -// if (DoublePressed.onDoublePressed()) return; | ||
| 140 | -// btn_return.setClickable(false); | ||
| 141 | -// if (captureLisenter != null) { | ||
| 142 | -// captureLisenter.takePictures(); | ||
| 143 | -// } | ||
| 144 | -// } | ||
| 145 | -// | ||
| 146 | -// @Override | ||
| 147 | -// public void recordShort(long time) { | ||
| 148 | -// btn_return.setClickable(true); | ||
| 149 | -// if (captureLisenter != null) { | ||
| 150 | -// captureLisenter.recordShort(time); | ||
| 151 | -// } | ||
| 152 | -// startAlphaAnimation(); | ||
| 153 | -// } | ||
| 154 | -// | ||
| 155 | -// @Override | ||
| 156 | -// public void recordStart() { | ||
| 157 | -// btn_return.setClickable(false); | ||
| 158 | -// if (captureLisenter != null) { | ||
| 159 | -// captureLisenter.recordStart(); | ||
| 160 | -// } | ||
| 161 | -// startAlphaAnimation(); | ||
| 162 | -// } | ||
| 163 | -// | ||
| 164 | -// @Override | ||
| 165 | -// public void recordEnd(long time) { | ||
| 166 | -// if (captureLisenter != null) { | ||
| 167 | -// captureLisenter.recordEnd(time); | ||
| 168 | -// } | ||
| 169 | -// startAlphaAnimation(); | ||
| 170 | -// startTypeBtnAnimator(); | ||
| 171 | -// } | ||
| 172 | -// | ||
| 173 | -// @Override | ||
| 174 | -// public void recordZoom(float zoom) { | ||
| 175 | -// if (captureLisenter != null) { | ||
| 176 | -// captureLisenter.recordZoom(zoom); | ||
| 177 | -// } | ||
| 178 | -// } | ||
| 179 | -// | ||
| 180 | -// @Override | ||
| 181 | -// public void recordError() { | ||
| 182 | -// if (captureLisenter != null) { | ||
| 183 | -// captureLisenter.recordError(); | ||
| 184 | -// } | ||
| 185 | -// } | ||
| 186 | -// }); | ||
| 187 | -// | ||
| 188 | -// //取消按钮 | ||
| 189 | -// btn_cancel = new TypeButton(getContext(), TypeButton.TYPE_CANCEL, button_size); | ||
| 190 | -// final LayoutParams btn_cancel_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 191 | -// btn_cancel_param.gravity = Gravity.CENTER_VERTICAL; | ||
| 192 | -// btn_cancel_param.setMargins(dip2px(200), 0, 0, 0); | ||
| 193 | -// btn_cancel.setLayoutParams(btn_cancel_param); | ||
| 194 | -// btn_cancel.setOnClickListener(new OnClickListener() { | ||
| 195 | -// @Override | ||
| 196 | -// public void onClick(View view) { | ||
| 197 | -// if (typeLisenter != null) { | ||
| 198 | -// typeLisenter.cancel(); | ||
| 199 | -// } | ||
| 200 | -// } | ||
| 201 | -// }); | ||
| 202 | -// | ||
| 203 | -// | ||
| 204 | -// //确认按钮 | ||
| 205 | -// btn_confirm = new TypeButton(getContext(), TypeButton.TYPE_CONFIRM, button_size); | ||
| 206 | -// LayoutParams btn_confirm_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 207 | -// btn_confirm_param.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; | ||
| 208 | -// btn_confirm_param.setMargins(0, 0, dip2px(200), 0); | ||
| 209 | -// btn_confirm.setLayoutParams(btn_confirm_param); | ||
| 210 | -// btn_confirm.setOnClickListener(new OnClickListener() { | ||
| 211 | -// @Override | ||
| 212 | -// public void onClick(View view) { | ||
| 213 | -// if (typeLisenter != null) { | ||
| 214 | -// typeLisenter.confirm(); | ||
| 215 | -// } | ||
| 216 | -// startAlphaAnimation(); | ||
| 217 | -// } | ||
| 218 | -// }); | ||
| 219 | -// | ||
| 220 | -// //返回按钮 | ||
| 221 | -// btn_return = new ReturnButton(getContext(), (int) (button_size / 2.5f)); | ||
| 222 | -// btn_return.setPadding(5,5,5,5); | ||
| 223 | -// LayoutParams btn_return_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 224 | -// btn_return_param.gravity = Gravity.CENTER_VERTICAL; | ||
| 225 | -// btn_cancel_param.height = 100; | ||
| 226 | -// btn_cancel_param.width = 100; | ||
| 227 | -// btn_return_param.setMargins(layout_width / 6, 0, 0, dip2px(-4)); | ||
| 228 | -// btn_return.setLayoutParams(btn_return_param); | ||
| 229 | -// btn_return.setOnClickListener(new OnClickListener() { | ||
| 230 | -// @Override | ||
| 231 | -// public void onClick(View v) { | ||
| 232 | -// if (leftClickListener != null) { | ||
| 233 | -// leftClickListener.onClick(); | ||
| 234 | -// } | ||
| 235 | -// } | ||
| 236 | -// }); | ||
| 237 | -// //左边自定义按钮 | ||
| 238 | -// iv_custom_left = new ImageView(getContext()); | ||
| 239 | -// LayoutParams iv_custom_param_left = new LayoutParams((int) (button_size / 2.5f), (int) (button_size / 2.5f)); | ||
| 240 | -// iv_custom_param_left.gravity = Gravity.CENTER_VERTICAL; | ||
| 241 | -// iv_custom_param_left.setMargins(layout_width / 6, 0, 0, 0); | ||
| 242 | -// iv_custom_left.setLayoutParams(iv_custom_param_left); | ||
| 243 | -// iv_custom_left.setOnClickListener(new OnClickListener() { | ||
| 244 | -// @Override | ||
| 245 | -// public void onClick(View v) { | ||
| 246 | -// if (leftClickListener != null) { | ||
| 247 | -// leftClickListener.onClick(); | ||
| 248 | -// } | ||
| 249 | -// } | ||
| 250 | -// }); | ||
| 251 | -// | ||
| 252 | -// //右边自定义按钮 | ||
| 253 | -// iv_custom_right = new ImageView(getContext()); | ||
| 254 | -// LayoutParams iv_custom_param_right = new LayoutParams((int) (button_size / 2.5f), (int) (button_size / 2.5f)); | ||
| 255 | -// iv_custom_param_right.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; | ||
| 256 | -// iv_custom_param_right.setMargins(0, 0, layout_width / 6, 0); | ||
| 257 | -// iv_custom_right.setLayoutParams(iv_custom_param_right); | ||
| 258 | -// iv_custom_right.setOnClickListener(new OnClickListener() { | ||
| 259 | -// @Override | ||
| 260 | -// public void onClick(View v) { | ||
| 261 | -// if (rightClickListener != null) { | ||
| 262 | -// rightClickListener.onClick(); | ||
| 263 | -// } | ||
| 264 | -// } | ||
| 265 | -// }); | ||
| 266 | -// | ||
| 267 | -// txt_tip = new TextView(getContext()); | ||
| 268 | -// LayoutParams txt_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); | ||
| 269 | -// txt_param.gravity = Gravity.CENTER_HORIZONTAL; | ||
| 270 | -// txt_param.setMargins(0, 0, 0, 0); | ||
| 271 | -// txt_tip.setPadding(0, 0, 0, 50); | ||
| 272 | -// txt_tip.setTextColor(0xFFFFFFFF); | ||
| 273 | -// txt_tip.setGravity(Gravity.CENTER); | ||
| 274 | -// txt_tip.setLayoutParams(txt_param); | ||
| 275 | -// | ||
| 276 | -// this.addView(btn_capture); | ||
| 277 | -// this.addView(btn_cancel); | ||
| 278 | -// this.addView(btn_confirm); | ||
| 279 | -// this.addView(btn_return); | ||
| 280 | -// this.addView(iv_custom_left); | ||
| 281 | -// this.addView(iv_custom_right); | ||
| 282 | -// this.addView(txt_tip); | ||
| 283 | -// } | ||
| 284 | -// | ||
| 285 | -// public static int dip2px(float dipValue) { | ||
| 286 | -// float scale = Resources.getSystem().getDisplayMetrics().density; | ||
| 287 | -// return (int) (dipValue * scale + 0.5F); | ||
| 288 | -// } | ||
| 289 | -// public void resetCaptureLayout() { | ||
| 290 | -// btn_capture.resetRecordAnim(); | ||
| 291 | -// btn_capture.resetState(); | ||
| 292 | -// btn_cancel.setVisibility(GONE); | ||
| 293 | -// btn_confirm.setVisibility(GONE); | ||
| 294 | -// btn_capture.setVisibility(VISIBLE); | ||
| 295 | -// if (this.iconLeft != 0) | ||
| 296 | -// iv_custom_left.setVisibility(VISIBLE); | ||
| 297 | -// else { | ||
| 298 | -// btn_return.setClickable(true); | ||
| 299 | -// btn_return.setVisibility(VISIBLE); | ||
| 300 | -// } | ||
| 301 | -// if (this.iconRight != 0) | ||
| 302 | -// iv_custom_right.setVisibility(VISIBLE); | ||
| 303 | -// } | ||
| 304 | -// | ||
| 305 | -// private boolean checkErrorState() { | ||
| 306 | -// if (isErrorState) { | ||
| 307 | -// isErrorState = false; | ||
| 308 | -// return true; | ||
| 309 | -// } | ||
| 310 | -// return false; | ||
| 311 | -// } | ||
| 312 | -// | ||
| 313 | -// public void onError() { | ||
| 314 | -// onError(false); | ||
| 315 | -// } | ||
| 316 | -// | ||
| 317 | -// public void onError(boolean state) { | ||
| 318 | -// isErrorState = state; | ||
| 319 | -// btn_return.setClickable(true); | ||
| 320 | -// } | ||
| 321 | -// | ||
| 322 | -// public void startAlphaAnimation() { | ||
| 323 | -// if (isFirst) { | ||
| 324 | -// ObjectAnimator animator_txt_tip = ObjectAnimator.ofFloat(txt_tip, "alpha", 1f, 0f); | ||
| 325 | -// animator_txt_tip.setDuration(500); | ||
| 326 | -// animator_txt_tip.start(); | ||
| 327 | -// isFirst = false; | ||
| 328 | -// } | ||
| 329 | -// } | ||
| 330 | -// | ||
| 331 | -// public void setTextWithAnimation(String tip) { | ||
| 332 | -// txt_tip.setText(tip); | ||
| 333 | -// ObjectAnimator animator_txt_tip = ObjectAnimator.ofFloat(txt_tip, "alpha", 0f, 1f, 1f, 0f); | ||
| 334 | -// animator_txt_tip.setDuration(2500); | ||
| 335 | -// animator_txt_tip.start(); | ||
| 336 | -// } | ||
| 337 | -// | ||
| 338 | -// public void setDuration(int duration) { | ||
| 339 | -// btn_capture.setDuration(duration); | ||
| 340 | -// } | ||
| 341 | -// | ||
| 342 | -// public void setButtonFeatures(int state) { | ||
| 343 | -// if (state == BUTTON_STATE_BOTH) { | ||
| 344 | -// txt_tip.setText("轻触拍照,长按摄像"); | ||
| 345 | -// } else if (state == BUTTON_STATE_ONLY_CAPTURE) { | ||
| 346 | -// txt_tip.setText("轻触拍照"); | ||
| 347 | -// } else if (state == BUTTON_STATE_ONLY_RECORDER) { | ||
| 348 | -// txt_tip.setText("长按摄像"); | ||
| 349 | -// } | ||
| 350 | -// btn_capture.setButtonFeatures(state); | ||
| 351 | -// } | ||
| 352 | -// | ||
| 353 | -// public void setTip(String tip) { | ||
| 354 | -// txt_tip.setText(tip); | ||
| 355 | -// } | ||
| 356 | -// | ||
| 357 | -// public void showTip() { | ||
| 358 | -// txt_tip.setVisibility(VISIBLE); | ||
| 359 | -// } | ||
| 360 | -// | ||
| 361 | -// public void setIconSrc(int iconLeft, int iconRight) { | ||
| 362 | -// this.iconLeft = iconLeft; | ||
| 363 | -// this.iconRight = iconRight; | ||
| 364 | -// if (this.iconLeft != 0) { | ||
| 365 | -// iv_custom_left.setImageResource(iconLeft); | ||
| 366 | -// iv_custom_left.setVisibility(VISIBLE); | ||
| 367 | -// btn_return.setVisibility(GONE); | ||
| 368 | -// } else { | ||
| 369 | -// iv_custom_left.setVisibility(GONE); | ||
| 370 | -// btn_return.setClickable(true); | ||
| 371 | -// btn_return.setVisibility(VISIBLE); | ||
| 372 | -// } | ||
| 373 | -// if (this.iconRight != 0) { | ||
| 374 | -// iv_custom_right.setImageResource(iconRight); | ||
| 375 | -// iv_custom_right.setVisibility(VISIBLE); | ||
| 376 | -// } else { | ||
| 377 | -// iv_custom_right.setVisibility(GONE); | ||
| 378 | -// } | ||
| 379 | -// } | ||
| 380 | -// | ||
| 381 | -// public void setLeftClickListener(ClickListener leftClickListener) { | ||
| 382 | -// this.leftClickListener = leftClickListener; | ||
| 383 | -// } | ||
| 384 | -// | ||
| 385 | -// public void setRightClickListener(ClickListener rightClickListener) { | ||
| 386 | -// this.rightClickListener = rightClickListener; | ||
| 387 | -// } | ||
| 388 | -//} | 1 | +package com.cnlive.media.ui.widget.record; |
| 2 | + | ||
| 3 | +import static com.cnlive.media.ui.widget.record.CaptureButton.BUTTON_STATE_BOTH; | ||
| 4 | +import static com.cnlive.media.ui.widget.record.CaptureButton.BUTTON_STATE_ONLY_CAPTURE; | ||
| 5 | +import static com.cnlive.media.ui.widget.record.CaptureButton.BUTTON_STATE_ONLY_RECORDER; | ||
| 6 | + | ||
| 7 | +import android.animation.Animator; | ||
| 8 | +import android.animation.AnimatorListenerAdapter; | ||
| 9 | +import android.animation.AnimatorSet; | ||
| 10 | +import android.animation.ObjectAnimator; | ||
| 11 | +import android.content.Context; | ||
| 12 | +import android.content.res.Configuration; | ||
| 13 | +import android.content.res.Resources; | ||
| 14 | +import android.util.AttributeSet; | ||
| 15 | +import android.view.Gravity; | ||
| 16 | +import android.view.View; | ||
| 17 | +import android.widget.FrameLayout; | ||
| 18 | +import android.widget.ImageView; | ||
| 19 | +import android.widget.TextView; | ||
| 20 | + | ||
| 21 | +import com.cnlive.libs.base.util.DoublePressed; | ||
| 22 | +import com.cnlive.media.ui.widget.record.listener.CaptureListener; | ||
| 23 | +import com.cnlive.media.ui.widget.record.listener.ClickListener; | ||
| 24 | +import com.cnlive.media.ui.widget.record.listener.ReturnListener; | ||
| 25 | +import com.cnlive.media.ui.widget.record.listener.TypeListener; | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +public class CaptureLayout extends FrameLayout { | ||
| 29 | + private boolean isErrorState = false; | ||
| 30 | + private CaptureListener captureLisenter; //拍照按钮监听 | ||
| 31 | + private TypeListener typeLisenter; //拍照或录制后接结果按钮监听 | ||
| 32 | + private ReturnListener returnListener; //退出按钮监听 | ||
| 33 | + private ClickListener leftClickListener; //左边按钮监听 | ||
| 34 | + private ClickListener rightClickListener; //右边按钮监听 | ||
| 35 | + | ||
| 36 | + public void setTypeLisenter(TypeListener typeLisenter) { | ||
| 37 | + this.typeLisenter = typeLisenter; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public void setCaptureLisenter(CaptureListener captureLisenter) { | ||
| 41 | + this.captureLisenter = captureLisenter; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public void setReturnLisenter(ReturnListener returnListener) { | ||
| 45 | + this.returnListener = returnListener; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + private CaptureButton btn_capture; //拍照按钮 | ||
| 49 | + private TypeButton btn_confirm; //确认按钮 | ||
| 50 | + private TypeButton btn_cancel; //取消按钮 | ||
| 51 | + private ReturnButton btn_return; //返回按钮 | ||
| 52 | + private ImageView iv_custom_left; //左边自定义按钮 | ||
| 53 | + private ImageView iv_custom_right; //右边自定义按钮 | ||
| 54 | + private TextView txt_tip; //提示文本 | ||
| 55 | + | ||
| 56 | + private int layout_width; | ||
| 57 | + private int layout_height; | ||
| 58 | + private int button_size; | ||
| 59 | + private int iconLeft = 0; | ||
| 60 | + private int iconRight = 0; | ||
| 61 | + | ||
| 62 | + private boolean isFirst = true; | ||
| 63 | + | ||
| 64 | + public CaptureLayout(Context context) { | ||
| 65 | + this(context, null); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + public CaptureLayout(Context context, AttributeSet attrs) { | ||
| 69 | + this(context, attrs, 0); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + public CaptureLayout(Context context, AttributeSet attrs, int defStyleAttr) { | ||
| 73 | + super(context, attrs, defStyleAttr); | ||
| 74 | + if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { | ||
| 75 | + layout_width = dip2px(250); | ||
| 76 | + } else { | ||
| 77 | + layout_width = dip2px(250); | ||
| 78 | + } | ||
| 79 | + layout_height = dip2px(150); | ||
| 80 | + button_size = dip2px(50); | ||
| 81 | + initView(); | ||
| 82 | + initEvent(); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + @Override | ||
| 86 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 87 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 88 | + setMeasuredDimension(layout_width, layout_height); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + public void initEvent() { | ||
| 92 | + iv_custom_right.setVisibility(GONE); | ||
| 93 | + btn_cancel.setVisibility(GONE); | ||
| 94 | + btn_confirm.setVisibility(GONE); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public void startTypeBtnAnimator() { | ||
| 98 | + if (checkErrorState()) return; | ||
| 99 | + //拍照录制结果后的动画 | ||
| 100 | + if (this.iconLeft != 0) | ||
| 101 | + iv_custom_left.setVisibility(GONE); | ||
| 102 | + else | ||
| 103 | + btn_return.setVisibility(GONE); | ||
| 104 | + if (this.iconRight != 0) | ||
| 105 | + iv_custom_right.setVisibility(GONE); | ||
| 106 | + btn_capture.setVisibility(GONE); | ||
| 107 | + btn_cancel.setVisibility(VISIBLE); | ||
| 108 | + btn_confirm.setVisibility(VISIBLE); | ||
| 109 | + btn_cancel.setClickable(false); | ||
| 110 | + btn_confirm.setClickable(false); | ||
| 111 | + ObjectAnimator animator_cancel = ObjectAnimator.ofFloat(btn_cancel, "translationX", layout_width / 4, 0); | ||
| 112 | + ObjectAnimator animator_confirm = ObjectAnimator.ofFloat(btn_confirm, "translationX", -layout_width / 4, 0); | ||
| 113 | + | ||
| 114 | + AnimatorSet set = new AnimatorSet(); | ||
| 115 | + set.playTogether(animator_cancel, animator_confirm); | ||
| 116 | + set.addListener(new AnimatorListenerAdapter() { | ||
| 117 | + @Override | ||
| 118 | + public void onAnimationEnd(Animator animation) { | ||
| 119 | + super.onAnimationEnd(animation); | ||
| 120 | + btn_cancel.setClickable(true); | ||
| 121 | + btn_confirm.setClickable(true); | ||
| 122 | + } | ||
| 123 | + }); | ||
| 124 | + set.setDuration(200); | ||
| 125 | + set.start(); | ||
| 126 | + } | ||
| 127 | + private void initView() { | ||
| 128 | + setWillNotDraw(false); | ||
| 129 | + //拍照按钮 | ||
| 130 | + btn_capture = new CaptureButton(getContext(), button_size); | ||
| 131 | + LayoutParams btn_capture_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 132 | + btn_capture_param.gravity = Gravity.CENTER; | ||
| 133 | + // btn_capture_param.setMargins(0,0,0,dip2px(-4)); | ||
| 134 | + btn_capture.setLayoutParams(btn_capture_param); | ||
| 135 | + btn_capture.setCaptureLisenter(new CaptureListener() { | ||
| 136 | + @Override | ||
| 137 | + public void takePictures() { | ||
| 138 | + if (DoublePressed.onDoublePressed()) return; | ||
| 139 | + btn_return.setClickable(false); | ||
| 140 | + if (captureLisenter != null) { | ||
| 141 | + captureLisenter.takePictures(); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + @Override | ||
| 146 | + public void recordShort(long time) { | ||
| 147 | + btn_return.setClickable(true); | ||
| 148 | + if (captureLisenter != null) { | ||
| 149 | + captureLisenter.recordShort(time); | ||
| 150 | + } | ||
| 151 | + startAlphaAnimation(); | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + @Override | ||
| 155 | + public void recordStart() { | ||
| 156 | + btn_return.setClickable(false); | ||
| 157 | + if (captureLisenter != null) { | ||
| 158 | + captureLisenter.recordStart(); | ||
| 159 | + } | ||
| 160 | + startAlphaAnimation(); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + @Override | ||
| 164 | + public void recordEnd(long time) { | ||
| 165 | + if (captureLisenter != null) { | ||
| 166 | + captureLisenter.recordEnd(time); | ||
| 167 | + } | ||
| 168 | + startAlphaAnimation(); | ||
| 169 | + startTypeBtnAnimator(); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + @Override | ||
| 173 | + public void recordZoom(float zoom) { | ||
| 174 | + if (captureLisenter != null) { | ||
| 175 | + captureLisenter.recordZoom(zoom); | ||
| 176 | + } | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + @Override | ||
| 180 | + public void recordError() { | ||
| 181 | + if (captureLisenter != null) { | ||
| 182 | + captureLisenter.recordError(); | ||
| 183 | + } | ||
| 184 | + } | ||
| 185 | + }); | ||
| 186 | + | ||
| 187 | + //取消按钮 | ||
| 188 | + btn_cancel = new TypeButton(getContext(), TypeButton.TYPE_CANCEL, button_size); | ||
| 189 | + final LayoutParams btn_cancel_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 190 | + btn_cancel_param.gravity = Gravity.CENTER_VERTICAL; | ||
| 191 | + btn_cancel_param.setMargins(dip2px(200), 0, 0, 0); | ||
| 192 | + btn_cancel.setLayoutParams(btn_cancel_param); | ||
| 193 | + btn_cancel.setOnClickListener(new OnClickListener() { | ||
| 194 | + @Override | ||
| 195 | + public void onClick(View view) { | ||
| 196 | + if (typeLisenter != null) { | ||
| 197 | + typeLisenter.cancel(); | ||
| 198 | + } | ||
| 199 | + } | ||
| 200 | + }); | ||
| 201 | + | ||
| 202 | + | ||
| 203 | + //确认按钮 | ||
| 204 | + btn_confirm = new TypeButton(getContext(), TypeButton.TYPE_CONFIRM, button_size); | ||
| 205 | + LayoutParams btn_confirm_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 206 | + btn_confirm_param.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; | ||
| 207 | + btn_confirm_param.setMargins(0, 0, dip2px(200), 0); | ||
| 208 | + btn_confirm.setLayoutParams(btn_confirm_param); | ||
| 209 | + btn_confirm.setOnClickListener(new OnClickListener() { | ||
| 210 | + @Override | ||
| 211 | + public void onClick(View view) { | ||
| 212 | + if (typeLisenter != null) { | ||
| 213 | + typeLisenter.confirm(); | ||
| 214 | + } | ||
| 215 | + startAlphaAnimation(); | ||
| 216 | + } | ||
| 217 | + }); | ||
| 218 | + | ||
| 219 | + //返回按钮 | ||
| 220 | + btn_return = new ReturnButton(getContext(), (int) (button_size / 2.5f)); | ||
| 221 | + btn_return.setPadding(5,5,5,5); | ||
| 222 | + LayoutParams btn_return_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 223 | + btn_return_param.gravity = Gravity.CENTER_VERTICAL; | ||
| 224 | + btn_cancel_param.height = 100; | ||
| 225 | + btn_cancel_param.width = 100; | ||
| 226 | + btn_return_param.setMargins(layout_width / 6, 0, 0, dip2px(-4)); | ||
| 227 | + btn_return.setLayoutParams(btn_return_param); | ||
| 228 | + btn_return.setOnClickListener(new OnClickListener() { | ||
| 229 | + @Override | ||
| 230 | + public void onClick(View v) { | ||
| 231 | + if (leftClickListener != null) { | ||
| 232 | + leftClickListener.onClick(); | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + }); | ||
| 236 | + //左边自定义按钮 | ||
| 237 | + iv_custom_left = new ImageView(getContext()); | ||
| 238 | + LayoutParams iv_custom_param_left = new LayoutParams((int) (button_size / 2.5f), (int) (button_size / 2.5f)); | ||
| 239 | + iv_custom_param_left.gravity = Gravity.CENTER_VERTICAL; | ||
| 240 | + iv_custom_param_left.setMargins(layout_width / 6, 0, 0, 0); | ||
| 241 | + iv_custom_left.setLayoutParams(iv_custom_param_left); | ||
| 242 | + iv_custom_left.setOnClickListener(new OnClickListener() { | ||
| 243 | + @Override | ||
| 244 | + public void onClick(View v) { | ||
| 245 | + if (leftClickListener != null) { | ||
| 246 | + leftClickListener.onClick(); | ||
| 247 | + } | ||
| 248 | + } | ||
| 249 | + }); | ||
| 250 | + | ||
| 251 | + //右边自定义按钮 | ||
| 252 | + iv_custom_right = new ImageView(getContext()); | ||
| 253 | + LayoutParams iv_custom_param_right = new LayoutParams((int) (button_size / 2.5f), (int) (button_size / 2.5f)); | ||
| 254 | + iv_custom_param_right.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; | ||
| 255 | + iv_custom_param_right.setMargins(0, 0, layout_width / 6, 0); | ||
| 256 | + iv_custom_right.setLayoutParams(iv_custom_param_right); | ||
| 257 | + iv_custom_right.setOnClickListener(new OnClickListener() { | ||
| 258 | + @Override | ||
| 259 | + public void onClick(View v) { | ||
| 260 | + if (rightClickListener != null) { | ||
| 261 | + rightClickListener.onClick(); | ||
| 262 | + } | ||
| 263 | + } | ||
| 264 | + }); | ||
| 265 | + | ||
| 266 | + txt_tip = new TextView(getContext()); | ||
| 267 | + LayoutParams txt_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); | ||
| 268 | + txt_param.gravity = Gravity.CENTER_HORIZONTAL; | ||
| 269 | + txt_param.setMargins(0, 0, 0, 0); | ||
| 270 | + txt_tip.setPadding(0, 0, 0, 50); | ||
| 271 | + txt_tip.setTextColor(0xFFFFFFFF); | ||
| 272 | + txt_tip.setGravity(Gravity.CENTER); | ||
| 273 | + txt_tip.setLayoutParams(txt_param); | ||
| 274 | + | ||
| 275 | + this.addView(btn_capture); | ||
| 276 | + this.addView(btn_cancel); | ||
| 277 | + this.addView(btn_confirm); | ||
| 278 | + this.addView(btn_return); | ||
| 279 | + this.addView(iv_custom_left); | ||
| 280 | + this.addView(iv_custom_right); | ||
| 281 | + this.addView(txt_tip); | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + public static int dip2px(float dipValue) { | ||
| 285 | + float scale = Resources.getSystem().getDisplayMetrics().density; | ||
| 286 | + return (int) (dipValue * scale + 0.5F); | ||
| 287 | + } | ||
| 288 | + public void resetCaptureLayout() { | ||
| 289 | + btn_capture.resetRecordAnim(); | ||
| 290 | + btn_capture.resetState(); | ||
| 291 | + btn_cancel.setVisibility(GONE); | ||
| 292 | + btn_confirm.setVisibility(GONE); | ||
| 293 | + btn_capture.setVisibility(VISIBLE); | ||
| 294 | + if (this.iconLeft != 0) | ||
| 295 | + iv_custom_left.setVisibility(VISIBLE); | ||
| 296 | + else { | ||
| 297 | + btn_return.setClickable(true); | ||
| 298 | + btn_return.setVisibility(VISIBLE); | ||
| 299 | + } | ||
| 300 | + if (this.iconRight != 0) | ||
| 301 | + iv_custom_right.setVisibility(VISIBLE); | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + private boolean checkErrorState() { | ||
| 305 | + if (isErrorState) { | ||
| 306 | + isErrorState = false; | ||
| 307 | + return true; | ||
| 308 | + } | ||
| 309 | + return false; | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + public void onError() { | ||
| 313 | + onError(false); | ||
| 314 | + } | ||
| 315 | + | ||
| 316 | + public void onError(boolean state) { | ||
| 317 | + isErrorState = state; | ||
| 318 | + btn_return.setClickable(true); | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + public void startAlphaAnimation() { | ||
| 322 | + if (isFirst) { | ||
| 323 | + ObjectAnimator animator_txt_tip = ObjectAnimator.ofFloat(txt_tip, "alpha", 1f, 0f); | ||
| 324 | + animator_txt_tip.setDuration(500); | ||
| 325 | + animator_txt_tip.start(); | ||
| 326 | + isFirst = false; | ||
| 327 | + } | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + public void setTextWithAnimation(String tip) { | ||
| 331 | + txt_tip.setText(tip); | ||
| 332 | + ObjectAnimator animator_txt_tip = ObjectAnimator.ofFloat(txt_tip, "alpha", 0f, 1f, 1f, 0f); | ||
| 333 | + animator_txt_tip.setDuration(2500); | ||
| 334 | + animator_txt_tip.start(); | ||
| 335 | + } | ||
| 336 | + | ||
| 337 | + public void setDuration(int duration) { | ||
| 338 | + btn_capture.setDuration(duration); | ||
| 339 | + } | ||
| 340 | + | ||
| 341 | + public void setButtonFeatures(int state) { | ||
| 342 | + if (state == BUTTON_STATE_BOTH) { | ||
| 343 | + txt_tip.setText("轻触拍照,长按摄像"); | ||
| 344 | + } else if (state == BUTTON_STATE_ONLY_CAPTURE) { | ||
| 345 | + txt_tip.setText("轻触拍照"); | ||
| 346 | + } else if (state == BUTTON_STATE_ONLY_RECORDER) { | ||
| 347 | + txt_tip.setText("长按摄像"); | ||
| 348 | + } | ||
| 349 | + btn_capture.setButtonFeatures(state); | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + public void setTip(String tip) { | ||
| 353 | + txt_tip.setText(tip); | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + public void showTip() { | ||
| 357 | + txt_tip.setVisibility(VISIBLE); | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + public void setIconSrc(int iconLeft, int iconRight) { | ||
| 361 | + this.iconLeft = iconLeft; | ||
| 362 | + this.iconRight = iconRight; | ||
| 363 | + if (this.iconLeft != 0) { | ||
| 364 | + iv_custom_left.setImageResource(iconLeft); | ||
| 365 | + iv_custom_left.setVisibility(VISIBLE); | ||
| 366 | + btn_return.setVisibility(GONE); | ||
| 367 | + } else { | ||
| 368 | + iv_custom_left.setVisibility(GONE); | ||
| 369 | + btn_return.setClickable(true); | ||
| 370 | + btn_return.setVisibility(VISIBLE); | ||
| 371 | + } | ||
| 372 | + if (this.iconRight != 0) { | ||
| 373 | + iv_custom_right.setImageResource(iconRight); | ||
| 374 | + iv_custom_right.setVisibility(VISIBLE); | ||
| 375 | + } else { | ||
| 376 | + iv_custom_right.setVisibility(GONE); | ||
| 377 | + } | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + public void setLeftClickListener(ClickListener leftClickListener) { | ||
| 381 | + this.leftClickListener = leftClickListener; | ||
| 382 | + } | ||
| 383 | + | ||
| 384 | + public void setRightClickListener(ClickListener rightClickListener) { | ||
| 385 | + this.rightClickListener = rightClickListener; | ||
| 386 | + } | ||
| 387 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/JCameraView.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record; | ||
| 2 | + | ||
| 3 | +import android.animation.AnimatorSet; | ||
| 4 | +import android.animation.ObjectAnimator; | ||
| 5 | +import android.content.Context; | ||
| 6 | +import android.content.res.TypedArray; | ||
| 7 | +import android.graphics.Bitmap; | ||
| 8 | +import android.hardware.Camera; | ||
| 9 | +import android.media.AudioManager; | ||
| 10 | +import android.media.MediaPlayer; | ||
| 11 | +import android.os.Build; | ||
| 12 | +import android.util.AttributeSet; | ||
| 13 | +import android.util.Log; | ||
| 14 | +import android.util.TypedValue; | ||
| 15 | +import android.view.Gravity; | ||
| 16 | +import android.view.LayoutInflater; | ||
| 17 | +import android.view.MotionEvent; | ||
| 18 | +import android.view.SurfaceHolder; | ||
| 19 | +import android.view.View; | ||
| 20 | +import android.view.ViewGroup; | ||
| 21 | +import android.view.WindowManager; | ||
| 22 | +import android.widget.FrameLayout; | ||
| 23 | +import android.widget.ImageView; | ||
| 24 | +import android.widget.VideoView; | ||
| 25 | + | ||
| 26 | +import androidx.annotation.RequiresApi; | ||
| 27 | + | ||
| 28 | +import com.cnlive.libs.base.util.AlertUtil; | ||
| 29 | +import com.cnlive.media.R; | ||
| 30 | +import com.cnlive.media.ui.widget.record.listener.CaptureListener; | ||
| 31 | +import com.cnlive.media.ui.widget.record.listener.ClickListener; | ||
| 32 | +import com.cnlive.media.ui.widget.record.listener.ErrorListener; | ||
| 33 | +import com.cnlive.media.ui.widget.record.listener.JCameraListener; | ||
| 34 | +import com.cnlive.media.ui.widget.record.listener.TypeListener; | ||
| 35 | +import com.cnlive.media.ui.widget.record.state.CameraMachine; | ||
| 36 | +import com.cnlive.media.ui.widget.record.view.CameraView; | ||
| 37 | +import com.cnlive.media.utils.FileUtil; | ||
| 38 | +import com.cnlive.media.utils.LogUtil; | ||
| 39 | +import com.cnlive.media.utils.ScreenUtils; | ||
| 40 | + | ||
| 41 | + | ||
| 42 | +/** | ||
| 43 | + * ===================================== | ||
| 44 | + * 作 者: 陈嘉桐 | ||
| 45 | + * 版 本:1.0.4 | ||
| 46 | + * 创建日期:2017/4/25 | ||
| 47 | + * 描 述: | ||
| 48 | + * ===================================== | ||
| 49 | + */ | ||
| 50 | +public class JCameraView extends FrameLayout implements CameraInterface.CameraOpenOverCallback, SurfaceHolder | ||
| 51 | + .Callback, CameraView { | ||
| 52 | +// private static final String TAG = "JCameraView"; | ||
| 53 | + | ||
| 54 | + //Camera状态机 | ||
| 55 | + private CameraMachine machine; | ||
| 56 | + | ||
| 57 | + //闪关灯状态 | ||
| 58 | + // private static final int TYPE_FLASH_AUTO = 0x021; | ||
| 59 | + private static final int TYPE_FLASH_ON = 0x022; | ||
| 60 | + private static final int TYPE_FLASH_OFF = 0x023; | ||
| 61 | + private int type_flash = TYPE_FLASH_OFF; | ||
| 62 | + | ||
| 63 | + //拍照浏览时候的类型 | ||
| 64 | + public static final int TYPE_PICTURE = 0x001; | ||
| 65 | + public static final int TYPE_VIDEO = 0x002; | ||
| 66 | + public static final int TYPE_SHORT = 0x003; | ||
| 67 | + public static final int TYPE_DEFAULT = 0x004; | ||
| 68 | + | ||
| 69 | + //录制视频比特率 | ||
| 70 | + public static final int MEDIA_QUALITY_HIGH = 20 * 100000; | ||
| 71 | + public static final int MEDIA_QUALITY_MIDDLE = 16 * 100000; | ||
| 72 | + public static final int MEDIA_QUALITY_LOW = 12 * 100000; | ||
| 73 | + public static final int MEDIA_QUALITY_POOR = 8 * 100000; | ||
| 74 | + public static final int MEDIA_QUALITY_FUNNY = 4 * 100000; | ||
| 75 | + public static final int MEDIA_QUALITY_DESPAIR = 2 * 100000; | ||
| 76 | + public static final int MEDIA_QUALITY_SORRY = 1 * 80000; | ||
| 77 | + | ||
| 78 | + | ||
| 79 | + public static final int BUTTON_STATE_ONLY_CAPTURE = 0x101; //只能拍照 | ||
| 80 | + public static final int BUTTON_STATE_ONLY_RECORDER = 0x102; //只能录像 | ||
| 81 | + public static final int BUTTON_STATE_BOTH = 0x103; //两者都可以 | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + //回调监听 | ||
| 85 | + private JCameraListener jCameraLisenter; | ||
| 86 | + private ClickListener leftClickListener; | ||
| 87 | + private ClickListener rightClickListener; | ||
| 88 | + | ||
| 89 | + private VideoView mVideoView; | ||
| 90 | + private ImageView mPhoto; | ||
| 91 | + private ImageView mSwitchCamera; | ||
| 92 | + private ImageView mFlashLamp; | ||
| 93 | + private CaptureLayout mCaptureLayout; | ||
| 94 | + private FoucsView mFoucsView; | ||
| 95 | + private MediaPlayer mMediaPlayer; | ||
| 96 | + | ||
| 97 | + private int layout_width; | ||
| 98 | + private float screenProp = 0f; | ||
| 99 | + | ||
| 100 | + private Bitmap captureBitmap; //捕获的图片 | ||
| 101 | + private String videoUrl; //视频URL | ||
| 102 | + | ||
| 103 | + | ||
| 104 | + //切换摄像头按钮的参数 | ||
| 105 | + private int iconSize = 0; //图标大小 | ||
| 106 | + private int iconMargin = 0; //右上边距 | ||
| 107 | + private int iconSrc = 0; //图标资源 | ||
| 108 | + private int iconLeft = 0; //左图标 | ||
| 109 | + private int iconRight = 0; //右图标 | ||
| 110 | + private int duration = 0; //录制时间 | ||
| 111 | + | ||
| 112 | + //缩放梯度 | ||
| 113 | + private int zoomGradient = 0; | ||
| 114 | + | ||
| 115 | + private boolean firstTouch = true; | ||
| 116 | + private float firstTouchLength = 0; | ||
| 117 | + private boolean recordEnd = false; | ||
| 118 | + private long lastClick; | ||
| 119 | + private int id = Camera.CameraInfo.CAMERA_FACING_BACK; | ||
| 120 | + private boolean flashIsVisi = true; | ||
| 121 | + | ||
| 122 | + public JCameraView(Context context) { | ||
| 123 | + this(context, null); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + public JCameraView(Context context, AttributeSet attrs) { | ||
| 127 | + this(context, attrs, 0); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + public JCameraView(Context context, AttributeSet attrs, int defStyleAttr) { | ||
| 131 | + super(context, attrs, defStyleAttr); | ||
| 132 | + //get AttributeSet | ||
| 133 | + TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.JCameraView, defStyleAttr, 0); | ||
| 134 | + iconSize = a.getDimensionPixelSize(R.styleable.JCameraView_iconSize, (int) TypedValue.applyDimension( | ||
| 135 | + TypedValue.COMPLEX_UNIT_SP, 35, getResources().getDisplayMetrics())); | ||
| 136 | + iconMargin = a.getDimensionPixelSize(R.styleable.JCameraView_iconMargin, (int) TypedValue.applyDimension( | ||
| 137 | + TypedValue.COMPLEX_UNIT_SP, 15, getResources().getDisplayMetrics())); | ||
| 138 | + // iconSrc = a.getResourceId(R.styleable.JCameraView_iconSrc, R.drawable.fb_xiangji); | ||
| 139 | + iconLeft = a.getResourceId(R.styleable.JCameraView_iconLeft, 0); | ||
| 140 | + iconRight = a.getResourceId(R.styleable.JCameraView_iconRight, 0); | ||
| 141 | + duration = a.getInteger(R.styleable.JCameraView_duration_max, 10 * 1000); //没设置默认为10s | ||
| 142 | + a.recycle(); | ||
| 143 | + initData(); | ||
| 144 | + initView(); | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + private void initData() { | ||
| 148 | + layout_width = ScreenUtils.getScreenWidth(getContext()); | ||
| 149 | + //缩放梯度 | ||
| 150 | + zoomGradient = (int) (layout_width / 16f); | ||
| 151 | + LogUtil.i("zoom = " + zoomGradient); | ||
| 152 | + machine = new CameraMachine(getContext(), this, this); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + public int getScreenWidth() { | ||
| 156 | + WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); | ||
| 157 | + return wm == null ? 0 : wm.getDefaultDisplay().getWidth(); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + private long lastClickTime = 0L; | ||
| 161 | + private static final int FAST_CLICK_DELAY_TIME = 1000; // 快速点击间隔 | ||
| 162 | + | ||
| 163 | + private void initView() { | ||
| 164 | + int cameraCount = Camera.getNumberOfCameras(); | ||
| 165 | + setWillNotDraw(false); | ||
| 166 | + int[] cid = {1}; | ||
| 167 | + View view = LayoutInflater.from(getContext()).inflate(R.layout.camera_view, this); | ||
| 168 | + mVideoView = (VideoView) view.findViewById(R.id.video_preview); | ||
| 169 | + mVideoView.setLayoutParams(new LayoutParams(getScreenWidth(), getScreenWidth() * 1920 / 1080)); | ||
| 170 | + mPhoto = (ImageView) view.findViewById(R.id.image_photo); | ||
| 171 | + mSwitchCamera = (ImageView) view.findViewById(R.id.image_switch); | ||
| 172 | + mSwitchCamera.setImageResource(R.drawable.fb_xiangji); | ||
| 173 | + mFlashLamp = (ImageView) view.findViewById(R.id.image_flash); | ||
| 174 | + if (!flashIsVisi) mFlashLamp.setVisibility(GONE); | ||
| 175 | + mFlashLamp.setImageResource(R.drawable.ic_flash_off); | ||
| 176 | + machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 177 | + if (System.currentTimeMillis() - lastClick <= 4000) { | ||
| 178 | + return; | ||
| 179 | + } else { | ||
| 180 | + mFlashLamp.setOnClickListener(new OnClickListener() { | ||
| 181 | + @Override | ||
| 182 | + public void onClick(View v) { | ||
| 183 | + if (CameraInterface.getInstance().getSelectedCamera() == Camera.CameraInfo.CAMERA_FACING_FRONT) | ||
| 184 | + return; | ||
| 185 | + type_flash++; | ||
| 186 | + if (type_flash > 0x023) { | ||
| 187 | + type_flash = 0x022; | ||
| 188 | + } | ||
| 189 | + if (type_flash == TYPE_FLASH_ON) { | ||
| 190 | + mFlashLamp.setImageResource(R.drawable.ic_flash_on); | ||
| 191 | + machine.flash(Camera.Parameters.FLASH_MODE_ON); | ||
| 192 | + } else if (type_flash == TYPE_FLASH_OFF) { | ||
| 193 | + mFlashLamp.setImageResource(R.drawable.ic_flash_off); | ||
| 194 | + machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 195 | + } else { | ||
| 196 | + AlertUtil.showDeftToast(v.getContext(), "闪光灯打开失败"); | ||
| 197 | + mFlashLamp.setImageResource(R.drawable.ic_flash_off); | ||
| 198 | + machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + }); | ||
| 202 | + } | ||
| 203 | + lastClick = System.currentTimeMillis(); | ||
| 204 | + if (cameraCount == 1) { | ||
| 205 | + mSwitchCamera.setVisibility(GONE); | ||
| 206 | + mSwitchCamera.setClickable(false); | ||
| 207 | + } else { | ||
| 208 | + mSwitchCamera.setVisibility(VISIBLE); | ||
| 209 | + mSwitchCamera.setClickable(true); | ||
| 210 | + mSwitchCamera.setImageResource(R.drawable.fb_xiangji); | ||
| 211 | + //切换摄像头 | ||
| 212 | + long[] mHits = new long[3]; | ||
| 213 | + mSwitchCamera.setOnClickListener(new OnClickListener() { | ||
| 214 | + @Override | ||
| 215 | + public void onClick(View v) { | ||
| 216 | + if (System.currentTimeMillis() - lastClickTime < FAST_CLICK_DELAY_TIME) { | ||
| 217 | + } else { | ||
| 218 | + if (machine.swtich(mVideoView.getHolder(), screenProp)) { | ||
| 219 | + if (cid[0] == 1) { | ||
| 220 | + // mFlashLamp.setVisibility(INVISIBLE); | ||
| 221 | + machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 222 | + mFlashLamp.setImageResource(R.drawable.ic_flash_off); | ||
| 223 | + cid[0] = 1; | ||
| 224 | + } else if (cid[0] == 0) { | ||
| 225 | + mFlashLamp.setVisibility(VISIBLE); | ||
| 226 | + machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 227 | + mFlashLamp.setImageResource(R.drawable.ic_flash_off); | ||
| 228 | + cid[0] = 0; | ||
| 229 | + } | ||
| 230 | + } else { | ||
| 231 | + mCaptureLayout.onError(); | ||
| 232 | + } | ||
| 233 | + } | ||
| 234 | + lastClickTime = System.currentTimeMillis(); | ||
| 235 | + | ||
| 236 | + } | ||
| 237 | + }); | ||
| 238 | + } | ||
| 239 | + mCaptureLayout = (CaptureLayout) view.findViewById(R.id.capture_layout); | ||
| 240 | + mCaptureLayout.setDuration(duration); | ||
| 241 | + mCaptureLayout.setIconSrc(iconLeft, iconRight); | ||
| 242 | + mFoucsView = (FoucsView) view.findViewById(R.id.fouce_view); | ||
| 243 | + mVideoView.getHolder().addCallback(this); | ||
| 244 | + //拍照 录像 | ||
| 245 | + mCaptureLayout.setCaptureLisenter(new CaptureListener() { | ||
| 246 | + @Override | ||
| 247 | + public void takePictures() { | ||
| 248 | + if (machine.capture()) { | ||
| 249 | + mSwitchCamera.setVisibility(INVISIBLE); | ||
| 250 | + recordEnd = true; | ||
| 251 | + mFlashLamp.setVisibility(INVISIBLE); | ||
| 252 | + } else { | ||
| 253 | + AlertUtil.showDeftToast(getContext(), "相机拍摄失败"); | ||
| 254 | + Log.e("Camera", "相机拍摄失败."); | ||
| 255 | + mCaptureLayout.onError(); | ||
| 256 | + recordEnd = true; | ||
| 257 | + } | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + @Override | ||
| 261 | + public void recordStart() { | ||
| 262 | + recordEnd = false; | ||
| 263 | + if (machine.record(mVideoView.getHolder().getSurface(), screenProp, getContext())) { | ||
| 264 | + mSwitchCamera.setVisibility(INVISIBLE); | ||
| 265 | + mFlashLamp.setVisibility(INVISIBLE); | ||
| 266 | + } else { | ||
| 267 | + AlertUtil.showDeftToast(getContext(), "相机开启失败"); | ||
| 268 | + Log.e("Camera", "相机开启失败."); | ||
| 269 | + mCaptureLayout.onError(true); | ||
| 270 | + } | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + @Override | ||
| 274 | + public void recordShort(final long time) { | ||
| 275 | + mCaptureLayout.setTextWithAnimation("录制时间过短"); | ||
| 276 | + mSwitchCamera.setVisibility(VISIBLE); | ||
| 277 | + mFlashLamp.setVisibility(VISIBLE); | ||
| 278 | + postDelayed(new Runnable() { | ||
| 279 | + @Override | ||
| 280 | + public void run() { | ||
| 281 | + machine.stopRecord(true, time); | ||
| 282 | + } | ||
| 283 | + }, 1500 - time); | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + @Override | ||
| 287 | + public void recordEnd(long time) { | ||
| 288 | + machine.stopRecord(false, time); | ||
| 289 | + recordEnd = true; | ||
| 290 | + if (jCameraLisenter != null) { | ||
| 291 | + jCameraLisenter.recordEnd(videoUrl, duration); | ||
| 292 | + } | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + @Override | ||
| 296 | + public void recordZoom(float zoom) { | ||
| 297 | + LogUtil.i("recordZoom"); | ||
| 298 | + machine.zoom(zoom, CameraInterface.TYPE_RECORDER); | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + @Override | ||
| 302 | + public void recordError() { | ||
| 303 | + if (errorLisenter != null) { | ||
| 304 | + errorLisenter.AudioPermissionError(); | ||
| 305 | + } | ||
| 306 | + } | ||
| 307 | + }); | ||
| 308 | + //确认 取消 | ||
| 309 | + mCaptureLayout.setTypeLisenter(new TypeListener() { | ||
| 310 | + @Override | ||
| 311 | + public void cancel() { | ||
| 312 | + machine.confirm(); | ||
| 313 | + } | ||
| 314 | + | ||
| 315 | + @Override | ||
| 316 | + public void confirm() { | ||
| 317 | + machine.cancle(mVideoView.getHolder(), screenProp); | ||
| 318 | + stopVideo(); | ||
| 319 | + recordEnd = false; | ||
| 320 | + mFlashLamp.setImageResource(R.drawable.ic_flash_off); | ||
| 321 | + machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 322 | + } | ||
| 323 | + }); | ||
| 324 | + //退出 | ||
| 325 | +// mCaptureLayout.setReturnLisenter(new ReturnListener() { | ||
| 326 | +// @Override | ||
| 327 | +// public void onReturn() { | ||
| 328 | +// if (jCameraLisenter != null) { | ||
| 329 | +// jCameraLisenter.quit(); | ||
| 330 | +// } | ||
| 331 | +// } | ||
| 332 | +// }); | ||
| 333 | + mCaptureLayout.setLeftClickListener(new ClickListener() { | ||
| 334 | + @Override | ||
| 335 | + public void onClick() { | ||
| 336 | + if (leftClickListener != null) { | ||
| 337 | + leftClickListener.onClick(); | ||
| 338 | + } | ||
| 339 | + } | ||
| 340 | + }); | ||
| 341 | + mCaptureLayout.setRightClickListener(new ClickListener() { | ||
| 342 | + @Override | ||
| 343 | + public void onClick() { | ||
| 344 | + if (rightClickListener != null) { | ||
| 345 | + rightClickListener.onClick(); | ||
| 346 | + } | ||
| 347 | + } | ||
| 348 | + }); | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + public void setDuration(int duration_ss) { | ||
| 352 | + if (mCaptureLayout != null) mCaptureLayout.setDuration(duration = duration_ss); | ||
| 353 | + } | ||
| 354 | + | ||
| 355 | + @Override | ||
| 356 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 357 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 358 | + float widthSize = mVideoView.getMeasuredWidth(); | ||
| 359 | + float heightSize = mVideoView.getMeasuredHeight(); | ||
| 360 | + if (screenProp == 0) { | ||
| 361 | + screenProp = heightSize / widthSize; | ||
| 362 | + } | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | + @Override | ||
| 366 | + public void cameraHasOpened() { | ||
| 367 | + CameraInterface.getInstance().doStartPreview(mVideoView.getHolder(), screenProp); | ||
| 368 | + } | ||
| 369 | + | ||
| 370 | + //生命周期onResume | ||
| 371 | + public void onResume() { | ||
| 372 | + LogUtil.i("JCameraView onResume"); | ||
| 373 | + resetState(TYPE_DEFAULT); //重置状态 | ||
| 374 | + CameraInterface.getInstance().registerSensorManager(getContext()); | ||
| 375 | + CameraInterface.getInstance().setSwitchView(mSwitchCamera, mFlashLamp); | ||
| 376 | + machine.setDefaultState(); | ||
| 377 | + machine.start(mVideoView.getHolder(), screenProp); | ||
| 378 | + | ||
| 379 | + CameraInterface.getInstance().doOpenCamera(JCameraView.this, id); | ||
| 380 | + } | ||
| 381 | + | ||
| 382 | + //生命周期onPause | ||
| 383 | + public void onStop() { | ||
| 384 | + LogUtil.i("JCameraView onPause"); | ||
| 385 | + stopVideo(); | ||
| 386 | + resetState(TYPE_PICTURE); | ||
| 387 | + CameraInterface.getInstance().isPreview(false); | ||
| 388 | + CameraInterface.getInstance().unregisterSensorManager(getContext()); | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + //SurfaceView生命周期 | ||
| 392 | + @Override | ||
| 393 | + public void surfaceCreated(SurfaceHolder holder) { | ||
| 394 | + LogUtil.i("JCameraView SurfaceCreated"); | ||
| 395 | + if (recordEnd) { | ||
| 396 | + if (mMediaPlayer != null) { | ||
| 397 | + mMediaPlayer.setDisplay(holder); | ||
| 398 | + mMediaPlayer.start(); | ||
| 399 | + } | ||
| 400 | + return; | ||
| 401 | + } | ||
| 402 | + new Thread() { | ||
| 403 | + @Override | ||
| 404 | + public void run() { | ||
| 405 | + CameraInterface.getInstance().doOpenCamera(JCameraView.this, id); | ||
| 406 | + } | ||
| 407 | + }.start(); | ||
| 408 | + } | ||
| 409 | + | ||
| 410 | + @Override | ||
| 411 | + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { | ||
| 412 | + } | ||
| 413 | + | ||
| 414 | + @Override | ||
| 415 | + public void surfaceDestroyed(SurfaceHolder holder) { | ||
| 416 | + LogUtil.i("JCameraView SurfaceDestroyed"); | ||
| 417 | + if (recordEnd) { | ||
| 418 | + if (mMediaPlayer != null) | ||
| 419 | + mMediaPlayer.setDisplay(null); | ||
| 420 | + pausePlayer(); | ||
| 421 | + return; | ||
| 422 | + } | ||
| 423 | + CameraInterface.getInstance().doDestroyCamera(); | ||
| 424 | + | ||
| 425 | + } | ||
| 426 | + | ||
| 427 | + | ||
| 428 | + @Override | ||
| 429 | + public boolean onTouchEvent(MotionEvent event) { | ||
| 430 | + switch (event.getAction()) { | ||
| 431 | + case MotionEvent.ACTION_DOWN: | ||
| 432 | + if (event.getPointerCount() == 1) { | ||
| 433 | + //显示对焦指示器 | ||
| 434 | + setFocusViewWidthAnimation(event.getX(), event.getY()); | ||
| 435 | + } | ||
| 436 | + if (event.getPointerCount() == 2) { | ||
| 437 | + Log.i("CJT", "ACTION_DOWN = " + 2); | ||
| 438 | + } | ||
| 439 | + break; | ||
| 440 | + case MotionEvent.ACTION_MOVE: | ||
| 441 | + if (event.getPointerCount() == 1) { | ||
| 442 | + firstTouch = true; | ||
| 443 | + } | ||
| 444 | + if (event.getPointerCount() == 2) { | ||
| 445 | + //第一个点 | ||
| 446 | + float point_1_X = event.getX(0); | ||
| 447 | + float point_1_Y = event.getY(0); | ||
| 448 | + //第二个点 | ||
| 449 | + float point_2_X = event.getX(1); | ||
| 450 | + float point_2_Y = event.getY(1); | ||
| 451 | + | ||
| 452 | + float result = (float) Math.sqrt(Math.pow(point_1_X - point_2_X, 2) + Math.pow(point_1_Y - | ||
| 453 | + point_2_Y, 2)); | ||
| 454 | + | ||
| 455 | + if (firstTouch) { | ||
| 456 | + firstTouchLength = result; | ||
| 457 | + firstTouch = false; | ||
| 458 | + } | ||
| 459 | + if ((int) (result - firstTouchLength) / zoomGradient != 0) { | ||
| 460 | + firstTouch = true; | ||
| 461 | + machine.zoom(result - firstTouchLength, CameraInterface.TYPE_CAPTURE); | ||
| 462 | + } | ||
| 463 | +// Log.i("CJT", "result = " + (result - firstTouchLength)); | ||
| 464 | + } | ||
| 465 | + break; | ||
| 466 | + case MotionEvent.ACTION_UP: | ||
| 467 | + firstTouch = true; | ||
| 468 | + break; | ||
| 469 | + } | ||
| 470 | + return true; | ||
| 471 | + } | ||
| 472 | + | ||
| 473 | + //对焦框指示器动画 | ||
| 474 | + private void setFocusViewWidthAnimation(float x, float y) { | ||
| 475 | + machine.foucs(x, y, new CameraInterface.FocusCallback() { | ||
| 476 | + @Override | ||
| 477 | + public void focusSuccess() { | ||
| 478 | + mFoucsView.setVisibility(INVISIBLE); | ||
| 479 | + } | ||
| 480 | + }); | ||
| 481 | + } | ||
| 482 | + | ||
| 483 | + private void updateVideoViewSize(float videoWidth, float videoHeight) { | ||
| 484 | + if (videoWidth > videoHeight) { | ||
| 485 | + LayoutParams videoViewParam; | ||
| 486 | + int height = (int) ((videoHeight / videoWidth) * getWidth()); | ||
| 487 | + videoViewParam = new LayoutParams(LayoutParams.MATCH_PARENT, height); | ||
| 488 | + videoViewParam.gravity = Gravity.CENTER; | ||
| 489 | + mVideoView.setLayoutParams(videoViewParam); | ||
| 490 | + } | ||
| 491 | + } | ||
| 492 | + | ||
| 493 | + /************************************************** | ||
| 494 | + * 对外提供的API * | ||
| 495 | + **************************************************/ | ||
| 496 | + | ||
| 497 | + public void setSaveVideoPath(String path) { | ||
| 498 | + CameraInterface.getInstance().setSaveVideoPath(path); | ||
| 499 | + } | ||
| 500 | + | ||
| 501 | + | ||
| 502 | + public void setJCameraLisenter(JCameraListener jCameraLisenter) { | ||
| 503 | + this.jCameraLisenter = jCameraLisenter; | ||
| 504 | + } | ||
| 505 | + | ||
| 506 | + | ||
| 507 | + private ErrorListener errorLisenter; | ||
| 508 | + | ||
| 509 | + //启动Camera错误回调 | ||
| 510 | + public void setErrorLisenter(ErrorListener errorLisenter) { | ||
| 511 | + this.errorLisenter = errorLisenter; | ||
| 512 | + CameraInterface.getInstance().setErrorLinsenter(errorLisenter); | ||
| 513 | + } | ||
| 514 | + | ||
| 515 | + //设置CaptureButton功能(拍照和录像) | ||
| 516 | + public void setFeatures(int state) { | ||
| 517 | + this.mCaptureLayout.setButtonFeatures(state); | ||
| 518 | + } | ||
| 519 | + | ||
| 520 | + //设置初始前置 | ||
| 521 | + public void setFront(int state) { | ||
| 522 | + id = state; | ||
| 523 | + flashIsVisi = false; | ||
| 524 | + } | ||
| 525 | + | ||
| 526 | + //设置录制质量 | ||
| 527 | + public void setMediaQuality(int quality) { | ||
| 528 | + CameraInterface.getInstance().setMediaQuality(quality); | ||
| 529 | + } | ||
| 530 | + | ||
| 531 | + public void setButtonVisiblity() { | ||
| 532 | + mCaptureLayout.setVisibility(GONE); | ||
| 533 | + } | ||
| 534 | + | ||
| 535 | + @Override | ||
| 536 | + public void resetState(int type) { | ||
| 537 | + switch (type) { | ||
| 538 | + case TYPE_VIDEO: | ||
| 539 | + stopVideo(); //停止播放 | ||
| 540 | + //初始化VideoView | ||
| 541 | + FileUtil.deleteFile(videoUrl); | ||
| 542 | + mVideoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 543 | + machine.start(mVideoView.getHolder(), screenProp); | ||
| 544 | + break; | ||
| 545 | + case TYPE_PICTURE: | ||
| 546 | + mPhoto.setVisibility(INVISIBLE); | ||
| 547 | + break; | ||
| 548 | + case TYPE_SHORT: | ||
| 549 | + break; | ||
| 550 | + case TYPE_DEFAULT: | ||
| 551 | + mVideoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 552 | + break; | ||
| 553 | + } | ||
| 554 | + mSwitchCamera.setVisibility(VISIBLE); | ||
| 555 | + mFlashLamp.setVisibility(VISIBLE); | ||
| 556 | + mCaptureLayout.resetCaptureLayout(); | ||
| 557 | + } | ||
| 558 | + | ||
| 559 | + @Override | ||
| 560 | + public void confirmState(int type) { | ||
| 561 | + switch (type) { | ||
| 562 | + case TYPE_VIDEO: | ||
| 563 | + int duration = mMediaPlayer.getDuration(); | ||
| 564 | + stopVideo(); //停止播放 | ||
| 565 | + mVideoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 566 | + machine.start(mVideoView.getHolder(), screenProp); | ||
| 567 | + if (jCameraLisenter != null) { | ||
| 568 | + jCameraLisenter.recordSuccess(videoUrl, duration); | ||
| 569 | + } | ||
| 570 | + break; | ||
| 571 | + case TYPE_PICTURE: | ||
| 572 | + mPhoto.setVisibility(INVISIBLE); | ||
| 573 | + if (jCameraLisenter != null) { | ||
| 574 | + jCameraLisenter.captureSuccess(captureBitmap); | ||
| 575 | + } | ||
| 576 | + break; | ||
| 577 | + case TYPE_SHORT: | ||
| 578 | + break; | ||
| 579 | + case TYPE_DEFAULT: | ||
| 580 | + break; | ||
| 581 | + } | ||
| 582 | + mCaptureLayout.resetCaptureLayout(); | ||
| 583 | + } | ||
| 584 | + | ||
| 585 | + @Override | ||
| 586 | + public void showPicture(Bitmap bitmap, boolean isVertical) { | ||
| 587 | + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { | ||
| 588 | + ViewGroup.LayoutParams layoutParams = mPhoto.getLayoutParams(); | ||
| 589 | + layoutParams.width = ScreenUtils.getScreenWidth(getContext()); | ||
| 590 | + layoutParams.height = ScreenUtils.getScreenHeight(getContext()); | ||
| 591 | + mPhoto.setLayoutParams(layoutParams); | ||
| 592 | + } else { | ||
| 593 | + if (isVertical) { | ||
| 594 | + mPhoto.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||
| 595 | + } else { | ||
| 596 | + mPhoto.setScaleType(ImageView.ScaleType.FIT_CENTER); | ||
| 597 | + } | ||
| 598 | + } | ||
| 599 | + captureBitmap = bitmap; | ||
| 600 | + mPhoto.setVisibility(VISIBLE); | ||
| 601 | + mPhoto.setImageBitmap(captureBitmap); | ||
| 602 | + | ||
| 603 | + mCaptureLayout.startAlphaAnimation(); | ||
| 604 | + mCaptureLayout.startTypeBtnAnimator(); | ||
| 605 | + } | ||
| 606 | + | ||
| 607 | + @Override | ||
| 608 | + public void playVideo(final String url) { | ||
| 609 | + videoUrl = url; | ||
| 610 | + new Thread(new Runnable() { | ||
| 611 | + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) | ||
| 612 | + @Override | ||
| 613 | + public void run() { | ||
| 614 | + try { | ||
| 615 | + if (mMediaPlayer == null) { | ||
| 616 | + mMediaPlayer = new MediaPlayer(); | ||
| 617 | + } else { | ||
| 618 | + mMediaPlayer.reset(); | ||
| 619 | + } | ||
| 620 | + mMediaPlayer.setDataSource(url); | ||
| 621 | + try { | ||
| 622 | + | ||
| 623 | + mMediaPlayer.setDisplay(mVideoView.getHolder()); | ||
| 624 | + } catch (Exception e) { | ||
| 625 | + Log.e("MediaPlayer", "setDisplay", e); | ||
| 626 | + } | ||
| 627 | + mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT); | ||
| 628 | + mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); | ||
| 629 | + mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer | ||
| 630 | + .OnVideoSizeChangedListener() { | ||
| 631 | + @Override | ||
| 632 | + public void | ||
| 633 | + onVideoSizeChanged(MediaPlayer mp, int width, int height) { | ||
| 634 | + updateVideoViewSize(mMediaPlayer.getVideoWidth(), mMediaPlayer | ||
| 635 | + .getVideoHeight()); | ||
| 636 | + } | ||
| 637 | + }); | ||
| 638 | + mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { | ||
| 639 | + @Override | ||
| 640 | + public void onPrepared(MediaPlayer mp) { | ||
| 641 | + mMediaPlayer.start(); | ||
| 642 | + } | ||
| 643 | + }); | ||
| 644 | + mMediaPlayer.setLooping(true); | ||
| 645 | + mMediaPlayer.prepare(); | ||
| 646 | + } catch (Exception e) { | ||
| 647 | + Log.e("MediaPlayer", "", e); | ||
| 648 | + } | ||
| 649 | + } | ||
| 650 | + }).start(); | ||
| 651 | + } | ||
| 652 | + | ||
| 653 | + @Override | ||
| 654 | + public void stopVideo() { | ||
| 655 | + if (mMediaPlayer != null) { | ||
| 656 | + mMediaPlayer.stop(); | ||
| 657 | + mMediaPlayer.release(); | ||
| 658 | + mMediaPlayer = null; | ||
| 659 | + } | ||
| 660 | + // recordEnd=true; | ||
| 661 | + } | ||
| 662 | + | ||
| 663 | + @Override | ||
| 664 | + public void setTip(String tip) { | ||
| 665 | + mCaptureLayout.setTip(tip); | ||
| 666 | + } | ||
| 667 | + | ||
| 668 | + @Override | ||
| 669 | + public void startPreviewCallback() { | ||
| 670 | + LogUtil.i("startPreviewCallback"); | ||
| 671 | + handlerFoucs(mFoucsView.getWidth() / 2, mFoucsView.getHeight() / 2); | ||
| 672 | + } | ||
| 673 | + | ||
| 674 | + @Override | ||
| 675 | + public boolean handlerFoucs(float x, float y) { | ||
| 676 | + if (y > mCaptureLayout.getTop()) { | ||
| 677 | + return false; | ||
| 678 | + } | ||
| 679 | + mFoucsView.setVisibility(VISIBLE); | ||
| 680 | + if (x < mFoucsView.getWidth() / 2) { | ||
| 681 | + x = mFoucsView.getWidth() / 2; | ||
| 682 | + } | ||
| 683 | + if (x > layout_width - mFoucsView.getWidth() / 2) { | ||
| 684 | + x = layout_width - mFoucsView.getWidth() / 2; | ||
| 685 | + } | ||
| 686 | + if (y < mFoucsView.getWidth() / 2) { | ||
| 687 | + y = mFoucsView.getWidth() / 2; | ||
| 688 | + } | ||
| 689 | + if (y > mCaptureLayout.getTop() - mFoucsView.getWidth() / 2) { | ||
| 690 | + y = mCaptureLayout.getTop() - mFoucsView.getWidth() / 2; | ||
| 691 | + } | ||
| 692 | + mFoucsView.setX(x - mFoucsView.getWidth() / 2); | ||
| 693 | + mFoucsView.setY(y - mFoucsView.getHeight() / 2); | ||
| 694 | + ObjectAnimator scaleX = ObjectAnimator.ofFloat(mFoucsView, "scaleX", 1, 0.6f); | ||
| 695 | + ObjectAnimator scaleY = ObjectAnimator.ofFloat(mFoucsView, "scaleY", 1, 0.6f); | ||
| 696 | + ObjectAnimator alpha = ObjectAnimator.ofFloat(mFoucsView, "alpha", 1f, 0.4f, 1f, 0.4f, 1f, 0.4f, 1f); | ||
| 697 | + AnimatorSet animSet = new AnimatorSet(); | ||
| 698 | + animSet.play(scaleX).with(scaleY).before(alpha); | ||
| 699 | + animSet.setDuration(400); | ||
| 700 | + animSet.start(); | ||
| 701 | + return true; | ||
| 702 | + } | ||
| 703 | + | ||
| 704 | + @Override | ||
| 705 | + public void pausePlayer() { | ||
| 706 | + if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { | ||
| 707 | + mMediaPlayer.pause(); | ||
| 708 | + } | ||
| 709 | + } | ||
| 710 | + | ||
| 711 | + @Override | ||
| 712 | + public void resumePlayer() { | ||
| 713 | + if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) { | ||
| 714 | + mMediaPlayer.start(); | ||
| 715 | + } | ||
| 716 | + } | ||
| 717 | + | ||
| 718 | + public void setLeftClickListener(ClickListener clickListener) { | ||
| 719 | + this.leftClickListener = clickListener; | ||
| 720 | + } | ||
| 721 | + | ||
| 722 | + public void setRightClickListener(ClickListener clickListener) { | ||
| 723 | + this.rightClickListener = clickListener; | ||
| 724 | + } | ||
| 725 | + | ||
| 726 | + public void onDestroy() { | ||
| 727 | + if (recordEnd) { | ||
| 728 | + CameraInterface.getInstance().doDestroyCamera(); | ||
| 729 | + } | ||
| 730 | + if (machine != null) machine.onDestroy(); | ||
| 731 | + } | ||
| 732 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/OnLineCaptureButton.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record; | ||
| 2 | +// | ||
| 3 | +// | ||
| 4 | +//import static com.cnlive.media.ui.widget.record.JCameraView.BUTTON_STATE_BOTH; | ||
| 5 | +//import static com.cnlive.media.ui.widget.record.JCameraView.BUTTON_STATE_ONLY_CAPTURE; | ||
| 6 | +// | ||
| 7 | +//import android.animation.Animator; | ||
| 8 | +//import android.animation.AnimatorListenerAdapter; | ||
| 9 | +//import android.animation.ValueAnimator; | ||
| 10 | +//import android.content.Context; | ||
| 11 | +//import android.graphics.Canvas; | ||
| 12 | +//import android.graphics.Color; | ||
| 13 | +//import android.graphics.Paint; | ||
| 14 | +//import android.graphics.RectF; | ||
| 15 | +//import android.os.CountDownTimer; | ||
| 16 | +//import android.view.View; | ||
| 17 | +// | ||
| 18 | +//import com.cnlive.libs.base.util.AlertUtil; | ||
| 19 | +//import com.cnlive.media.R; | ||
| 20 | +//import com.cnlive.media.ui.widget.record.listener.CaptureListener; | ||
| 21 | +//import com.cnlive.media.utils.LogUtil; | ||
| 22 | +// | ||
| 23 | +// | ||
| 24 | +///** | ||
| 25 | +// * ===================================== | ||
| 26 | +// * 作 者: 陈嘉桐 445263848@qq.com | ||
| 27 | +// * 版 本:1.1.4 | ||
| 28 | +// * 创建日期:2017/4/25 | ||
| 29 | +// * 描 述:拍照按钮 | ||
| 30 | +// * ===================================== | ||
| 31 | +// */ | ||
| 32 | +//public class OnLineCaptureButton extends View { | ||
| 33 | +// | ||
| 34 | +// private int state; //当前按钮状态 | ||
| 35 | +// private int button_state; //按钮可执行的功能状态(拍照,录制,两者) | ||
| 36 | +// | ||
| 37 | +// public static final int STATE_IDLE = 0x001; //空闲状态 | ||
| 38 | +// public static final int STATE_PRESS = 0x002; //按下状态 | ||
| 39 | +// public static final int STATE_LONG_PRESS = 0x003; //长按状态 | ||
| 40 | +// public static final int STATE_RECORDERING = 0x004; //录制状态 | ||
| 41 | +// public static final int STATE_BAN = 0x005; //禁止状态 | ||
| 42 | +// | ||
| 43 | +// private int progress_color = Color.GREEN; //进度条颜色 | ||
| 44 | +// private int outside_color = 0xEEf2f2f2; //外圆背景色 | ||
| 45 | +// private int inside_color = Color.WHITE; //内圆背景色 | ||
| 46 | +// | ||
| 47 | +// | ||
| 48 | +// private float event_Y; //Touch_Event_Down时候记录的Y值 | ||
| 49 | +// | ||
| 50 | +// | ||
| 51 | +// private Paint mPaint,inPaint; | ||
| 52 | +// | ||
| 53 | +// private float strokeWidth; //进度条宽度 | ||
| 54 | +// private int outside_add_size; //长按外圆半径变大的Size | ||
| 55 | +// private int inside_reduce_size; //长安内圆缩小的Size | ||
| 56 | +// | ||
| 57 | +// //中心坐标 | ||
| 58 | +// private float center_X; | ||
| 59 | +// private float center_Y; | ||
| 60 | +// | ||
| 61 | +// private float button_radius; //按钮半径 | ||
| 62 | +// private float button_outside_radius; //外圆半径 | ||
| 63 | +// private float button_inside_radius; //内圆半径 | ||
| 64 | +// private int button_size; //按钮大小 | ||
| 65 | +// | ||
| 66 | +// private float progress; //录制视频的进度 | ||
| 67 | +// private int duration; //录制视频最大时间长度 | ||
| 68 | +// private int min_duration; //最短录制时间限制 | ||
| 69 | +// private int recorded_time; //记录当前录制的时间 | ||
| 70 | +// | ||
| 71 | +// private RectF rectF; | ||
| 72 | +// | ||
| 73 | +// private LongPressRunnable longPressRunnable; //长按后处理的逻辑Runnable | ||
| 74 | +// private CaptureListener captureLisenter; //按钮回调接口 | ||
| 75 | +// private RecordCountDownTimer timer; //计时器 | ||
| 76 | +// | ||
| 77 | +// public OnLineCaptureButton(Context context) { | ||
| 78 | +// super(context); | ||
| 79 | +// } | ||
| 80 | +// | ||
| 81 | +// public OnLineCaptureButton(Context context, int size) { | ||
| 82 | +// super(context); | ||
| 83 | +// this.button_size = size; | ||
| 84 | +// button_radius = size / 2.0f; | ||
| 85 | +// | ||
| 86 | +// button_outside_radius = button_radius; | ||
| 87 | +// button_inside_radius = button_radius * 0.75f; | ||
| 88 | +// | ||
| 89 | +// strokeWidth = size / 15; | ||
| 90 | +// outside_add_size = size / 5; | ||
| 91 | +// inside_reduce_size = size / 8; | ||
| 92 | +// | ||
| 93 | +// mPaint = new Paint(); | ||
| 94 | +// inPaint = new Paint(); | ||
| 95 | +// mPaint.setAntiAlias(true); | ||
| 96 | +// inPaint.setAntiAlias(true); | ||
| 97 | +// inPaint.setStyle(Paint.Style.FILL); | ||
| 98 | +// progress = 0; | ||
| 99 | +// longPressRunnable = new LongPressRunnable(); | ||
| 100 | +// | ||
| 101 | +// state = STATE_IDLE; //初始化为空闲状态 | ||
| 102 | +// LogUtil.i("CaptureButtom start"); | ||
| 103 | +// duration = 10 * 1000; //默认最长录制时间为10s | ||
| 104 | +// LogUtil.i("CaptureButtom end"); | ||
| 105 | +// min_duration = 2000; //默认最短录制时间为1.5s | ||
| 106 | +// | ||
| 107 | +// center_X = (button_size + outside_add_size * 2) / 2; | ||
| 108 | +// center_Y = (button_size + outside_add_size * 2) / 2; | ||
| 109 | +// | ||
| 110 | +// rectF = new RectF( | ||
| 111 | +// center_X - (button_radius + outside_add_size - strokeWidth / 2), | ||
| 112 | +// center_Y - (button_radius + outside_add_size - strokeWidth / 2), | ||
| 113 | +// center_X + (button_radius + outside_add_size - strokeWidth / 2), | ||
| 114 | +// center_Y + (button_radius + outside_add_size - strokeWidth / 2)); | ||
| 115 | +// | ||
| 116 | +// timer = new RecordCountDownTimer(duration, duration / 360); //录制定时器 | ||
| 117 | +// } | ||
| 118 | +// | ||
| 119 | +// @Override | ||
| 120 | +// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 121 | +// super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 122 | +// setMeasuredDimension(button_size + outside_add_size * 2, button_size + outside_add_size * 2); | ||
| 123 | +// } | ||
| 124 | +// | ||
| 125 | +// @Override | ||
| 126 | +// protected void onDraw(Canvas canvas) { | ||
| 127 | +// super.onDraw(canvas); | ||
| 128 | +// mPaint.setStyle(Paint.Style.STROKE); | ||
| 129 | +// mPaint.setColor(getResources().getColor(R.color.imagepicker_text_white)); | ||
| 130 | +// mPaint.setStrokeWidth(dip2px(4)); | ||
| 131 | +// canvas.drawCircle(center_X, center_Y, button_outside_radius, mPaint); | ||
| 132 | +// | ||
| 133 | +// inPaint.setColor(getResources().getColor(R.color.onlinein)); | ||
| 134 | +// inPaint.setStrokeWidth(dip2px(2)); | ||
| 135 | +// | ||
| 136 | +// canvas.drawRect(center_X-25, center_Y+25,center_X+25,center_Y-25, inPaint); | ||
| 137 | +// } | ||
| 138 | +// | ||
| 139 | +// public int dip2px(int dp) { | ||
| 140 | +// float density = getContext().getResources().getDisplayMetrics().density; | ||
| 141 | +// return (int) (dp * density + 0.5); | ||
| 142 | +// } | ||
| 143 | +// | ||
| 144 | +// /* @Override | ||
| 145 | +// public boolean onTouchEvent(MotionEvent event) { | ||
| 146 | +// switch (event.getAction()) { | ||
| 147 | +// case MotionEvent.ACTION_DOWN: | ||
| 148 | +// LogUtil.i("state = " + state); | ||
| 149 | +// if (event.getPointerCount() > 1 || state != STATE_IDLE) | ||
| 150 | +// break; | ||
| 151 | +// event_Y = event.getY(); //记录Y值 | ||
| 152 | +// state = STATE_PRESS; //修改当前状态为点击按下 | ||
| 153 | +// | ||
| 154 | +// //判断按钮状态是否为可录制状态 | ||
| 155 | +// if ((button_state == BUTTON_STATE_ONLY_RECORDER || button_state == BUTTON_STATE_BOTH)) | ||
| 156 | +// postDelayed(longPressRunnable, 200); //同时延长500启动长按后处理的逻辑Runnable | ||
| 157 | +// break; | ||
| 158 | +// case MotionEvent.ACTION_MOVE: | ||
| 159 | +// if (captureLisenter != null | ||
| 160 | +// && state == STATE_RECORDERING | ||
| 161 | +// && (button_state == BUTTON_STATE_ONLY_RECORDER || button_state == BUTTON_STATE_BOTH)) { | ||
| 162 | +// //记录当前Y值与按下时候Y值的差值,调用缩放回调接口 | ||
| 163 | +// captureLisenter.recordZoom(event_Y - event.getY()); | ||
| 164 | +// } | ||
| 165 | +// break; | ||
| 166 | +// case MotionEvent.ACTION_UP: | ||
| 167 | +// //根据当前按钮的状态进行相应的处理 | ||
| 168 | +// handlerUnpressByState(); | ||
| 169 | +// break; | ||
| 170 | +// } | ||
| 171 | +// return true; | ||
| 172 | +// }*/ | ||
| 173 | +// | ||
| 174 | +// //当手指松开按钮时候处理的逻辑 | ||
| 175 | +// private void handlerUnpressByState() { | ||
| 176 | +// removeCallbacks(longPressRunnable); //移除长按逻辑的Runnable | ||
| 177 | +// //根据当前状态处理 | ||
| 178 | +// switch (state) { | ||
| 179 | +// //当前是点击按下 | ||
| 180 | +// case STATE_PRESS: | ||
| 181 | +// if (captureLisenter != null && (button_state == BUTTON_STATE_ONLY_CAPTURE || button_state == | ||
| 182 | +// BUTTON_STATE_BOTH)) { | ||
| 183 | +// startCaptureAnimation(button_inside_radius); | ||
| 184 | +// } else { | ||
| 185 | +// state = STATE_IDLE; | ||
| 186 | +// } | ||
| 187 | +// break; | ||
| 188 | +// //当前是长按状态 | ||
| 189 | +// case STATE_RECORDERING: | ||
| 190 | +// timer.cancel(); //停止计时器 | ||
| 191 | +// recordEnd(); //录制结束 | ||
| 192 | +// break; | ||
| 193 | +// } | ||
| 194 | +// } | ||
| 195 | +// | ||
| 196 | +// //录制结束 | ||
| 197 | +// private void recordEnd() { | ||
| 198 | +// if (captureLisenter != null) { | ||
| 199 | +// if (recorded_time < min_duration) | ||
| 200 | +// captureLisenter.recordShort(recorded_time);//回调录制时间过短 | ||
| 201 | +// else | ||
| 202 | +// captureLisenter.recordEnd(recorded_time); //回调录制结束 | ||
| 203 | +// } | ||
| 204 | +// resetRecordAnim(); //重制按钮状态 | ||
| 205 | +// } | ||
| 206 | +// | ||
| 207 | +// //重制状态 | ||
| 208 | +// public void resetRecordAnim() { | ||
| 209 | +// state = STATE_BAN; | ||
| 210 | +// progress = 0; //重制进度 | ||
| 211 | +// invalidate(); | ||
| 212 | +// //还原按钮初始状态动画 | ||
| 213 | +// startRecordAnimation( | ||
| 214 | +// button_outside_radius, | ||
| 215 | +// button_radius, | ||
| 216 | +// button_inside_radius, | ||
| 217 | +// button_radius * 0.75f | ||
| 218 | +// ); | ||
| 219 | +// } | ||
| 220 | +// | ||
| 221 | +// //内圆动画 | ||
| 222 | +// private void startCaptureAnimation(float inside_start) { | ||
| 223 | +// ValueAnimator inside_anim = ValueAnimator.ofFloat(inside_start, inside_start * 0.75f, inside_start); | ||
| 224 | +// inside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | ||
| 225 | +// @Override | ||
| 226 | +// public void onAnimationUpdate(ValueAnimator animation) { | ||
| 227 | +// button_inside_radius = (float) animation.getAnimatedValue(); | ||
| 228 | +// invalidate(); | ||
| 229 | +// } | ||
| 230 | +// }); | ||
| 231 | +// inside_anim.addListener(new AnimatorListenerAdapter() { | ||
| 232 | +// @Override | ||
| 233 | +// public void onAnimationEnd(Animator animation) { | ||
| 234 | +// super.onAnimationEnd(animation); | ||
| 235 | +// //回调拍照接口 | ||
| 236 | +// captureLisenter.takePictures(); | ||
| 237 | +// state = STATE_BAN; | ||
| 238 | +// } | ||
| 239 | +// }); | ||
| 240 | +// inside_anim.setDuration(100); | ||
| 241 | +// inside_anim.start(); | ||
| 242 | +// } | ||
| 243 | +// | ||
| 244 | +// //内外圆动画 | ||
| 245 | +// private void startRecordAnimation(float outside_start, float outside_end, float inside_start, float inside_end) { | ||
| 246 | +// /* ValueAnimator outside_anim = ValueAnimator.ofFloat(outside_start, outside_end); | ||
| 247 | +// ValueAnimator inside_anim = ValueAnimator.ofFloat(inside_start, inside_end); | ||
| 248 | +// //外圆动画监听 | ||
| 249 | +// outside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | ||
| 250 | +// @Override | ||
| 251 | +// public void onAnimationUpdate(ValueAnimator animation) { | ||
| 252 | +// button_outside_radius = (float) animation.getAnimatedValue(); | ||
| 253 | +// invalidate(); | ||
| 254 | +// } | ||
| 255 | +// }); | ||
| 256 | +// //内圆动画监听 | ||
| 257 | +// inside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | ||
| 258 | +// @Override | ||
| 259 | +// public void onAnimationUpdate(ValueAnimator animation) { | ||
| 260 | +// button_inside_radius = (float) animation.getAnimatedValue(); | ||
| 261 | +// invalidate(); | ||
| 262 | +// } | ||
| 263 | +// }); | ||
| 264 | +// AnimatorSet set = new AnimatorSet(); | ||
| 265 | +// //当动画结束后启动录像Runnable并且回调录像开始接口 | ||
| 266 | +// set.addListener(new AnimatorListenerAdapter() { | ||
| 267 | +// @Override | ||
| 268 | +// public void onAnimationEnd(Animator animation) { | ||
| 269 | +// super.onAnimationEnd(animation); | ||
| 270 | +// //设置为录制状态 | ||
| 271 | +// if (state == STATE_LONG_PRESS) { | ||
| 272 | +// if (captureLisenter != null) | ||
| 273 | +// captureLisenter.recordStart(); | ||
| 274 | +// state = STATE_RECORDERING; | ||
| 275 | +// timer.start(); | ||
| 276 | +// } | ||
| 277 | +// } | ||
| 278 | +// }); | ||
| 279 | +// set.playTogether(outside_anim, inside_anim); | ||
| 280 | +// set.setDuration(0); | ||
| 281 | +// set.start();*/ | ||
| 282 | +// | ||
| 283 | +// if (state == STATE_LONG_PRESS) { | ||
| 284 | +// AlertUtil.showDeftToast(getContext(),"开始"); | ||
| 285 | +// if (captureLisenter != null) | ||
| 286 | +// captureLisenter.recordStart(); | ||
| 287 | +// state = STATE_RECORDERING; | ||
| 288 | +// timer.start(); | ||
| 289 | +// } | ||
| 290 | +// } | ||
| 291 | +// | ||
| 292 | +// | ||
| 293 | +// //更新进度条 | ||
| 294 | +// private void updateProgress(long millisUntilFinished) { | ||
| 295 | +// recorded_time = (int) (duration - millisUntilFinished); | ||
| 296 | +// progress = 360f - millisUntilFinished / (float) duration * 360f; | ||
| 297 | +// invalidate(); | ||
| 298 | +// } | ||
| 299 | +// | ||
| 300 | +// //录制视频计时器 | ||
| 301 | +// private class RecordCountDownTimer extends CountDownTimer { | ||
| 302 | +// RecordCountDownTimer(long millisInFuture, long countDownInterval) { | ||
| 303 | +// super(millisInFuture, countDownInterval); | ||
| 304 | +// } | ||
| 305 | +// | ||
| 306 | +// @Override | ||
| 307 | +// public void onTick(long millisUntilFinished) { | ||
| 308 | +// updateProgress(millisUntilFinished); | ||
| 309 | +// } | ||
| 310 | +// | ||
| 311 | +// @Override | ||
| 312 | +// public void onFinish() { | ||
| 313 | +// updateProgress(0); | ||
| 314 | +// recordEnd(); | ||
| 315 | +// } | ||
| 316 | +// } | ||
| 317 | +// | ||
| 318 | +// //长按线程 | ||
| 319 | +// private class LongPressRunnable implements Runnable { | ||
| 320 | +// @Override | ||
| 321 | +// public void run() { | ||
| 322 | +// state = STATE_LONG_PRESS; //如果按下后经过500毫秒则会修改当前状态为长按状态 | ||
| 323 | +// //没有录制权限 | ||
| 324 | +// if (CheckPermission.getRecordState() != CheckPermission.STATE_SUCCESS) { | ||
| 325 | +// state = STATE_IDLE; | ||
| 326 | +// if (captureLisenter != null) { | ||
| 327 | +// captureLisenter.recordError(); | ||
| 328 | +// return; | ||
| 329 | +// } | ||
| 330 | +// } | ||
| 331 | +// //启动按钮动画,外圆变大,内圆缩小 | ||
| 332 | +// startRecordAnimation( | ||
| 333 | +// button_outside_radius, | ||
| 334 | +// button_outside_radius + outside_add_size, | ||
| 335 | +// button_inside_radius, | ||
| 336 | +// button_inside_radius - inside_reduce_size | ||
| 337 | +// ); | ||
| 338 | +// } | ||
| 339 | +// } | ||
| 340 | +// | ||
| 341 | +// /************************************************** | ||
| 342 | +// * 对外提供的API * | ||
| 343 | +// **************************************************/ | ||
| 344 | +// | ||
| 345 | +// //设置最长录制时间 | ||
| 346 | +// public void setDuration(int duration) { | ||
| 347 | +// this.duration = duration; | ||
| 348 | +// timer = new RecordCountDownTimer(duration, duration / 360); //录制定时器 | ||
| 349 | +// } | ||
| 350 | +// | ||
| 351 | +// //设置最短录制时间 | ||
| 352 | +// public void setMinDuration(int duration) { | ||
| 353 | +// this.min_duration = duration; | ||
| 354 | +// } | ||
| 355 | +// | ||
| 356 | +// //设置回调接口 | ||
| 357 | +// public void setCaptureLisenter(CaptureListener captureLisenter) { | ||
| 358 | +// this.captureLisenter = captureLisenter; | ||
| 359 | +// } | ||
| 360 | +// | ||
| 361 | +// //设置按钮功能(拍照和录像) | ||
| 362 | +// public void setButtonFeatures(int state) { | ||
| 363 | +// this.button_state = state; | ||
| 364 | +// } | ||
| 365 | +// | ||
| 366 | +// //是否空闲状态 | ||
| 367 | +// public boolean isIdle() { | ||
| 368 | +// return state == STATE_IDLE ? true : false; | ||
| 369 | +// } | ||
| 370 | +// | ||
| 371 | +// //设置状态 | ||
| 372 | +// public void resetState() { | ||
| 373 | +// state = STATE_IDLE; | ||
| 374 | +// } | ||
| 375 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/OnLineCaptureLayout.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record; | ||
| 2 | +// | ||
| 3 | +//import static com.cnlive.libs.base.logic.Config.SUCCESS; | ||
| 4 | +//import static com.cnlive.media.ui.widget.record.view.OnLineCameraView.BUTTON_STATE_BOTH; | ||
| 5 | +//import static com.cnlive.media.ui.widget.record.view.OnLineCameraView.BUTTON_STATE_ONLY_CAPTURE; | ||
| 6 | +//import static com.cnlive.media.ui.widget.record.view.OnLineCameraView.BUTTON_STATE_ONLY_RECORDER; | ||
| 7 | +// | ||
| 8 | +//import android.animation.Animator; | ||
| 9 | +//import android.animation.AnimatorListenerAdapter; | ||
| 10 | +//import android.animation.AnimatorSet; | ||
| 11 | +//import android.animation.ObjectAnimator; | ||
| 12 | +//import android.app.Activity; | ||
| 13 | +//import android.app.Dialog; | ||
| 14 | +//import android.content.Context; | ||
| 15 | +//import android.content.res.Configuration; | ||
| 16 | +//import android.content.res.Resources; | ||
| 17 | +//import android.media.MediaMetadataRetriever; | ||
| 18 | +//import android.util.AttributeSet; | ||
| 19 | +//import android.view.Gravity; | ||
| 20 | +//import android.view.View; | ||
| 21 | +//import android.widget.FrameLayout; | ||
| 22 | +//import android.widget.ImageView; | ||
| 23 | +//import android.widget.TextView; | ||
| 24 | +// | ||
| 25 | +//import com.cnlive.media.R; | ||
| 26 | +//import com.cnlive.media.ui.widget.record.listener.CaptureListener; | ||
| 27 | +//import com.cnlive.media.ui.widget.record.listener.ClickListener; | ||
| 28 | +//import com.cnlive.media.ui.widget.record.listener.ReturnListener; | ||
| 29 | +//import com.cnlive.media.ui.widget.record.listener.TypeListener; | ||
| 30 | +//import com.cnlive.media.utils.AlertDialogUtils; | ||
| 31 | +//import com.cnlive.media.utils.JiaShenUploadDialog; | ||
| 32 | +// | ||
| 33 | +// | ||
| 34 | +///** | ||
| 35 | +// * ===================================== | ||
| 36 | +// * 作 者: 陈嘉桐 445263848@qq.com | ||
| 37 | +// * 版 本:1.0.4 | ||
| 38 | +// * 创建日期:2017/4/26 | ||
| 39 | +// * 描 述:集成各个控件的布局 | ||
| 40 | +// * ===================================== | ||
| 41 | +// */ | ||
| 42 | +// | ||
| 43 | +//public class OnLineCaptureLayout extends FrameLayout { | ||
| 44 | +// public static final String OPEN_URL = "https://api.cnlive.com/"; | ||
| 45 | +// private boolean isErrorState = false; | ||
| 46 | +// private CaptureListener captureLisenter; //拍照按钮监听 | ||
| 47 | +// private TypeListener typeLisenter; //拍照或录制后接结果按钮监听 | ||
| 48 | +// private ReturnListener returnListener; //退出按钮监听 | ||
| 49 | +// private ClickListener leftClickListener; //左边按钮监听 | ||
| 50 | +// private ClickListener rightClickListener; //右边按钮监听 | ||
| 51 | +// private TextView textView, textover; | ||
| 52 | +// | ||
| 53 | +// public void setTypeLisenter(TypeListener typeLisenter) { | ||
| 54 | +// this.typeLisenter = typeLisenter; | ||
| 55 | +// } | ||
| 56 | +// | ||
| 57 | +// public void setCaptureLisenter(CaptureListener captureLisenter) { | ||
| 58 | +// this.captureLisenter = captureLisenter; | ||
| 59 | +// } | ||
| 60 | +// | ||
| 61 | +// public void setReturnLisenter(ReturnListener returnListener) { | ||
| 62 | +// this.returnListener = returnListener; | ||
| 63 | +// } | ||
| 64 | +// | ||
| 65 | +// public OnLineCaptureButton btn_capture; //拍照按钮 | ||
| 66 | +// // private TypeButton btn_cancel,btn_confirm; //取消按钮 | ||
| 67 | +// private ImageView iv_custom_left; //左边自定义按钮 | ||
| 68 | +// private ImageView iv_custom_right; //右边自定义按钮 | ||
| 69 | +// private TextView txt_tip; //提示文本 | ||
| 70 | +// | ||
| 71 | +// private int layout_width; | ||
| 72 | +// private int layout_height; | ||
| 73 | +// private int button_size; | ||
| 74 | +// private int iconLeft = 0; | ||
| 75 | +// private int iconRight = 0; | ||
| 76 | +// | ||
| 77 | +// private boolean isFirst = true; | ||
| 78 | +// | ||
| 79 | +// private JiaShenUploadDialog uploadDialog; | ||
| 80 | +// | ||
| 81 | +// public OnLineCaptureLayout(Context context) { | ||
| 82 | +// this(context, null); | ||
| 83 | +// } | ||
| 84 | +// | ||
| 85 | +// public OnLineCaptureLayout(Context context, AttributeSet attrs) { | ||
| 86 | +// this(context, attrs, 0); | ||
| 87 | +// } | ||
| 88 | +// | ||
| 89 | +// public OnLineCaptureLayout(Context context, AttributeSet attrs, int defStyleAttr) { | ||
| 90 | +// super(context, attrs, defStyleAttr); | ||
| 91 | +// if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { | ||
| 92 | +// layout_width = dip2px(250); | ||
| 93 | +// // layout_width = outMetrics.widthPixels; | ||
| 94 | +// } else { | ||
| 95 | +// layout_width = dip2px(250); | ||
| 96 | +// } | ||
| 97 | +// layout_height = dip2px(100); | ||
| 98 | +// button_size = dip2px(50); | ||
| 99 | +// initView(); | ||
| 100 | +// initEvent(); | ||
| 101 | +// } | ||
| 102 | +// | ||
| 103 | +// @Override | ||
| 104 | +// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 105 | +// super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 106 | +// setMeasuredDimension(layout_width, layout_height); | ||
| 107 | +// } | ||
| 108 | +// | ||
| 109 | +// public void initEvent() { | ||
| 110 | +// iv_custom_right.setVisibility(GONE); | ||
| 111 | +// textover.setVisibility(GONE); | ||
| 112 | +// textView.setVisibility(GONE); | ||
| 113 | +// } | ||
| 114 | +// | ||
| 115 | +// public void startTypeBtnAnimator() { | ||
| 116 | +// if (checkErrorState()) return; | ||
| 117 | +// //拍照录制结果后的动画 | ||
| 118 | +// if (this.iconLeft != 0) | ||
| 119 | +// iv_custom_left.setVisibility(GONE); | ||
| 120 | +// if (this.iconRight != 0) | ||
| 121 | +// iv_custom_right.setVisibility(GONE); | ||
| 122 | +// btn_capture.setVisibility(GONE); | ||
| 123 | +// textView.setVisibility(VISIBLE); | ||
| 124 | +// textover.setVisibility(VISIBLE); | ||
| 125 | +// textView.setClickable(false); | ||
| 126 | +// textover.setClickable(false); | ||
| 127 | +// ObjectAnimator textview = ObjectAnimator.ofFloat(textView, "translationX", -layout_width / 4, 0); | ||
| 128 | +// ObjectAnimator textvie = ObjectAnimator.ofFloat(textover, "translationX", layout_width / 4, 0); | ||
| 129 | +// | ||
| 130 | +// AnimatorSet set = new AnimatorSet(); | ||
| 131 | +// set.playTogether(textview, textvie); | ||
| 132 | +// set.addListener(new AnimatorListenerAdapter() { | ||
| 133 | +// @Override | ||
| 134 | +// public void onAnimationEnd(Animator animation) { | ||
| 135 | +// super.onAnimationEnd(animation); | ||
| 136 | +// textView.setClickable(true); | ||
| 137 | +// textover.setClickable(true); | ||
| 138 | +// } | ||
| 139 | +// }); | ||
| 140 | +// set.setDuration(200); | ||
| 141 | +// set.start(); | ||
| 142 | +// } | ||
| 143 | +// | ||
| 144 | +// private void initView() { | ||
| 145 | +// setWillNotDraw(false); | ||
| 146 | +// //拍照按钮 | ||
| 147 | +// btn_capture = new OnLineCaptureButton(getContext(), button_size); | ||
| 148 | +// LayoutParams btn_capture_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); | ||
| 149 | +// btn_capture_param.gravity = Gravity.CENTER; | ||
| 150 | +// btn_capture.setLayoutParams(btn_capture_param); | ||
| 151 | +// textover = new TextView(getContext()); | ||
| 152 | +// LayoutParams textlayo = new LayoutParams(dip2px(80), dip2px(40)); | ||
| 153 | +// textlayo.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; | ||
| 154 | +// textover.setLayoutParams(textlayo); | ||
| 155 | +// textover.setText("上传答案"); | ||
| 156 | +// textover.setGravity(Gravity.CENTER); | ||
| 157 | +// textover.setBackground(getResources().getDrawable(R.drawable.post1)); | ||
| 158 | +// textover.setTextColor(getResources().getColor(R.color.color_bg_dialog)); | ||
| 159 | +// textover.setTextSize(15); | ||
| 160 | +// textover.setOnClickListener(new OnClickListener() { | ||
| 161 | +// @Override | ||
| 162 | +// public void onClick(View view) { | ||
| 163 | +// AlertDialogUtils.showTwoButtonDialog( | ||
| 164 | +// getContext(), | ||
| 165 | +// "否", | ||
| 166 | +// "是", | ||
| 167 | +// "如同意上传将以此次比赛结果为准", | ||
| 168 | +// R.color.color_3F93FD, | ||
| 169 | +// R.color.color_3F93FD, | ||
| 170 | +// new AlertDialogUtils.DialogTwoListener() { | ||
| 171 | +// @Override | ||
| 172 | +// public void onClickLeft(Dialog dialog) { | ||
| 173 | +// dialog.dismiss(); | ||
| 174 | +// } | ||
| 175 | +// | ||
| 176 | +// @Override | ||
| 177 | +// public void onClickRight(Dialog dialog) { | ||
| 178 | +//// if (typeLisenter != null) { | ||
| 179 | +//// typeLisenter.cancel(); | ||
| 180 | +//// } | ||
| 181 | +// showUploadDialog(); | ||
| 182 | +// startAlphaAnimation(); | ||
| 183 | +// dialog.dismiss(); | ||
| 184 | +// } | ||
| 185 | +// }); | ||
| 186 | +// } | ||
| 187 | +// }); | ||
| 188 | +// | ||
| 189 | +// textView = new TextView(getContext()); | ||
| 190 | +// | ||
| 191 | +// | ||
| 192 | +// LayoutParams textlay = new LayoutParams(dip2px(80), dip2px(40)); | ||
| 193 | +// textlay.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT; | ||
| 194 | +// textView.setLayoutParams(textlay); | ||
| 195 | +// textView.setText("放弃答案"); | ||
| 196 | +// textView.setGravity(Gravity.CENTER); | ||
| 197 | +// textView.setBackground(getResources().getDrawable(R.drawable.post)); | ||
| 198 | +// textView.setTextColor(getResources().getColor(R.color.givaup)); | ||
| 199 | +// textView.setTextSize(15); | ||
| 200 | +// | ||
| 201 | +// | ||
| 202 | +// textView.setOnClickListener(new OnClickListener() { | ||
| 203 | +// @Override | ||
| 204 | +// public void onClick(View view) { | ||
| 205 | +// AlertDialogUtils.showTwoButtonDialog( | ||
| 206 | +// getContext(), | ||
| 207 | +// "是", | ||
| 208 | +// "否", | ||
| 209 | +// "如放弃将视为本场考试无效,您确定吗?", | ||
| 210 | +// R.color.color_3F93FD, | ||
| 211 | +// R.color.color_3F93FD, | ||
| 212 | +// new AlertDialogUtils.DialogTwoListener() { | ||
| 213 | +// @Override | ||
| 214 | +// public void onClickLeft(Dialog dialog) { | ||
| 215 | +// if (typeLisenter != null) { | ||
| 216 | +// typeLisenter.confirm(); | ||
| 217 | +// } | ||
| 218 | +// startAlphaAnimation(); | ||
| 219 | +// dialog.dismiss(); | ||
| 220 | +// } | ||
| 221 | +// | ||
| 222 | +// @Override | ||
| 223 | +// public void onClickRight(Dialog dialog) { | ||
| 224 | +// dialog.dismiss(); | ||
| 225 | +// } | ||
| 226 | +// }); | ||
| 227 | +// } | ||
| 228 | +// }); | ||
| 229 | +// | ||
| 230 | +// //左边自定义按钮 | ||
| 231 | +// iv_custom_left = new ImageView(getContext()); | ||
| 232 | +// LayoutParams iv_custom_param_left = new LayoutParams((int) (button_size / 2.5f), (int) (button_size / 2.5f)); | ||
| 233 | +// iv_custom_param_left.gravity = Gravity.CENTER_VERTICAL; | ||
| 234 | +// iv_custom_param_left.setMargins(layout_width / 6, 0, 0, 0); | ||
| 235 | +// iv_custom_left.setLayoutParams(iv_custom_param_left); | ||
| 236 | +// iv_custom_left.setOnClickListener(new OnClickListener() { | ||
| 237 | +// @Override | ||
| 238 | +// public void onClick(View v) { | ||
| 239 | +// if (leftClickListener != null) { | ||
| 240 | +// leftClickListener.onClick(); | ||
| 241 | +// } | ||
| 242 | +// } | ||
| 243 | +// }); | ||
| 244 | +// | ||
| 245 | +// //右边自定义按钮 | ||
| 246 | +// iv_custom_right = new ImageView(getContext()); | ||
| 247 | +// LayoutParams iv_custom_param_right = new LayoutParams((int) (button_size / 2.5f), (int) (button_size / 2.5f)); | ||
| 248 | +// iv_custom_param_right.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; | ||
| 249 | +// iv_custom_param_right.setMargins(0, 0, layout_width / 6, 0); | ||
| 250 | +// iv_custom_right.setLayoutParams(iv_custom_param_right); | ||
| 251 | +// iv_custom_right.setOnClickListener(new OnClickListener() { | ||
| 252 | +// @Override | ||
| 253 | +// public void onClick(View v) { | ||
| 254 | +// if (rightClickListener != null) { | ||
| 255 | +// rightClickListener.onClick(); | ||
| 256 | +// } | ||
| 257 | +// } | ||
| 258 | +// }); | ||
| 259 | +// | ||
| 260 | +// txt_tip = new TextView(getContext()); | ||
| 261 | +// LayoutParams txt_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); | ||
| 262 | +// txt_param.gravity = Gravity.CENTER_HORIZONTAL; | ||
| 263 | +// txt_param.setMargins(0, 0, 0, 0); | ||
| 264 | +// txt_tip.setPadding(0, 0, 0, 50); | ||
| 265 | +// txt_tip.setTextColor(0xFFFFFFFF); | ||
| 266 | +// txt_tip.setGravity(Gravity.CENTER); | ||
| 267 | +// txt_tip.setLayoutParams(txt_param); | ||
| 268 | +// | ||
| 269 | +// this.addView(btn_capture); | ||
| 270 | +// this.addView(iv_custom_left); | ||
| 271 | +// this.addView(iv_custom_right); | ||
| 272 | +// this.addView(txt_tip); | ||
| 273 | +// this.addView(textView); | ||
| 274 | +// this.addView(textover); | ||
| 275 | +// } | ||
| 276 | +// | ||
| 277 | +// public static int dip2px(float dipValue) { | ||
| 278 | +// float scale = Resources.getSystem().getDisplayMetrics().density; | ||
| 279 | +// return (int) (dipValue * scale + 0.5F); | ||
| 280 | +// } | ||
| 281 | +// | ||
| 282 | +// private void showUploadDialog() { | ||
| 283 | +// if (uploadDialog != null) uploadDialog.dismiss(); | ||
| 284 | +// | ||
| 285 | +// if (getContext() == null) return; | ||
| 286 | +// | ||
| 287 | +// uploadDialog = new JiaShenUploadDialog(getContext(), "视频上传中,请勿退出页面"); | ||
| 288 | +// uploadDialog.setCanceledOnTouchOutside(false); | ||
| 289 | +// uploadDialog.setCancelable(false); | ||
| 290 | +// uploadDialog.show(); | ||
| 291 | +// } | ||
| 292 | +// | ||
| 293 | +// /************************************************** | ||
| 294 | +// * 对外提供的API * | ||
| 295 | +// **************************************************/ | ||
| 296 | +// public void resetCaptureLayout() { | ||
| 297 | +// btn_capture.resetRecordAnim(); | ||
| 298 | +// btn_capture.resetState(); | ||
| 299 | +// textover.setVisibility(GONE); | ||
| 300 | +// textView.setVisibility(GONE); | ||
| 301 | +// btn_capture.setVisibility(VISIBLE); | ||
| 302 | +// if (this.iconLeft != 0) | ||
| 303 | +// iv_custom_left.setVisibility(VISIBLE); | ||
| 304 | +// if (this.iconRight != 0) | ||
| 305 | +// iv_custom_right.setVisibility(VISIBLE); | ||
| 306 | +// } | ||
| 307 | +// | ||
| 308 | +// private boolean checkErrorState() { | ||
| 309 | +// if (isErrorState) { | ||
| 310 | +// isErrorState = false; | ||
| 311 | +// return true; | ||
| 312 | +// } | ||
| 313 | +// return false; | ||
| 314 | +// } | ||
| 315 | +// | ||
| 316 | +// public void onError() { | ||
| 317 | +// onError(false); | ||
| 318 | +// } | ||
| 319 | +// | ||
| 320 | +// public void onError(boolean state) { | ||
| 321 | +// isErrorState = state; | ||
| 322 | +// } | ||
| 323 | +// | ||
| 324 | +// public void startAlphaAnimation() { | ||
| 325 | +// if (isFirst) { | ||
| 326 | +// ObjectAnimator animator_txt_tip = ObjectAnimator.ofFloat(txt_tip, "alpha", 1f, 0f); | ||
| 327 | +// animator_txt_tip.setDuration(500); | ||
| 328 | +// animator_txt_tip.start(); | ||
| 329 | +// isFirst = false; | ||
| 330 | +// } | ||
| 331 | +// } | ||
| 332 | +// | ||
| 333 | +// public void setTextWithAnimation(String tip) { | ||
| 334 | +// txt_tip.setText(tip); | ||
| 335 | +// ObjectAnimator animator_txt_tip = ObjectAnimator.ofFloat(txt_tip, "alpha", 0f, 1f, 1f, 0f); | ||
| 336 | +// animator_txt_tip.setDuration(2500); | ||
| 337 | +// animator_txt_tip.start(); | ||
| 338 | +// } | ||
| 339 | +// | ||
| 340 | +// public void setDuration(int duration) { | ||
| 341 | +// btn_capture.setDuration(duration); | ||
| 342 | +// } | ||
| 343 | +// | ||
| 344 | +// public void setButtonFeatures(int state) { | ||
| 345 | +// if (state == BUTTON_STATE_BOTH) { | ||
| 346 | +// txt_tip.setText("轻触拍照,长按摄像"); | ||
| 347 | +// } else if (state == BUTTON_STATE_ONLY_CAPTURE) { | ||
| 348 | +// txt_tip.setText("轻触拍照"); | ||
| 349 | +// } else if (state == BUTTON_STATE_ONLY_RECORDER) { | ||
| 350 | +// txt_tip.setText(""); | ||
| 351 | +// } | ||
| 352 | +// btn_capture.setButtonFeatures(state); | ||
| 353 | +// } | ||
| 354 | +// | ||
| 355 | +// public void setTip(String tip) { | ||
| 356 | +// txt_tip.setText(tip); | ||
| 357 | +// } | ||
| 358 | +// | ||
| 359 | +// public void showTip() { | ||
| 360 | +// txt_tip.setVisibility(VISIBLE); | ||
| 361 | +// } | ||
| 362 | +// | ||
| 363 | +// public void setIconSrc(int iconLeft, int iconRight) { | ||
| 364 | +// this.iconLeft = iconLeft; | ||
| 365 | +// this.iconRight = iconRight; | ||
| 366 | +// if (this.iconLeft != 0) { | ||
| 367 | +// iv_custom_left.setImageResource(iconLeft); | ||
| 368 | +// iv_custom_left.setVisibility(VISIBLE); | ||
| 369 | +// } else { | ||
| 370 | +// iv_custom_left.setVisibility(GONE); | ||
| 371 | +// } | ||
| 372 | +// if (this.iconRight != 0) { | ||
| 373 | +// iv_custom_right.setImageResource(iconRight); | ||
| 374 | +// iv_custom_right.setVisibility(VISIBLE); | ||
| 375 | +// } else { | ||
| 376 | +// iv_custom_right.setVisibility(GONE); | ||
| 377 | +// } | ||
| 378 | +// } | ||
| 379 | +// | ||
| 380 | +// public void setLeftClickListener(ClickListener leftClickListener) { | ||
| 381 | +// this.leftClickListener = leftClickListener; | ||
| 382 | +// } | ||
| 383 | +// | ||
| 384 | +// public void setRightClickListener(ClickListener rightClickListener) { | ||
| 385 | +// this.rightClickListener = rightClickListener; | ||
| 386 | +// } | ||
| 387 | +// | ||
| 388 | +// public void showTake() { | ||
| 389 | +// btn_capture.setOnClickListener(new OnClickListener() { | ||
| 390 | +// @Override | ||
| 391 | +// public void onClick(View v) { | ||
| 392 | +// if (captureLisenter != null) { | ||
| 393 | +// captureLisenter.recordEnd(20000); | ||
| 394 | +// } | ||
| 395 | +// startAlphaAnimation(); | ||
| 396 | +// startTypeBtnAnimator(); | ||
| 397 | +// } | ||
| 398 | +// }); | ||
| 399 | +// } | ||
| 400 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/ReturnButton.java
| @@ -25,6 +25,7 @@ import com.cnlive.media.R; | @@ -25,6 +25,7 @@ import com.cnlive.media.R; | ||
| 25 | public class ReturnButton extends View { | 25 | public class ReturnButton extends View { |
| 26 | 26 | ||
| 27 | private int size; | 27 | private int size; |
| 28 | + | ||
| 28 | private int center_X; | 29 | private int center_X; |
| 29 | private int center_Y; | 30 | private int center_Y; |
| 30 | private float strokeWidth; | 31 | private float strokeWidth; |
| @@ -32,45 +33,38 @@ public class ReturnButton extends View { | @@ -32,45 +33,38 @@ public class ReturnButton extends View { | ||
| 32 | private Paint paint; | 33 | private Paint paint; |
| 33 | Path path; | 34 | Path path; |
| 34 | 35 | ||
| 35 | - public ReturnButton(Context context) { | ||
| 36 | - this(context, null); | ||
| 37 | - } | ||
| 38 | - | ||
| 39 | - public ReturnButton(Context context, @Nullable AttributeSet attrs) { | ||
| 40 | - this(context, attrs, 0); | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - public ReturnButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | ||
| 44 | - super(context, attrs, defStyleAttr); | ||
| 45 | - TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ReturnButtonStyle); | ||
| 46 | - | ||
| 47 | - size = typedArray.getDimensionPixelSize(R.styleable.ReturnButtonStyle_strokeWidth, 20); | ||
| 48 | - int strokeColor = typedArray.getColor(R.styleable.ReturnButtonStyle_strokeColor, Color.GREEN); | ||
| 49 | - typedArray.recycle(); | 36 | + public ReturnButton(Context context, int size) { |
| 37 | + this(context); | ||
| 38 | + this.size = size; | ||
| 50 | center_X = size / 2; | 39 | center_X = size / 2; |
| 51 | center_Y = size / 2; | 40 | center_Y = size / 2; |
| 41 | + | ||
| 52 | strokeWidth = size / 15f; | 42 | strokeWidth = size / 15f; |
| 43 | + | ||
| 53 | paint = new Paint(); | 44 | paint = new Paint(); |
| 54 | paint.setAntiAlias(true); | 45 | paint.setAntiAlias(true); |
| 55 | - paint.setColor(strokeColor); | 46 | + paint.setColor(0xffffa300); |
| 56 | paint.setStyle(Paint.Style.STROKE); | 47 | paint.setStyle(Paint.Style.STROKE); |
| 57 | paint.setStrokeWidth(strokeWidth); | 48 | paint.setStrokeWidth(strokeWidth); |
| 49 | + | ||
| 58 | path = new Path(); | 50 | path = new Path(); |
| 51 | + } | ||
| 59 | 52 | ||
| 53 | + public ReturnButton(Context context) { | ||
| 54 | + super(context); | ||
| 60 | } | 55 | } |
| 61 | 56 | ||
| 62 | @Override | 57 | @Override |
| 63 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | 58 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 64 | - | ||
| 65 | setMeasuredDimension(size, size / 2); | 59 | setMeasuredDimension(size, size / 2); |
| 66 | } | 60 | } |
| 67 | 61 | ||
| 68 | @Override | 62 | @Override |
| 69 | protected void onDraw(Canvas canvas) { | 63 | protected void onDraw(Canvas canvas) { |
| 70 | super.onDraw(canvas); | 64 | super.onDraw(canvas); |
| 71 | - path.moveTo(strokeWidth, strokeWidth / 2); | ||
| 72 | - path.lineTo(center_X, center_Y - strokeWidth / 2); | ||
| 73 | - path.lineTo(size - strokeWidth, strokeWidth / 2); | 65 | + path.moveTo(strokeWidth, strokeWidth/2); |
| 66 | + path.lineTo(center_X, center_Y - strokeWidth/2); | ||
| 67 | + path.lineTo(size - strokeWidth, strokeWidth/2); | ||
| 74 | 68 | ||
| 75 | canvas.drawPath(path, paint); | 69 | canvas.drawPath(path, paint); |
| 76 | } | 70 | } |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/TypeButton.java
| @@ -23,37 +23,93 @@ public class TypeButton extends androidx.appcompat.widget.AppCompatImageView { | @@ -23,37 +23,93 @@ public class TypeButton extends androidx.appcompat.widget.AppCompatImageView { | ||
| 23 | 23 | ||
| 24 | public static final int TYPE_CANCEL = 0x001; | 24 | public static final int TYPE_CANCEL = 0x001; |
| 25 | public static final int TYPE_CONFIRM = 0x002; | 25 | public static final int TYPE_CONFIRM = 0x002; |
| 26 | + // private int button_type; | ||
| 26 | private int button_size; | 27 | private int button_size; |
| 27 | 28 | ||
| 28 | - public TypeButton(@NonNull Context context) { | ||
| 29 | - this(context, null); | ||
| 30 | - } | ||
| 31 | - | ||
| 32 | - public TypeButton(@NonNull Context context, @Nullable AttributeSet attrs) { | ||
| 33 | - this(context, attrs, 0); | ||
| 34 | - } | 29 | +// private float center_X; |
| 30 | +// private float center_Y; | ||
| 31 | +// private float button_radius; | ||
| 35 | 32 | ||
| 36 | - public TypeButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | ||
| 37 | - super(context, attrs, defStyleAttr); | 33 | +// private Paint mPaint; |
| 34 | +// private Path path; | ||
| 35 | +// private float strokeWidth; | ||
| 38 | 36 | ||
| 39 | - TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TypeButtonStyle); | ||
| 40 | - int drawable = array.getResourceId(R.styleable.TypeButtonStyle_typeBg, R.drawable.fb_wancheng); | ||
| 41 | - float typeSize = array.getDimension(R.styleable.TypeButtonStyle_typeSize, 30); | ||
| 42 | - setImageResource(drawable); | ||
| 43 | - button_size = (int)typeSize; | 37 | + private float index; |
| 38 | +// private RectF rectF; | ||
| 44 | 39 | ||
| 45 | - array.recycle(); | 40 | + public TypeButton(Context context, int type, int size) { |
| 41 | + super(context); | ||
| 42 | + if (type == TYPE_CANCEL) { | ||
| 43 | + setImageResource(R.drawable.fb_wancheng); | ||
| 44 | + } | ||
| 45 | + if (type == TYPE_CONFIRM){ | ||
| 46 | + setImageResource(R.drawable.fb_chongpai); | ||
| 47 | + } | ||
| 48 | +// this.button_type = type; | ||
| 49 | + button_size = size; | ||
| 50 | +// button_radius = size / 2.0f; | ||
| 51 | +// center_X = size / 2.0f; | ||
| 52 | +// center_Y = size / 2.0f; | ||
| 46 | 53 | ||
| 54 | +// mPaint = new Paint(); | ||
| 55 | +// path = new Path(); | ||
| 56 | +// strokeWidth = size / 50f; | ||
| 57 | +// index = button_size / 12f; | ||
| 58 | +// rectF = new RectF(center_X, center_Y - index, center_X + index * 2, center_Y + index); | ||
| 47 | } | 59 | } |
| 48 | 60 | ||
| 49 | -// public TypeButton(Context context, int type, int size) { | ||
| 50 | -// super(context); | ||
| 51 | - | ||
| 52 | -// } | ||
| 53 | - | ||
| 54 | @Override | 61 | @Override |
| 55 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | 62 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 56 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); | 63 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
| 57 | setMeasuredDimension(button_size, button_size); | 64 | setMeasuredDimension(button_size, button_size); |
| 58 | } | 65 | } |
| 66 | + | ||
| 67 | +// @Override | ||
| 68 | +// protected void onDraw(Canvas canvas) { | ||
| 69 | +// super.onDraw(canvas); | ||
| 70 | +// //如果类型为取消,则绘制内部为返回箭头 | ||
| 71 | +// if (button_type == TYPE_CANCEL) { | ||
| 72 | +// mPaint.setAntiAlias(true); | ||
| 73 | +// mPaint.setColor(0xEEDCDCDC); | ||
| 74 | +// mPaint.setStyle(Paint.Style.FILL); | ||
| 75 | +// canvas.drawCircle(center_X, center_Y, button_radius, mPaint); | ||
| 76 | +// | ||
| 77 | +// mPaint.setColor(Color.BLACK); | ||
| 78 | +// mPaint.setStyle(Paint.Style.STROKE); | ||
| 79 | +// mPaint.setStrokeWidth(strokeWidth); | ||
| 80 | +// | ||
| 81 | +// path.moveTo(center_X - index / 7, center_Y + index); | ||
| 82 | +// path.lineTo(center_X + index, center_Y + index); | ||
| 83 | +// | ||
| 84 | +// path.arcTo(rectF, 90, -180); | ||
| 85 | +// path.lineTo(center_X - index, center_Y - index); | ||
| 86 | +// canvas.drawPath(path, mPaint); | ||
| 87 | +// mPaint.setStyle(Paint.Style.FILL); | ||
| 88 | +// path.reset(); | ||
| 89 | +// path.moveTo(center_X - index, (float) (center_Y - index * 1.5)); | ||
| 90 | +// path.lineTo(center_X - index, (float) (center_Y - index / 2.3)); | ||
| 91 | +// path.lineTo((float) (center_X - index * 1.6), center_Y - index); | ||
| 92 | +// path.close(); | ||
| 93 | +// canvas.drawPath(path, mPaint); | ||
| 94 | +// | ||
| 95 | +// } | ||
| 96 | +// //如果类型为确认,则绘制绿色勾 | ||
| 97 | +// if (button_type == TYPE_CONFIRM) { | ||
| 98 | +// mPaint.setAntiAlias(true); | ||
| 99 | +// mPaint.setColor(0xFFFFFFFF); | ||
| 100 | +// mPaint.setStyle(Paint.Style.FILL); | ||
| 101 | +// canvas.drawCircle(center_X, center_Y, button_radius, mPaint); | ||
| 102 | +// mPaint.setAntiAlias(true); | ||
| 103 | +// mPaint.setStyle(Paint.Style.STROKE); | ||
| 104 | +// mPaint.setColor(0xFF00CC00); | ||
| 105 | +// mPaint.setStrokeWidth(strokeWidth); | ||
| 106 | +// | ||
| 107 | +// path.moveTo(center_X - button_size / 6f, center_Y); | ||
| 108 | +// path.lineTo(center_X - button_size / 21.2f, center_Y + button_size / 7.7f); | ||
| 109 | +// path.lineTo(center_X + button_size / 4.0f, center_Y - button_size / 8.5f); | ||
| 110 | +// path.lineTo(center_X - button_size / 21.2f, center_Y + button_size / 9.4f); | ||
| 111 | +// path.close(); | ||
| 112 | +// canvas.drawPath(path, mPaint); | ||
| 113 | +// } | ||
| 114 | +// } | ||
| 59 | } | 115 | } |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/BorrowPictureState.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record.state; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.view.Surface; | ||
| 5 | +import android.view.SurfaceHolder; | ||
| 6 | + | ||
| 7 | +import com.cnlive.media.ui.widget.record.CameraInterface; | ||
| 8 | +import com.cnlive.media.ui.widget.record.JCameraView; | ||
| 9 | +import com.cnlive.media.utils.LogUtil; | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * ===================================== | ||
| 14 | + * 作 者: 陈嘉桐 | ||
| 15 | + * 版 本:1.1.4 | ||
| 16 | + * 创建日期:2017/9/8 | ||
| 17 | + * 描 述: | ||
| 18 | + * ===================================== | ||
| 19 | + */ | ||
| 20 | +public class BorrowPictureState implements State { | ||
| 21 | + private final String TAG = "BorrowPictureState"; | ||
| 22 | + private CameraMachine machine; | ||
| 23 | + | ||
| 24 | + public BorrowPictureState(CameraMachine machine) { | ||
| 25 | + this.machine = machine; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 30 | + if (CameraInterface.getInstance().doStartPreview(holder, screenProp)) { | ||
| 31 | + machine.setState(machine.getPreviewState()); | ||
| 32 | + return true; | ||
| 33 | + } | ||
| 34 | + return false; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + @Override | ||
| 38 | + public void stop() { | ||
| 39 | + | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public boolean foucs(float x, float y, CameraInterface.FocusCallback callback) { | ||
| 45 | + return false; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 50 | + return false; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @Override | ||
| 54 | + public void restart() { | ||
| 55 | + | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + @Override | ||
| 59 | + public boolean capture() { | ||
| 60 | + return false; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @Override | ||
| 64 | + public boolean record(Surface surface, float screenProp, Context context) { | ||
| 65 | + return false; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @Override | ||
| 69 | + public void stopRecord(boolean isShort, long time) { | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + @Override | ||
| 73 | + public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 74 | + CameraInterface.getInstance().doStartPreview(holder, screenProp); | ||
| 75 | + machine.getView().resetState(JCameraView.TYPE_PICTURE); | ||
| 76 | + machine.setState(machine.getPreviewState()); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + @Override | ||
| 80 | + public void confirm() { | ||
| 81 | + machine.getView().confirmState(JCameraView.TYPE_PICTURE); | ||
| 82 | + machine.setState(machine.getPreviewState()); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + @Override | ||
| 86 | + public void zoom(float zoom, int type) { | ||
| 87 | + LogUtil.i(TAG, "zoom"); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @Override | ||
| 91 | + public void flash(String mode) { | ||
| 92 | + return ; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + @Override | ||
| 96 | + public void onDestroy() { | ||
| 97 | + CameraInterface.getInstance().onDestroy(); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/BorrowVideoState.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record.state; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.view.Surface; | ||
| 5 | +import android.view.SurfaceHolder; | ||
| 6 | + | ||
| 7 | +import com.cnlive.media.ui.widget.record.CameraInterface; | ||
| 8 | +import com.cnlive.media.ui.widget.record.JCameraView; | ||
| 9 | +import com.cnlive.media.utils.LogUtil; | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * ===================================== | ||
| 14 | + * 作 者: 陈嘉桐 | ||
| 15 | + * 版 本:1.1.4 | ||
| 16 | + * 创建日期:2017/9/8 | ||
| 17 | + * 描 述: | ||
| 18 | + * ===================================== | ||
| 19 | + */ | ||
| 20 | +public class BorrowVideoState implements State { | ||
| 21 | + private final String TAG = "BorrowVideoState"; | ||
| 22 | + private CameraMachine machine; | ||
| 23 | + | ||
| 24 | + public BorrowVideoState(CameraMachine machine) { | ||
| 25 | + this.machine = machine; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 30 | + if (CameraInterface.getInstance().doStartPreview(holder, screenProp)) { | ||
| 31 | + machine.setState(machine.getPreviewState()); | ||
| 32 | + return true; | ||
| 33 | + } | ||
| 34 | + return false; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + @Override | ||
| 38 | + public void stop() { | ||
| 39 | + | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public boolean foucs(float x, float y, CameraInterface.FocusCallback callback) { | ||
| 44 | + return false; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 50 | + return false; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @Override | ||
| 54 | + public void restart() { | ||
| 55 | + | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + @Override | ||
| 59 | + public boolean capture() { | ||
| 60 | + return false; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @Override | ||
| 64 | + public boolean record(Surface surface, float screenProp, Context context) { | ||
| 65 | + return false; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @Override | ||
| 69 | + public void stopRecord(boolean isShort, long time) { | ||
| 70 | + | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + @Override | ||
| 74 | + public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 75 | + machine.getView().resetState(JCameraView.TYPE_VIDEO); | ||
| 76 | + machine.setState(machine.getPreviewState()); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + @Override | ||
| 80 | + public void confirm() { | ||
| 81 | + machine.getView().confirmState(JCameraView.TYPE_VIDEO); | ||
| 82 | + machine.setState(machine.getPreviewState()); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + @Override | ||
| 86 | + public void zoom(float zoom, int type) { | ||
| 87 | + LogUtil.i(TAG, "zoom"); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @Override | ||
| 91 | + public void flash(String mode) { | ||
| 92 | + return ; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + @Override | ||
| 96 | + public void onDestroy() { | ||
| 97 | + CameraInterface.getInstance().onDestroy(); | ||
| 98 | + } | ||
| 99 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/CameraMachine.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record.state; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.view.Surface; | ||
| 5 | +import android.view.SurfaceHolder; | ||
| 6 | + | ||
| 7 | +import com.cnlive.media.ui.widget.record.CameraInterface; | ||
| 8 | +import com.cnlive.media.ui.widget.record.view.CameraView; | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * ===================================== | ||
| 13 | + * 作 者: 陈嘉桐 | ||
| 14 | + * 版 本:1.1.4 | ||
| 15 | + * 创建日期:2017/9/8 | ||
| 16 | + * 描 述: | ||
| 17 | + * ===================================== | ||
| 18 | + */ | ||
| 19 | +public class CameraMachine implements State { | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + private Context context; | ||
| 23 | + private State state; | ||
| 24 | + private CameraView view; | ||
| 25 | +// private CameraInterface.CameraOpenOverCallback cameraOpenOverCallback; | ||
| 26 | + | ||
| 27 | + private State previewState; //浏览状态(空闲) | ||
| 28 | + private State borrowPictureState; //浏览图片 | ||
| 29 | + private State borrowVideoState; //浏览视频 | ||
| 30 | + | ||
| 31 | + public CameraMachine(Context context, CameraView view, CameraInterface.CameraOpenOverCallback | ||
| 32 | + cameraOpenOverCallback) { | ||
| 33 | + this.context = context; | ||
| 34 | + previewState = new PreviewState(this); | ||
| 35 | + borrowPictureState = new BorrowPictureState(this); | ||
| 36 | + borrowVideoState = new BorrowVideoState(this); | ||
| 37 | + //默认设置为空闲状态 | ||
| 38 | + this.state = previewState; | ||
| 39 | +// this.cameraOpenOverCallback = cameraOpenOverCallback; | ||
| 40 | + this.view = view; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public CameraView getView() { | ||
| 44 | + return view; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public Context getContext() { | ||
| 48 | + return context; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + public void setState(State state) { | ||
| 52 | + this.state = state; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public void setDefaultState() { | ||
| 56 | + this.state = previewState; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + //获取浏览图片状态 | ||
| 60 | + State getBorrowPictureState() { | ||
| 61 | + return borrowPictureState; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + //获取浏览视频状态 | ||
| 65 | + State getBorrowVideoState() { | ||
| 66 | + return borrowVideoState; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + //获取空闲状态 | ||
| 70 | + public State getPreviewState() { | ||
| 71 | + return previewState; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + @Override | ||
| 75 | + public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 76 | + return state.start(holder, screenProp); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + @Override | ||
| 80 | + public void stop() { | ||
| 81 | + state.stop(); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + @Override | ||
| 85 | + public boolean foucs(float x, float y, CameraInterface.FocusCallback callback) { | ||
| 86 | + return state.foucs(x, y, callback); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + @Override | ||
| 90 | + public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 91 | + return state.swtich(holder, screenProp); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + @Override | ||
| 95 | + public void restart() { | ||
| 96 | + state.restart(); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + @Override | ||
| 100 | + public boolean capture() { | ||
| 101 | + return state.capture(); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + @Override | ||
| 105 | + public boolean record(Surface surface, float screenProp,Context context) { | ||
| 106 | + return state.record(surface, screenProp,context); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + @Override | ||
| 110 | + public void stopRecord(boolean isShort, long time) { | ||
| 111 | + state.stopRecord(isShort, time); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + @Override | ||
| 115 | + public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 116 | + state.cancle(holder, screenProp); | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + @Override | ||
| 120 | + public void confirm() { | ||
| 121 | + state.confirm(); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + | ||
| 125 | + @Override | ||
| 126 | + public void zoom(float zoom, int type) { | ||
| 127 | + state.zoom(zoom, type); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + @Override | ||
| 131 | + public void flash(String mode) { | ||
| 132 | + state.flash(mode); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + @Override | ||
| 136 | + public void onDestroy() { | ||
| 137 | + if (state != null) state.onDestroy(); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + public State getState() { | ||
| 141 | + return this.state; | ||
| 142 | + } | ||
| 143 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/OnLineBorrowPictureState.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record.state; | ||
| 2 | +// | ||
| 3 | +//import android.content.Context; | ||
| 4 | +//import android.view.Surface; | ||
| 5 | +//import android.view.SurfaceHolder; | ||
| 6 | +// | ||
| 7 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraInterface; | ||
| 8 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraView; | ||
| 9 | +//import com.cnlive.media.utils.LogUtil; | ||
| 10 | +// | ||
| 11 | +// | ||
| 12 | +///** | ||
| 13 | +// * ===================================== | ||
| 14 | +// * 作 者: 陈嘉桐 | ||
| 15 | +// * 版 本:1.1.4 | ||
| 16 | +// * 创建日期:2017/9/8 | ||
| 17 | +// * 描 述: | ||
| 18 | +// * ===================================== | ||
| 19 | +// */ | ||
| 20 | +//public class OnLineBorrowPictureState implements OnLineState { | ||
| 21 | +// private final String TAG = "BorrowPictureState"; | ||
| 22 | +// private OnLineCameraMachine machine; | ||
| 23 | +// | ||
| 24 | +// public OnLineBorrowPictureState(OnLineCameraMachine machine) { | ||
| 25 | +// this.machine = machine; | ||
| 26 | +// } | ||
| 27 | +// | ||
| 28 | +// @Override | ||
| 29 | +// public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 30 | +// if (OnLineCameraInterface.getInstance().doStartPreview(holder, screenProp)) { | ||
| 31 | +// machine.setState(machine.getPreviewState()); | ||
| 32 | +// return true; | ||
| 33 | +// } | ||
| 34 | +// return false; | ||
| 35 | +// } | ||
| 36 | +// | ||
| 37 | +// @Override | ||
| 38 | +// public void stop() { | ||
| 39 | +// | ||
| 40 | +// } | ||
| 41 | +// | ||
| 42 | +// | ||
| 43 | +// @Override | ||
| 44 | +// public boolean foucs(float x, float y, OnLineCameraInterface.FocusCallback callback) { | ||
| 45 | +// return false; | ||
| 46 | +// } | ||
| 47 | +// | ||
| 48 | +// @Override | ||
| 49 | +// public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 50 | +// return false; | ||
| 51 | +// } | ||
| 52 | +// | ||
| 53 | +// @Override | ||
| 54 | +// public void restart() { | ||
| 55 | +// | ||
| 56 | +// } | ||
| 57 | +// | ||
| 58 | +// @Override | ||
| 59 | +// public boolean capture() { | ||
| 60 | +// return false; | ||
| 61 | +// } | ||
| 62 | +// | ||
| 63 | +// @Override | ||
| 64 | +// public boolean record(Surface surface, float screenProp, Context context) { | ||
| 65 | +// return false; | ||
| 66 | +// } | ||
| 67 | +// | ||
| 68 | +// @Override | ||
| 69 | +// public void stopRecord(boolean isShort, long time) { | ||
| 70 | +// } | ||
| 71 | +// | ||
| 72 | +// @Override | ||
| 73 | +// public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 74 | +// OnLineCameraInterface.getInstance().doStartPreview(holder, screenProp); | ||
| 75 | +// machine.getView().resetState(OnLineCameraView.TYPE_PICTURE); | ||
| 76 | +// machine.setState(machine.getPreviewState()); | ||
| 77 | +// } | ||
| 78 | +// | ||
| 79 | +// @Override | ||
| 80 | +// public void confirm() { | ||
| 81 | +// machine.getView().confirmState(OnLineCameraView.TYPE_PICTURE); | ||
| 82 | +// machine.setState(machine.getPreviewState()); | ||
| 83 | +// } | ||
| 84 | +// | ||
| 85 | +// @Override | ||
| 86 | +// public void zoom(float zoom, int type) { | ||
| 87 | +// LogUtil.i(TAG, "zoom"); | ||
| 88 | +// } | ||
| 89 | +// | ||
| 90 | +// @Override | ||
| 91 | +// public void flash(String mode) { | ||
| 92 | +// return ; | ||
| 93 | +// } | ||
| 94 | +// | ||
| 95 | +// @Override | ||
| 96 | +// public void onDestroy() { | ||
| 97 | +// OnLineCameraInterface.getInstance().onDestroy(); | ||
| 98 | +// } | ||
| 99 | +// | ||
| 100 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/OnLineBorrowVideoState.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record.state; | ||
| 2 | +// | ||
| 3 | +//import android.content.Context; | ||
| 4 | +//import android.view.Surface; | ||
| 5 | +//import android.view.SurfaceHolder; | ||
| 6 | +// | ||
| 7 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraInterface; | ||
| 8 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraView; | ||
| 9 | +//import com.cnlive.media.utils.LogUtil; | ||
| 10 | +// | ||
| 11 | +// | ||
| 12 | +///** | ||
| 13 | +// * ===================================== | ||
| 14 | +// * 作 者: 陈嘉桐 | ||
| 15 | +// * 版 本:1.1.4 | ||
| 16 | +// * 创建日期:2017/9/8 | ||
| 17 | +// * 描 述: | ||
| 18 | +// * ===================================== | ||
| 19 | +// */ | ||
| 20 | +//public class OnLineBorrowVideoState implements OnLineState { | ||
| 21 | +// private final String TAG = "BorrowVideoState"; | ||
| 22 | +// private OnLineCameraMachine machine; | ||
| 23 | +// | ||
| 24 | +// public OnLineBorrowVideoState(OnLineCameraMachine machine) { | ||
| 25 | +// this.machine = machine; | ||
| 26 | +// } | ||
| 27 | +// | ||
| 28 | +// @Override | ||
| 29 | +// public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 30 | +// /*if (OnLineCameraInterface.getInstance().doStartPreview(holder, screenProp)) { | ||
| 31 | +// machine.setState(machine.getPreviewState()); | ||
| 32 | +// return true; | ||
| 33 | +// }*/ | ||
| 34 | +// return false; | ||
| 35 | +// } | ||
| 36 | +// | ||
| 37 | +// @Override | ||
| 38 | +// public void stop() { | ||
| 39 | +// | ||
| 40 | +// } | ||
| 41 | +// | ||
| 42 | +// @Override | ||
| 43 | +// public boolean foucs(float x, float y, OnLineCameraInterface.FocusCallback callback) { | ||
| 44 | +// return false; | ||
| 45 | +// } | ||
| 46 | +// | ||
| 47 | +// | ||
| 48 | +// @Override | ||
| 49 | +// public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 50 | +// return false; | ||
| 51 | +// } | ||
| 52 | +// | ||
| 53 | +// @Override | ||
| 54 | +// public void restart() { | ||
| 55 | +// | ||
| 56 | +// } | ||
| 57 | +// | ||
| 58 | +// @Override | ||
| 59 | +// public boolean capture() { | ||
| 60 | +// return false; | ||
| 61 | +// } | ||
| 62 | +// | ||
| 63 | +// @Override | ||
| 64 | +// public boolean record(Surface surface, float screenProp, Context context) { | ||
| 65 | +// return false; | ||
| 66 | +// } | ||
| 67 | +// | ||
| 68 | +// @Override | ||
| 69 | +// public void stopRecord(boolean isShort, long time) { | ||
| 70 | +// | ||
| 71 | +// } | ||
| 72 | +// | ||
| 73 | +// @Override | ||
| 74 | +// public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 75 | +// machine.getView().resetState(OnLineCameraView.TYPE_VIDEO); | ||
| 76 | +// machine.setState(machine.getPreviewState()); | ||
| 77 | +// } | ||
| 78 | +// | ||
| 79 | +// @Override | ||
| 80 | +// public void confirm() { | ||
| 81 | +// machine.getView().confirmState(OnLineCameraView.TYPE_VIDEO); | ||
| 82 | +// machine.setState(machine.getPreviewState()); | ||
| 83 | +// } | ||
| 84 | +// | ||
| 85 | +// @Override | ||
| 86 | +// public void zoom(float zoom, int type) { | ||
| 87 | +// LogUtil.i(TAG, "zoom"); | ||
| 88 | +// } | ||
| 89 | +// | ||
| 90 | +// @Override | ||
| 91 | +// public void flash(String mode) { | ||
| 92 | +// return ; | ||
| 93 | +// } | ||
| 94 | +// | ||
| 95 | +// @Override | ||
| 96 | +// public void onDestroy() { | ||
| 97 | +// OnLineCameraInterface.getInstance().onDestroy(); | ||
| 98 | +// } | ||
| 99 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/OnLineCameraMachine.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record.state; | ||
| 2 | +// | ||
| 3 | +//import android.content.Context; | ||
| 4 | +//import android.view.Surface; | ||
| 5 | +//import android.view.SurfaceHolder; | ||
| 6 | +// | ||
| 7 | +//import com.cnlive.media.ui.widget.record.view.CameraView; | ||
| 8 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraInterface; | ||
| 9 | +// | ||
| 10 | +// | ||
| 11 | +///** | ||
| 12 | +// * ===================================== | ||
| 13 | +// * 作 者: 陈嘉桐 | ||
| 14 | +// * 版 本:1.1.4 | ||
| 15 | +// * 创建日期:2017/9/8 | ||
| 16 | +// * 描 述: | ||
| 17 | +// * ===================================== | ||
| 18 | +// */ | ||
| 19 | +//public class OnLineCameraMachine implements OnLineState { | ||
| 20 | +// | ||
| 21 | +// | ||
| 22 | +// private Context context; | ||
| 23 | +// private OnLineState state; | ||
| 24 | +// private CameraView view; | ||
| 25 | +//// private CameraInterface.CameraOpenOverCallback cameraOpenOverCallback; | ||
| 26 | +// | ||
| 27 | +// private OnLineState previewState; //浏览状态(空闲) | ||
| 28 | +// private OnLineState borrowPictureState; //浏览图片 | ||
| 29 | +// private OnLineState borrowVideoState; //浏览视频 | ||
| 30 | +// | ||
| 31 | +// public OnLineCameraMachine(Context context, CameraView view, OnLineCameraInterface.CameraOpenOverCallback | ||
| 32 | +// cameraOpenOverCallback) { | ||
| 33 | +// this.context = context; | ||
| 34 | +// previewState = new OnLinePreviewState(this); | ||
| 35 | +// borrowPictureState = new OnLineBorrowPictureState(this); | ||
| 36 | +// borrowVideoState = new OnLineBorrowVideoState(this); | ||
| 37 | +// //默认设置为空闲状态 | ||
| 38 | +// this.state = previewState; | ||
| 39 | +//// this.cameraOpenOverCallback = cameraOpenOverCallback; | ||
| 40 | +// this.view = view; | ||
| 41 | +// } | ||
| 42 | +// | ||
| 43 | +// public CameraView getView() { | ||
| 44 | +// return view; | ||
| 45 | +// } | ||
| 46 | +// | ||
| 47 | +// public Context getContext() { | ||
| 48 | +// return context; | ||
| 49 | +// } | ||
| 50 | +// | ||
| 51 | +// public void setState(OnLineState state) { | ||
| 52 | +// this.state = state; | ||
| 53 | +// } | ||
| 54 | +// | ||
| 55 | +// public void setDefaultState() { | ||
| 56 | +// this.state = previewState; | ||
| 57 | +// } | ||
| 58 | +// | ||
| 59 | +// //获取浏览图片状态 | ||
| 60 | +// OnLineState getBorrowPictureState() { | ||
| 61 | +// return borrowPictureState; | ||
| 62 | +// } | ||
| 63 | +// | ||
| 64 | +// //获取浏览视频状态 | ||
| 65 | +// OnLineState getBorrowVideoState() { | ||
| 66 | +// return borrowVideoState; | ||
| 67 | +// } | ||
| 68 | +// | ||
| 69 | +// //获取空闲状态 | ||
| 70 | +// public OnLineState getPreviewState() { | ||
| 71 | +// return previewState; | ||
| 72 | +// } | ||
| 73 | +// | ||
| 74 | +// @Override | ||
| 75 | +// public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 76 | +// return state.start(holder, screenProp); | ||
| 77 | +// } | ||
| 78 | +// | ||
| 79 | +// @Override | ||
| 80 | +// public void stop() { | ||
| 81 | +// state.stop(); | ||
| 82 | +// } | ||
| 83 | +// | ||
| 84 | +// @Override | ||
| 85 | +// public boolean foucs(float x, float y, OnLineCameraInterface.FocusCallback callback) { | ||
| 86 | +// return state.foucs(x, y, callback); | ||
| 87 | +// } | ||
| 88 | +// | ||
| 89 | +// @Override | ||
| 90 | +// public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 91 | +// return state.swtich(holder, screenProp); | ||
| 92 | +// } | ||
| 93 | +// | ||
| 94 | +// @Override | ||
| 95 | +// public void restart() { | ||
| 96 | +// state.restart(); | ||
| 97 | +// } | ||
| 98 | +// | ||
| 99 | +// @Override | ||
| 100 | +// public boolean capture() { | ||
| 101 | +// return state.capture(); | ||
| 102 | +// } | ||
| 103 | +// | ||
| 104 | +// @Override | ||
| 105 | +// public boolean record(Surface surface, float screenProp,Context context) { | ||
| 106 | +// return state.record(surface, screenProp,context); | ||
| 107 | +// } | ||
| 108 | +// | ||
| 109 | +// @Override | ||
| 110 | +// public void stopRecord(boolean isShort, long time) { | ||
| 111 | +// state.stopRecord(isShort, time); | ||
| 112 | +// } | ||
| 113 | +// | ||
| 114 | +// @Override | ||
| 115 | +// public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 116 | +// state.cancle(holder, screenProp); | ||
| 117 | +// } | ||
| 118 | +// | ||
| 119 | +// @Override | ||
| 120 | +// public void confirm() { | ||
| 121 | +// state.confirm(); | ||
| 122 | +// } | ||
| 123 | +// | ||
| 124 | +// | ||
| 125 | +// @Override | ||
| 126 | +// public void zoom(float zoom, int type) { | ||
| 127 | +// state.zoom(zoom, type); | ||
| 128 | +// } | ||
| 129 | +// | ||
| 130 | +// @Override | ||
| 131 | +// public void flash(String mode) { | ||
| 132 | +// state.flash(mode); | ||
| 133 | +// } | ||
| 134 | +// | ||
| 135 | +// @Override | ||
| 136 | +// public void onDestroy() { | ||
| 137 | +// if (state != null) state.onDestroy(); | ||
| 138 | +// } | ||
| 139 | +// | ||
| 140 | +// public OnLineState getState() { | ||
| 141 | +// return this.state; | ||
| 142 | +// } | ||
| 143 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/OnLinePreviewState.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record.state; | ||
| 2 | +// | ||
| 3 | +//import android.content.Context; | ||
| 4 | +//import android.graphics.Bitmap; | ||
| 5 | +//import android.util.Log; | ||
| 6 | +//import android.view.Surface; | ||
| 7 | +//import android.view.SurfaceHolder; | ||
| 8 | +// | ||
| 9 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraInterface; | ||
| 10 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraView; | ||
| 11 | +//import com.cnlive.media.utils.LogUtil; | ||
| 12 | +// | ||
| 13 | +// | ||
| 14 | +///** | ||
| 15 | +// * ===================================== | ||
| 16 | +// * 作 者: 陈嘉桐 | ||
| 17 | +// * 版 本:1.1.4 | ||
| 18 | +// * 创建日期:2017/9/8 | ||
| 19 | +// * 描 述:空闲状态 | ||
| 20 | +// * ===================================== | ||
| 21 | +// */ | ||
| 22 | +//class OnLinePreviewState implements OnLineState { | ||
| 23 | +// public static final String TAG = "PreviewState"; | ||
| 24 | +// | ||
| 25 | +// private OnLineCameraMachine machine; | ||
| 26 | +// | ||
| 27 | +// OnLinePreviewState(OnLineCameraMachine machine) { | ||
| 28 | +// this.machine = machine; | ||
| 29 | +// } | ||
| 30 | +// | ||
| 31 | +// @Override | ||
| 32 | +// public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 33 | +// return OnLineCameraInterface.getInstance().doStartPreview(holder, screenProp); | ||
| 34 | +// } | ||
| 35 | +// | ||
| 36 | +// @Override | ||
| 37 | +// public void stop() { | ||
| 38 | +// OnLineCameraInterface.getInstance().doStopPreview(); | ||
| 39 | +// } | ||
| 40 | +// | ||
| 41 | +// | ||
| 42 | +// @Override | ||
| 43 | +// public boolean foucs(float x, float y, OnLineCameraInterface.FocusCallback callback) { | ||
| 44 | +// LogUtil.i("preview state foucs"); | ||
| 45 | +// try { | ||
| 46 | +// if (machine.getView().handlerFoucs(x, y)) { | ||
| 47 | +// return OnLineCameraInterface.getInstance().handleFocus(machine.getContext(), x, y, callback); | ||
| 48 | +// } | ||
| 49 | +// } catch (Exception e) { | ||
| 50 | +// Log.e("Camera", "", e); | ||
| 51 | +// } | ||
| 52 | +// | ||
| 53 | +// return false; | ||
| 54 | +// } | ||
| 55 | +// | ||
| 56 | +// @Override | ||
| 57 | +// public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 58 | +// return OnLineCameraInterface.getInstance().switchCamera(holder, screenProp); | ||
| 59 | +// } | ||
| 60 | +// | ||
| 61 | +// @Override | ||
| 62 | +// public void restart() { | ||
| 63 | +// | ||
| 64 | +// } | ||
| 65 | +// | ||
| 66 | +// @Override | ||
| 67 | +// public boolean capture() { | ||
| 68 | +// return OnLineCameraInterface.getInstance().takePicture(new OnLineCameraInterface.TakePictureCallback() { | ||
| 69 | +// @Override | ||
| 70 | +// public void captureResult(Bitmap bitmap, boolean isVertical) { | ||
| 71 | +// machine.getView().showPicture(bitmap, isVertical); | ||
| 72 | +// machine.setState(machine.getBorrowPictureState()); | ||
| 73 | +// LogUtil.i("capture"); | ||
| 74 | +// } | ||
| 75 | +// }); | ||
| 76 | +// } | ||
| 77 | +// | ||
| 78 | +// @Override | ||
| 79 | +// public boolean record(Surface surface, float screenProp, Context context) { | ||
| 80 | +// return OnLineCameraInterface.getInstance().startRecord(surface, screenProp, null, context); | ||
| 81 | +// } | ||
| 82 | +// | ||
| 83 | +// @Override | ||
| 84 | +// public void stopRecord(final boolean isShort, long time) { | ||
| 85 | +// OnLineCameraInterface.getInstance().stopRecord(isShort, new OnLineCameraInterface.StopRecordCallback() { | ||
| 86 | +// @Override | ||
| 87 | +// public void recordResult(String url) { | ||
| 88 | +// if (isShort) { | ||
| 89 | +// machine.getView().resetState(OnLineCameraView.TYPE_SHORT); | ||
| 90 | +// } else { | ||
| 91 | +// machine.getView().playVideo(url); | ||
| 92 | +// machine.setState(machine.getBorrowVideoState()); | ||
| 93 | +// } | ||
| 94 | +// } | ||
| 95 | +// }); | ||
| 96 | +// } | ||
| 97 | +// | ||
| 98 | +// @Override | ||
| 99 | +// public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 100 | +// LogUtil.i("浏览状态下,没有 cancle 事件"); | ||
| 101 | +// } | ||
| 102 | +// | ||
| 103 | +// @Override | ||
| 104 | +// public void confirm() { | ||
| 105 | +// LogUtil.i("浏览状态下,没有 confirm 事件"); | ||
| 106 | +// } | ||
| 107 | +// | ||
| 108 | +// @Override | ||
| 109 | +// public void zoom(float zoom, int type) { | ||
| 110 | +// LogUtil.i(TAG, "zoom"); | ||
| 111 | +// OnLineCameraInterface.getInstance().setZoom(zoom, type); | ||
| 112 | +// } | ||
| 113 | +// | ||
| 114 | +// @Override | ||
| 115 | +// public void flash(String mode) { | ||
| 116 | +// OnLineCameraInterface.getInstance().setFlashMode(mode); | ||
| 117 | +// } | ||
| 118 | +// | ||
| 119 | +// @Override | ||
| 120 | +// public void onDestroy() { | ||
| 121 | +// OnLineCameraInterface.getInstance().onDestroy(); | ||
| 122 | +// } | ||
| 123 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/OnLineState.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record.state; | ||
| 2 | +// | ||
| 3 | +//import android.content.Context; | ||
| 4 | +//import android.view.Surface; | ||
| 5 | +//import android.view.SurfaceHolder; | ||
| 6 | +// | ||
| 7 | +//import com.cnlive.media.ui.widget.record.view.OnLineCameraInterface; | ||
| 8 | +// | ||
| 9 | +// | ||
| 10 | +///** | ||
| 11 | +// * ===================================== | ||
| 12 | +// * 作 者: 陈嘉桐 | ||
| 13 | +// * 版 本:1.1.4 | ||
| 14 | +// * 创建日期:2017/9/8 | ||
| 15 | +// * 描 述: | ||
| 16 | +// * ===================================== | ||
| 17 | +// */ | ||
| 18 | +//public interface OnLineState { | ||
| 19 | +// | ||
| 20 | +// boolean start(SurfaceHolder holder, float screenProp); | ||
| 21 | +// | ||
| 22 | +// void stop(); | ||
| 23 | +// | ||
| 24 | +// boolean foucs(float x, float y, OnLineCameraInterface.FocusCallback callback); | ||
| 25 | +// | ||
| 26 | +// boolean swtich(SurfaceHolder holder, float screenProp); | ||
| 27 | +// | ||
| 28 | +// void restart(); | ||
| 29 | +// | ||
| 30 | +// boolean capture(); | ||
| 31 | +// | ||
| 32 | +// boolean record(Surface surface, float screenProp, Context context); | ||
| 33 | +// | ||
| 34 | +// void stopRecord(boolean isShort, long time); | ||
| 35 | +// | ||
| 36 | +// void cancle(SurfaceHolder holder, float screenProp); | ||
| 37 | +// | ||
| 38 | +// void confirm(); | ||
| 39 | +// | ||
| 40 | +// void zoom(float zoom, int type); | ||
| 41 | +// | ||
| 42 | +// void flash(String mode); | ||
| 43 | +// | ||
| 44 | +// void onDestroy(); | ||
| 45 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/PreviewState.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record.state; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.graphics.Bitmap; | ||
| 5 | +import android.util.Log; | ||
| 6 | +import android.view.Surface; | ||
| 7 | +import android.view.SurfaceHolder; | ||
| 8 | + | ||
| 9 | +import com.cnlive.media.ui.widget.record.CameraInterface; | ||
| 10 | +import com.cnlive.media.ui.widget.record.JCameraView; | ||
| 11 | +import com.cnlive.media.utils.LogUtil; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * ===================================== | ||
| 15 | + * 作 者: 陈嘉桐 | ||
| 16 | + * 版 本:1.1.4 | ||
| 17 | + * 创建日期:2017/9/8 | ||
| 18 | + * 描 述:空闲状态 | ||
| 19 | + * ===================================== | ||
| 20 | + */ | ||
| 21 | +class PreviewState implements State { | ||
| 22 | + public static final String TAG = "PreviewState"; | ||
| 23 | + | ||
| 24 | + private CameraMachine machine; | ||
| 25 | + | ||
| 26 | + PreviewState(CameraMachine machine) { | ||
| 27 | + this.machine = machine; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + @Override | ||
| 31 | + public boolean start(SurfaceHolder holder, float screenProp) { | ||
| 32 | + return CameraInterface.getInstance().doStartPreview(holder, screenProp); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + @Override | ||
| 36 | + public void stop() { | ||
| 37 | + CameraInterface.getInstance().doStopPreview(); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + | ||
| 41 | + @Override | ||
| 42 | + public boolean foucs(float x, float y, CameraInterface.FocusCallback callback) { | ||
| 43 | + LogUtil.i("preview state foucs"); | ||
| 44 | + try { | ||
| 45 | + if (machine.getView().handlerFoucs(x, y)) { | ||
| 46 | + return CameraInterface.getInstance().handleFocus(machine.getContext(), x, y, callback); | ||
| 47 | + } | ||
| 48 | + } catch (Exception e) { | ||
| 49 | + Log.e("Camera", "", e); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + return false; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public boolean swtich(SurfaceHolder holder, float screenProp) { | ||
| 57 | + return CameraInterface.getInstance().switchCamera(holder, screenProp); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public void restart() { | ||
| 62 | + | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + public boolean capture() { | ||
| 67 | + return CameraInterface.getInstance().takePicture(new CameraInterface.TakePictureCallback() { | ||
| 68 | + @Override | ||
| 69 | + public void captureResult(Bitmap bitmap, boolean isVertical) { | ||
| 70 | + machine.getView().showPicture(bitmap, isVertical); | ||
| 71 | + machine.setState(machine.getBorrowPictureState()); | ||
| 72 | + LogUtil.i("capture"); | ||
| 73 | + } | ||
| 74 | + }); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + @Override | ||
| 78 | + public boolean record(Surface surface, float screenProp, Context context) { | ||
| 79 | + return CameraInterface.getInstance().startRecord(surface, screenProp, null,context); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + @Override | ||
| 83 | + public void stopRecord(final boolean isShort, long time) { | ||
| 84 | + CameraInterface.getInstance().stopRecord(isShort, new CameraInterface.StopRecordCallback() { | ||
| 85 | + @Override | ||
| 86 | + public void recordResult(String url) { | ||
| 87 | + if (isShort) { | ||
| 88 | + machine.getView().resetState(JCameraView.TYPE_SHORT); | ||
| 89 | + } else { | ||
| 90 | + machine.getView().playVideo(url); | ||
| 91 | + machine.setState(machine.getBorrowVideoState()); | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + }); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + @Override | ||
| 98 | + public void cancle(SurfaceHolder holder, float screenProp) { | ||
| 99 | + LogUtil.i("浏览状态下,没有 cancle 事件"); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + @Override | ||
| 103 | + public void confirm() { | ||
| 104 | + LogUtil.i("浏览状态下,没有 confirm 事件"); | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + @Override | ||
| 108 | + public void zoom(float zoom, int type) { | ||
| 109 | + LogUtil.i(TAG, "zoom"); | ||
| 110 | + CameraInterface.getInstance().setZoom(zoom, type); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + @Override | ||
| 114 | + public void flash(String mode) { | ||
| 115 | + CameraInterface.getInstance().setFlashMode(mode); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + @Override | ||
| 119 | + public void onDestroy() { | ||
| 120 | + CameraInterface.getInstance().onDestroy(); | ||
| 121 | + } | ||
| 122 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/state/State.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record.state; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.view.Surface; | ||
| 5 | +import android.view.SurfaceHolder; | ||
| 6 | + | ||
| 7 | +import com.cnlive.media.ui.widget.record.CameraInterface; | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * ===================================== | ||
| 12 | + * 作 者: 陈嘉桐 | ||
| 13 | + * 版 本:1.1.4 | ||
| 14 | + * 创建日期:2017/9/8 | ||
| 15 | + * 描 述: | ||
| 16 | + * ===================================== | ||
| 17 | + */ | ||
| 18 | +public interface State { | ||
| 19 | + | ||
| 20 | + boolean start(SurfaceHolder holder, float screenProp); | ||
| 21 | + | ||
| 22 | + void stop(); | ||
| 23 | + | ||
| 24 | + boolean foucs(float x, float y, CameraInterface.FocusCallback callback); | ||
| 25 | + | ||
| 26 | + boolean swtich(SurfaceHolder holder, float screenProp); | ||
| 27 | + | ||
| 28 | + void restart(); | ||
| 29 | + | ||
| 30 | + boolean capture(); | ||
| 31 | + | ||
| 32 | + boolean record(Surface surface, float screenProp, Context context); | ||
| 33 | + | ||
| 34 | + void stopRecord(boolean isShort, long time); | ||
| 35 | + | ||
| 36 | + void cancle(SurfaceHolder holder, float screenProp); | ||
| 37 | + | ||
| 38 | + void confirm(); | ||
| 39 | + | ||
| 40 | + void zoom(float zoom, int type); | ||
| 41 | + | ||
| 42 | + void flash(String mode); | ||
| 43 | + | ||
| 44 | + void onDestroy(); | ||
| 45 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/view/CameraView.java
0 → 100644
| 1 | +package com.cnlive.media.ui.widget.record.view; | ||
| 2 | + | ||
| 3 | +import android.graphics.Bitmap; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * ===================================== | ||
| 7 | + * 作 者: 陈嘉桐 | ||
| 8 | + * 版 本:1.1.4 | ||
| 9 | + * 创建日期:2017/9/8 | ||
| 10 | + * 描 述: | ||
| 11 | + * ===================================== | ||
| 12 | + */ | ||
| 13 | +public interface CameraView { | ||
| 14 | + void resetState(int type); | ||
| 15 | + | ||
| 16 | + void confirmState(int type); | ||
| 17 | + | ||
| 18 | + void showPicture(Bitmap bitmap, boolean isVertical); | ||
| 19 | + | ||
| 20 | + void playVideo(String url); | ||
| 21 | + | ||
| 22 | + void stopVideo(); | ||
| 23 | + | ||
| 24 | + void setTip(String tip); | ||
| 25 | + | ||
| 26 | + void startPreviewCallback(); | ||
| 27 | + | ||
| 28 | + boolean handlerFoucs(float x, float y); | ||
| 29 | + | ||
| 30 | + void pausePlayer(); | ||
| 31 | + void resumePlayer(); | ||
| 32 | +} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/view/OnLineCameraInterface.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record.view; | ||
| 2 | +// | ||
| 3 | +//import static android.graphics.Bitmap.createBitmap; | ||
| 4 | +// | ||
| 5 | +//import android.animation.AnimatorSet; | ||
| 6 | +//import android.animation.ObjectAnimator; | ||
| 7 | +//import android.content.Context; | ||
| 8 | +//import android.graphics.Bitmap; | ||
| 9 | +//import android.graphics.BitmapFactory; | ||
| 10 | +//import android.graphics.ImageFormat; | ||
| 11 | +//import android.graphics.Matrix; | ||
| 12 | +//import android.graphics.Rect; | ||
| 13 | +//import android.graphics.RectF; | ||
| 14 | +//import android.hardware.Camera; | ||
| 15 | +//import android.hardware.Sensor; | ||
| 16 | +//import android.hardware.SensorEvent; | ||
| 17 | +//import android.hardware.SensorEventListener; | ||
| 18 | +//import android.hardware.SensorManager; | ||
| 19 | +//import android.media.MediaRecorder; | ||
| 20 | +//import android.os.Build; | ||
| 21 | +//import android.os.Environment; | ||
| 22 | +//import android.util.Log; | ||
| 23 | +//import android.view.Surface; | ||
| 24 | +//import android.view.SurfaceHolder; | ||
| 25 | +//import android.widget.ImageView; | ||
| 26 | +// | ||
| 27 | +//import com.cnlive.media.ui.widget.record.CheckPermission; | ||
| 28 | +//import com.cnlive.media.ui.widget.record.listener.ErrorListener; | ||
| 29 | +//import com.cnlive.media.utils.AngleUtil; | ||
| 30 | +//import com.cnlive.media.utils.CameraParamUtil; | ||
| 31 | +//import com.cnlive.media.utils.DeviceUtil; | ||
| 32 | +//import com.cnlive.media.utils.FileUtil; | ||
| 33 | +//import com.cnlive.media.utils.LogUtil; | ||
| 34 | +//import com.cnlive.media.utils.ScreenUtils; | ||
| 35 | +// | ||
| 36 | +//import java.io.File; | ||
| 37 | +//import java.io.IOException; | ||
| 38 | +//import java.util.ArrayList; | ||
| 39 | +//import java.util.List; | ||
| 40 | +// | ||
| 41 | +///** | ||
| 42 | +// * ===================================== | ||
| 43 | +// * 作 者: 陈嘉桐 | ||
| 44 | +// * 版 本:1.1.4 | ||
| 45 | +// * 创建日期:2017/4/25 | ||
| 46 | +// * 描 述:camera操作单例 | ||
| 47 | +// * ===================================== | ||
| 48 | +// */ | ||
| 49 | +//@SuppressWarnings("deprecation") | ||
| 50 | +//public class OnLineCameraInterface implements Camera.PreviewCallback { | ||
| 51 | +// | ||
| 52 | +// private static final String TAG = "CJT"; | ||
| 53 | +// | ||
| 54 | +// private volatile static OnLineCameraInterface mCameraInterface; | ||
| 55 | +// | ||
| 56 | +// public static void destroyCameraInterface() { | ||
| 57 | +// if (mCameraInterface != null) { | ||
| 58 | +// mCameraInterface = null; | ||
| 59 | +// } | ||
| 60 | +// } | ||
| 61 | +// | ||
| 62 | +// private Camera mCamera; | ||
| 63 | +// private Camera.Parameters mParams; | ||
| 64 | +// private boolean isPreviewing = false; | ||
| 65 | +// | ||
| 66 | +// private int SELECTED_CAMERA = -1; | ||
| 67 | +// private int CAMERA_POST_POSITION = -1; | ||
| 68 | +// private int CAMERA_FRONT_POSITION = -1; | ||
| 69 | +// | ||
| 70 | +// private SurfaceHolder mHolder = null; | ||
| 71 | +// private float screenProp = -1.0f; | ||
| 72 | +// | ||
| 73 | +// private boolean isRecorder = false; | ||
| 74 | +// private MediaRecorder mediaRecorder; | ||
| 75 | +// private String videoFileName; | ||
| 76 | +// private String saveVideoPath; | ||
| 77 | +// private String videoFileAbsPath; | ||
| 78 | +// | ||
| 79 | +// private ErrorListener errorLisenter; | ||
| 80 | +// | ||
| 81 | +// private ImageView mSwitchView; | ||
| 82 | +// private ImageView mFlashLamp; | ||
| 83 | +// | ||
| 84 | +// private int preview_width; | ||
| 85 | +// private int preview_height; | ||
| 86 | +// | ||
| 87 | +// private int angle = 0; | ||
| 88 | +// private int cameraAngle = 90;//摄像头角度 默认为90度 | ||
| 89 | +// private int rotation = 0; | ||
| 90 | +// private byte[] firstFrame_data; | ||
| 91 | +// | ||
| 92 | +// public static final int TYPE_RECORDER = 0x090; | ||
| 93 | +// public static final int TYPE_CAPTURE = 0x091; | ||
| 94 | +// private int nowScaleRate = 0; | ||
| 95 | +// private int recordScleRate = 0; | ||
| 96 | +// | ||
| 97 | +// //视频质量 | ||
| 98 | +// private int mediaQuality = OnLineCameraView.MEDIA_QUALITY_HIGH; | ||
| 99 | +// | ||
| 100 | +// //获取CameraInterface单例 | ||
| 101 | +// public static synchronized OnLineCameraInterface getInstance() { | ||
| 102 | +// if (mCameraInterface == null) | ||
| 103 | +// synchronized (OnLineCameraInterface.class) { | ||
| 104 | +// if (mCameraInterface == null) | ||
| 105 | +// mCameraInterface = new OnLineCameraInterface(); | ||
| 106 | +// } | ||
| 107 | +// return mCameraInterface; | ||
| 108 | +// } | ||
| 109 | +// | ||
| 110 | +// public void setSwitchView(ImageView mSwitchView, ImageView mFlashLamp) { | ||
| 111 | +// this.mSwitchView = mSwitchView; | ||
| 112 | +// this.mFlashLamp = mFlashLamp; | ||
| 113 | +// if (mSwitchView != null) { | ||
| 114 | +// cameraAngle = CameraParamUtil.getInstance().getCameraDisplayOrientation(mSwitchView.getContext(), | ||
| 115 | +// SELECTED_CAMERA); | ||
| 116 | +// } | ||
| 117 | +// } | ||
| 118 | +// | ||
| 119 | +// private SensorEventListener sensorEventListener = new SensorEventListener() { | ||
| 120 | +// public void onSensorChanged(SensorEvent event) { | ||
| 121 | +// if (Sensor.TYPE_ACCELEROMETER != event.sensor.getType()) { | ||
| 122 | +// return; | ||
| 123 | +// } | ||
| 124 | +// float[] values = event.values; | ||
| 125 | +// angle = AngleUtil.getSensorAngle(values[0], values[1]); | ||
| 126 | +// rotationAnimation(); | ||
| 127 | +// } | ||
| 128 | +// | ||
| 129 | +// public void onAccuracyChanged(Sensor sensor, int accuracy) { | ||
| 130 | +// } | ||
| 131 | +// }; | ||
| 132 | +// | ||
| 133 | +// //切换摄像头icon跟随手机角度进行旋转 | ||
| 134 | +// private void rotationAnimation() { | ||
| 135 | +// if (mSwitchView == null) { | ||
| 136 | +// return; | ||
| 137 | +// } | ||
| 138 | +// if (rotation != angle) { | ||
| 139 | +// int start_rotaion = 0; | ||
| 140 | +// int end_rotation = 0; | ||
| 141 | +// switch (rotation) { | ||
| 142 | +// case 0: | ||
| 143 | +// start_rotaion = 0; | ||
| 144 | +// switch (angle) { | ||
| 145 | +// case 90: | ||
| 146 | +// end_rotation = -90; | ||
| 147 | +// break; | ||
| 148 | +// case 270: | ||
| 149 | +// end_rotation = 90; | ||
| 150 | +// break; | ||
| 151 | +// } | ||
| 152 | +// break; | ||
| 153 | +// case 90: | ||
| 154 | +// start_rotaion = -90; | ||
| 155 | +// switch (angle) { | ||
| 156 | +// case 0: | ||
| 157 | +// end_rotation = 0; | ||
| 158 | +// break; | ||
| 159 | +// case 180: | ||
| 160 | +// end_rotation = -180; | ||
| 161 | +// break; | ||
| 162 | +// } | ||
| 163 | +// break; | ||
| 164 | +// case 180: | ||
| 165 | +// start_rotaion = 180; | ||
| 166 | +// switch (angle) { | ||
| 167 | +// case 90: | ||
| 168 | +// end_rotation = 270; | ||
| 169 | +// break; | ||
| 170 | +// case 270: | ||
| 171 | +// end_rotation = 90; | ||
| 172 | +// break; | ||
| 173 | +// } | ||
| 174 | +// break; | ||
| 175 | +// case 270: | ||
| 176 | +// start_rotaion = 90; | ||
| 177 | +// switch (angle) { | ||
| 178 | +// case 0: | ||
| 179 | +// end_rotation = 0; | ||
| 180 | +// break; | ||
| 181 | +// case 180: | ||
| 182 | +// end_rotation = 180; | ||
| 183 | +// break; | ||
| 184 | +// } | ||
| 185 | +// break; | ||
| 186 | +// } | ||
| 187 | +// ObjectAnimator animC = ObjectAnimator.ofFloat(mSwitchView, "rotation", start_rotaion, end_rotation); | ||
| 188 | +//// ObjectAnimator animF = ObjectAnimator.ofFloat(mFlashLamp, "rotation", start_rotaion, end_rotation); | ||
| 189 | +// AnimatorSet set = new AnimatorSet(); | ||
| 190 | +// set.playTogether(animC); | ||
| 191 | +// set.setDuration(500); | ||
| 192 | +// set.start(); | ||
| 193 | +// rotation = angle; | ||
| 194 | +// } | ||
| 195 | +// } | ||
| 196 | +// | ||
| 197 | +// @SuppressWarnings("ResultOfMethodCallIgnored") | ||
| 198 | +// void setSaveVideoPath(String saveVideoPath) { | ||
| 199 | +// this.saveVideoPath = saveVideoPath; | ||
| 200 | +// File file = new File(saveVideoPath); | ||
| 201 | +// if (!file.exists()) { | ||
| 202 | +// file.mkdirs(); | ||
| 203 | +// } | ||
| 204 | +// } | ||
| 205 | +// | ||
| 206 | +// | ||
| 207 | +// public void setZoom(float zoom, int type) { | ||
| 208 | +// if (mCamera == null) { | ||
| 209 | +// return; | ||
| 210 | +// } | ||
| 211 | +// try { | ||
| 212 | +// if (mParams == null) { | ||
| 213 | +// mParams = mCamera.getParameters(); | ||
| 214 | +// } | ||
| 215 | +// if (!mParams.isZoomSupported() || !mParams.isSmoothZoomSupported()) { | ||
| 216 | +// return; | ||
| 217 | +// } | ||
| 218 | +// switch (type) { | ||
| 219 | +// case TYPE_RECORDER: | ||
| 220 | +// //如果不是录制视频中,上滑不会缩放 | ||
| 221 | +// if (!isRecorder) { | ||
| 222 | +// return; | ||
| 223 | +// } | ||
| 224 | +// if (zoom >= 0) { | ||
| 225 | +// //每移动50个像素缩放一个级别 | ||
| 226 | +// int scaleRate = (int) (zoom / 40); | ||
| 227 | +// if (scaleRate <= mParams.getMaxZoom() && scaleRate >= nowScaleRate && recordScleRate != scaleRate) { | ||
| 228 | +// mParams.setZoom(scaleRate); | ||
| 229 | +// mCamera.setParameters(mParams); | ||
| 230 | +// recordScleRate = scaleRate; | ||
| 231 | +// } | ||
| 232 | +// } | ||
| 233 | +// break; | ||
| 234 | +// case TYPE_CAPTURE: | ||
| 235 | +// if (isRecorder) { | ||
| 236 | +// return; | ||
| 237 | +// } | ||
| 238 | +// //每移动50个像素缩放一个级别 | ||
| 239 | +// int scaleRate = (int) (zoom / 50); | ||
| 240 | +// if (scaleRate < mParams.getMaxZoom()) { | ||
| 241 | +// nowScaleRate += scaleRate; | ||
| 242 | +// if (nowScaleRate < 0) { | ||
| 243 | +// nowScaleRate = 0; | ||
| 244 | +// } else if (nowScaleRate > mParams.getMaxZoom()) { | ||
| 245 | +// nowScaleRate = mParams.getMaxZoom(); | ||
| 246 | +// } | ||
| 247 | +// mParams.setZoom(nowScaleRate); | ||
| 248 | +// mCamera.setParameters(mParams); | ||
| 249 | +// } | ||
| 250 | +// LogUtil.i("setZoom = " + nowScaleRate); | ||
| 251 | +// break; | ||
| 252 | +// } | ||
| 253 | +// } catch (Exception ignored) { | ||
| 254 | +// | ||
| 255 | +// } | ||
| 256 | +// } | ||
| 257 | +// | ||
| 258 | +// | ||
| 259 | +// @Override | ||
| 260 | +// public void onPreviewFrame(byte[] data, Camera camera) { | ||
| 261 | +// firstFrame_data = data; | ||
| 262 | +// } | ||
| 263 | +// | ||
| 264 | +// public void setFlashMode(String flashMode) { | ||
| 265 | +// if (mCamera == null) | ||
| 266 | +// return; | ||
| 267 | +// try { | ||
| 268 | +// | ||
| 269 | +// Camera.Parameters parameters = mCamera.getParameters(); | ||
| 270 | +// List<String> flashModes = parameters.getSupportedFlashModes(); | ||
| 271 | +// if (flashModes == null) { | ||
| 272 | +// return; | ||
| 273 | +// } | ||
| 274 | +// | ||
| 275 | +// if (flashMode.contains(Camera.Parameters.FLASH_MODE_ON)) { | ||
| 276 | +// parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON); | ||
| 277 | +// mCamera.setParameters(parameters); | ||
| 278 | +// } else if (flashMode.contains(Camera.Parameters.FLASH_MODE_OFF)) { | ||
| 279 | +// parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); | ||
| 280 | +// mCamera.setParameters(parameters); | ||
| 281 | +// } | ||
| 282 | +// | ||
| 283 | +// return; | ||
| 284 | +// } catch (Exception e) { | ||
| 285 | +// Log.e("Camera", "闪光灯异常", e); | ||
| 286 | +// } | ||
| 287 | +// return; | ||
| 288 | +// } | ||
| 289 | +// | ||
| 290 | +// public int getSelectedCamera() { | ||
| 291 | +// return SELECTED_CAMERA; | ||
| 292 | +// } | ||
| 293 | +// | ||
| 294 | +// public interface CameraOpenOverCallback { | ||
| 295 | +// void cameraHasOpened(); | ||
| 296 | +// } | ||
| 297 | +// | ||
| 298 | +// private OnLineCameraInterface() { | ||
| 299 | +// findAvailableCameras(); | ||
| 300 | +// SELECTED_CAMERA = CAMERA_POST_POSITION; | ||
| 301 | +// saveVideoPath = ""; | ||
| 302 | +// } | ||
| 303 | +// | ||
| 304 | +// | ||
| 305 | +// /** | ||
| 306 | +// * open Camera | ||
| 307 | +// */ | ||
| 308 | +// void doOpenCamera(CameraOpenOverCallback callback, int id) { | ||
| 309 | +// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { | ||
| 310 | +// if (!CheckPermission.isCameraUseable(id) && this.errorLisenter != null) { | ||
| 311 | +// this.errorLisenter.onError(); | ||
| 312 | +// return; | ||
| 313 | +// } | ||
| 314 | +// } | ||
| 315 | +// if (mCamera == null) { | ||
| 316 | +// openCamera(id); | ||
| 317 | +// } | ||
| 318 | +// callback.cameraHasOpened(); | ||
| 319 | +// } | ||
| 320 | +// | ||
| 321 | +// private void setFlashModel() { | ||
| 322 | +// mParams = mCamera.getParameters(); | ||
| 323 | +// mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); //设置camera参数为Torch模式 | ||
| 324 | +// mCamera.setParameters(mParams); | ||
| 325 | +// } | ||
| 326 | +// | ||
| 327 | +// private synchronized boolean openCamera(int id) { | ||
| 328 | +// try { | ||
| 329 | +// this.mCamera = Camera.open(id); | ||
| 330 | +// } catch (Exception e) { | ||
| 331 | +// if (this.errorLisenter != null) this.errorLisenter.onError(); | ||
| 332 | +// Log.e("CJT", "enable shutter sound faild", e); | ||
| 333 | +// } | ||
| 334 | +// | ||
| 335 | +// try { | ||
| 336 | +// if (Build.VERSION.SDK_INT > 17 && this.mCamera != null) { | ||
| 337 | +// this.mCamera.enableShutterSound(false); | ||
| 338 | +// } | ||
| 339 | +// } catch (Exception e) { | ||
| 340 | +// Log.e("CJT", "enable shutter sound faild", e); | ||
| 341 | +// } | ||
| 342 | +// | ||
| 343 | +// return mCamera != null; | ||
| 344 | +// } | ||
| 345 | +// | ||
| 346 | +// public synchronized boolean switchCamera(SurfaceHolder holder, float screenProp) { | ||
| 347 | +// if (SELECTED_CAMERA == CAMERA_POST_POSITION) { | ||
| 348 | +// SELECTED_CAMERA = CAMERA_FRONT_POSITION; | ||
| 349 | +// } else { | ||
| 350 | +// SELECTED_CAMERA = CAMERA_POST_POSITION; | ||
| 351 | +// } | ||
| 352 | +// doDestroyCamera(); | ||
| 353 | +// LogUtil.i("open start"); | ||
| 354 | +// openCamera(SELECTED_CAMERA); | ||
| 355 | +// if (Build.VERSION.SDK_INT > 17 && this.mCamera != null) { | ||
| 356 | +// try { | ||
| 357 | +// this.mCamera.enableShutterSound(false); | ||
| 358 | +// } catch (Exception e) { | ||
| 359 | +// e.printStackTrace(); | ||
| 360 | +// } | ||
| 361 | +// } | ||
| 362 | +// LogUtil.i("open end"); | ||
| 363 | +// return doStartPreview(holder, screenProp); | ||
| 364 | +// } | ||
| 365 | +// | ||
| 366 | +// /** | ||
| 367 | +// * doStartPreview | ||
| 368 | +// */ | ||
| 369 | +// public boolean doStartPreview(SurfaceHolder holder, float screenProp) { | ||
| 370 | +// if (isPreviewing) { | ||
| 371 | +// LogUtil.i("doStartPreview isPreviewing"); | ||
| 372 | +// } | ||
| 373 | +// if (this.screenProp < 0) { | ||
| 374 | +// this.screenProp = screenProp; | ||
| 375 | +// } | ||
| 376 | +// if (holder == null) { | ||
| 377 | +// return false; | ||
| 378 | +// } | ||
| 379 | +// this.mHolder = holder; | ||
| 380 | +// if (mCamera != null) { | ||
| 381 | +// try { | ||
| 382 | +// mParams = mCamera.getParameters(); | ||
| 383 | +// Camera.Size previewSize = CameraParamUtil.getInstance().getPreviewSize(mParams | ||
| 384 | +// .getSupportedPreviewSizes(), 1000, screenProp); | ||
| 385 | +// Camera.Size pictureSize = CameraParamUtil.getInstance().getPictureSize(mParams | ||
| 386 | +// .getSupportedPictureSizes(), 1200, screenProp); | ||
| 387 | +// | ||
| 388 | +// mParams.setPreviewSize(previewSize.width, previewSize.height); | ||
| 389 | +// | ||
| 390 | +// preview_width = previewSize.width; | ||
| 391 | +// preview_height = previewSize.height; | ||
| 392 | +// | ||
| 393 | +// mParams.setPictureSize(pictureSize.width, pictureSize.height); | ||
| 394 | +// | ||
| 395 | +// if (CameraParamUtil.getInstance().isSupportedFocusMode( | ||
| 396 | +// mParams.getSupportedFocusModes(), | ||
| 397 | +// Camera.Parameters.FOCUS_MODE_AUTO)) { | ||
| 398 | +// mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); | ||
| 399 | +// } | ||
| 400 | +// | ||
| 401 | +// | ||
| 402 | +// List<Camera.Size> sizeList = mParams.getSupportedPreviewSizes(); | ||
| 403 | +// Camera.Size optionSize = getOptimalPreviewSize(sizeList, preview_width - 70, preview_height - 70); | ||
| 404 | +// mParams.setPreviewSize(optionSize.width, optionSize.height); | ||
| 405 | +// if (CameraParamUtil.getInstance().isSupportedPictureFormats(mParams.getSupportedPictureFormats(), | ||
| 406 | +// ImageFormat.JPEG)) { | ||
| 407 | +// mParams.setPictureFormat(ImageFormat.JPEG); | ||
| 408 | +// mParams.setJpegQuality(100); | ||
| 409 | +// } | ||
| 410 | +// mCamera.setParameters(mParams); | ||
| 411 | +// //通过SurfaceView显示预览 | ||
| 412 | +// mCamera.setPreviewDisplay(mHolder); | ||
| 413 | +// mCamera.setDisplayOrientation(cameraAngle); | ||
| 414 | +// mCamera.setPreviewCallback(this); //每一帧回调 | ||
| 415 | +// //开始预览 | ||
| 416 | +// mCamera.startPreview(); | ||
| 417 | +// isPreviewing = true; | ||
| 418 | +// Log.i(TAG, "=== Start Preview ==="); | ||
| 419 | +// return true; | ||
| 420 | +// } catch (Exception e) { | ||
| 421 | +// Log.e("Camera", "开启预览异常", e); | ||
| 422 | +// } | ||
| 423 | +// } | ||
| 424 | +// return false; | ||
| 425 | +// } | ||
| 426 | +// | ||
| 427 | +// | ||
| 428 | +// private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { | ||
| 429 | +// final double ASPECT_TOLERANCE = 0.1; | ||
| 430 | +// double targetRatio = (double) w / h; | ||
| 431 | +// if (sizes == null) return null; | ||
| 432 | +// | ||
| 433 | +// Camera.Size optimalSize = null; | ||
| 434 | +// double minDiff = Double.MAX_VALUE; | ||
| 435 | +// int targetHeight = h; | ||
| 436 | +// | ||
| 437 | +// for (Camera.Size size : sizes) { | ||
| 438 | +// double ratio = (double) size.width / size.height; | ||
| 439 | +// if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; | ||
| 440 | +// if (Math.abs(size.height - targetHeight) < minDiff) { | ||
| 441 | +// optimalSize = size; | ||
| 442 | +// minDiff = Math.abs(size.height - targetHeight); | ||
| 443 | +// } | ||
| 444 | +// } | ||
| 445 | +// if (optimalSize == null) { | ||
| 446 | +// minDiff = Double.MAX_VALUE; | ||
| 447 | +// for (Camera.Size size : sizes) { | ||
| 448 | +// if (Math.abs(size.height - targetHeight) < minDiff) { | ||
| 449 | +// optimalSize = size; | ||
| 450 | +// minDiff = Math.abs(size.height - targetHeight); | ||
| 451 | +// } | ||
| 452 | +// } | ||
| 453 | +// } | ||
| 454 | +// return optimalSize; | ||
| 455 | +// } | ||
| 456 | +// | ||
| 457 | +// | ||
| 458 | +// /** | ||
| 459 | +// * 停止预览 | ||
| 460 | +// */ | ||
| 461 | +// public void doStopPreview() { | ||
| 462 | +// if (null != mCamera) { | ||
| 463 | +// try { | ||
| 464 | +// mCamera.setPreviewCallback(null); | ||
| 465 | +// mCamera.stopPreview(); | ||
| 466 | +// //这句要在stopPreview后执行,不然会卡顿或者花屏 | ||
| 467 | +// mCamera.setPreviewDisplay(null); | ||
| 468 | +// isPreviewing = false; | ||
| 469 | +// mCamera.lock(); | ||
| 470 | +// Log.i(TAG, "=== Stop Preview ==="); | ||
| 471 | +// } catch (Exception e) { | ||
| 472 | +// Log.e("Camera", "", e); | ||
| 473 | +// } | ||
| 474 | +// } | ||
| 475 | +// } | ||
| 476 | +// | ||
| 477 | +// /** | ||
| 478 | +// * 销毁Camera | ||
| 479 | +// */ | ||
| 480 | +// boolean doDestroyCamera() { | ||
| 481 | +// errorLisenter = null; | ||
| 482 | +// if (null != mCamera) { | ||
| 483 | +// try { | ||
| 484 | +// mCamera.setPreviewCallback(null); | ||
| 485 | +// mSwitchView = null; | ||
| 486 | +//// mFlashLamp = null; | ||
| 487 | +// mCamera.stopPreview(); | ||
| 488 | +// //这句要在stopPreview后执行,不然会卡顿或者花屏 | ||
| 489 | +// mCamera.setPreviewDisplay(null); | ||
| 490 | +// mHolder = null; | ||
| 491 | +// isPreviewing = false; | ||
| 492 | +// mCamera.lock(); | ||
| 493 | +// mCamera.release(); | ||
| 494 | +// mCamera = null; | ||
| 495 | +//// destroyCameraInterface(); | ||
| 496 | +// Log.i(TAG, "=== Destroy Camera ==="); | ||
| 497 | +// return true; | ||
| 498 | +// } catch (Exception e) { | ||
| 499 | +// Log.e("Camera", "", e); | ||
| 500 | +// } | ||
| 501 | +// return false; | ||
| 502 | +// } else { | ||
| 503 | +// Log.i(TAG, "=== Camera Null==="); | ||
| 504 | +// } | ||
| 505 | +// return true; | ||
| 506 | +// } | ||
| 507 | +// | ||
| 508 | +// /** | ||
| 509 | +// * 拍照 | ||
| 510 | +// */ | ||
| 511 | +// private int nowAngle; | ||
| 512 | +// | ||
| 513 | +// public boolean takePicture(TakePictureCallback callback) { | ||
| 514 | +// if (mCamera == null) { | ||
| 515 | +// return false; | ||
| 516 | +// } | ||
| 517 | +// switch (cameraAngle) { | ||
| 518 | +// case 90: | ||
| 519 | +// nowAngle = Math.abs(angle + cameraAngle) % 360; | ||
| 520 | +// break; | ||
| 521 | +// case 270: | ||
| 522 | +// nowAngle = Math.abs(cameraAngle - angle); | ||
| 523 | +// break; | ||
| 524 | +// } | ||
| 525 | +//// | ||
| 526 | +// Log.i("CJT", angle + " = " + cameraAngle + " = " + nowAngle); | ||
| 527 | +// try { | ||
| 528 | +// mCamera.takePicture(null, null, new Camera.PictureCallback() { | ||
| 529 | +// @Override | ||
| 530 | +// public void onPictureTaken(byte[] data, Camera camera) { | ||
| 531 | +// Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); | ||
| 532 | +// Matrix matrix = new Matrix(); | ||
| 533 | +// if (SELECTED_CAMERA == CAMERA_POST_POSITION) { | ||
| 534 | +// matrix.setRotate(nowAngle); | ||
| 535 | +// } else if (SELECTED_CAMERA == CAMERA_FRONT_POSITION) { | ||
| 536 | +// matrix.setRotate(360 - nowAngle); | ||
| 537 | +// matrix.postScale(-1, 1); | ||
| 538 | +// } | ||
| 539 | +// | ||
| 540 | +// bitmap = createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); | ||
| 541 | +// if (callback != null) { | ||
| 542 | +// if (nowAngle == 90 || nowAngle == 270) { | ||
| 543 | +// callback.captureResult(bitmap, true); | ||
| 544 | +// } else { | ||
| 545 | +// callback.captureResult(bitmap, false); | ||
| 546 | +// } | ||
| 547 | +// } | ||
| 548 | +// } | ||
| 549 | +// }); | ||
| 550 | +// return true; | ||
| 551 | +// } catch (Exception e) { | ||
| 552 | +// Log.e("Camera", "拍摄异常", e); | ||
| 553 | +// } | ||
| 554 | +// return false; | ||
| 555 | +// } | ||
| 556 | +// | ||
| 557 | +// //启动录像 | ||
| 558 | +// public boolean startRecord(Surface surface, float screenProp, ErrorCallback callback, Context context) { | ||
| 559 | +// if (mCamera == null) return false; | ||
| 560 | +// mCamera.setPreviewCallback(null); | ||
| 561 | +// final int nowAngle = (angle + 90) % 360; | ||
| 562 | +// | ||
| 563 | +// if (isRecorder) { | ||
| 564 | +// return true; | ||
| 565 | +// } | ||
| 566 | +// if (mCamera == null) { | ||
| 567 | +// openCamera(SELECTED_CAMERA); | ||
| 568 | +// } | ||
| 569 | +// if (mCamera == null) { | ||
| 570 | +// return false; | ||
| 571 | +// } | ||
| 572 | +// if (mediaRecorder == null) { | ||
| 573 | +// mediaRecorder = new MediaRecorder(); | ||
| 574 | +// } | ||
| 575 | +// if (mParams == null) { | ||
| 576 | +// mParams = mCamera.getParameters(); | ||
| 577 | +// } | ||
| 578 | +// List<String> focusModes = mParams.getSupportedFocusModes(); | ||
| 579 | +// if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { | ||
| 580 | +// mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); | ||
| 581 | +// } | ||
| 582 | +// try { | ||
| 583 | +// // mParams.set("preview-flip", "flip-v"); | ||
| 584 | +// mCamera.setParameters(mParams); | ||
| 585 | +// } catch (Exception e) { | ||
| 586 | +// | ||
| 587 | +// } | ||
| 588 | +// try { | ||
| 589 | +// mCamera.unlock(); | ||
| 590 | +// } catch (Exception e) { | ||
| 591 | +// | ||
| 592 | +// } | ||
| 593 | +// try { | ||
| 594 | +// mediaRecorder.reset(); | ||
| 595 | +// mediaRecorder.setCamera(mCamera); | ||
| 596 | +// mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); | ||
| 597 | +// mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); | ||
| 598 | +// mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); | ||
| 599 | +// mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); | ||
| 600 | +// mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); | ||
| 601 | +// mediaRecorder.setAudioSamplingRate(44100); | ||
| 602 | +// mediaRecorder.setAudioEncodingBitRate(128000); | ||
| 603 | +// mediaRecorder.setAudioChannels(1); | ||
| 604 | +// | ||
| 605 | +// Camera.Size videoSize; | ||
| 606 | +// if (mParams.getSupportedVideoSizes() == null) { | ||
| 607 | +// videoSize = CameraParamUtil.getInstance().getPreviewSize(mParams.getSupportedPreviewSizes(), 600, | ||
| 608 | +// screenProp); | ||
| 609 | +// } else { | ||
| 610 | +// videoSize = CameraParamUtil.getInstance().getPreviewSize(mParams.getSupportedVideoSizes(), 1280, | ||
| 611 | +// screenProp); | ||
| 612 | +// } | ||
| 613 | +// Log.i(TAG, "setVideoSize width = " + videoSize.width + "height = " + videoSize.height); | ||
| 614 | +// if (videoSize.width == videoSize.height) { | ||
| 615 | +// mediaRecorder.setVideoSize(preview_width, preview_height); | ||
| 616 | +// } else { | ||
| 617 | +// mediaRecorder.setVideoSize(videoSize.width, videoSize.height); | ||
| 618 | +// } | ||
| 619 | +// //手机预览倒立的处理 | ||
| 620 | +// if (cameraAngle == 270) { | ||
| 621 | +// //横屏 | ||
| 622 | +// if (nowAngle == 0) { | ||
| 623 | +// mediaRecorder.setOrientationHint(180); | ||
| 624 | +// } else if (nowAngle == 270) { | ||
| 625 | +// mediaRecorder.setOrientationHint(270); | ||
| 626 | +// } else { | ||
| 627 | +// mediaRecorder.setOrientationHint(90); | ||
| 628 | +// } | ||
| 629 | +// } else { | ||
| 630 | +// if (nowAngle == 90) { | ||
| 631 | +// mediaRecorder.setOrientationHint(270); | ||
| 632 | +// } else if (nowAngle == 270) { | ||
| 633 | +// mediaRecorder.setOrientationHint(90); | ||
| 634 | +// } else { | ||
| 635 | +// mediaRecorder.setOrientationHint(nowAngle); | ||
| 636 | +// } | ||
| 637 | +// } | ||
| 638 | +// | ||
| 639 | +// | ||
| 640 | +// if (DeviceUtil.isHuaWeiRongyao()) { | ||
| 641 | +// mediaRecorder.setVideoEncodingBitRate(4 * 100000); | ||
| 642 | +// } else { | ||
| 643 | +// // mediaRecorder.setVideoEncodingBitRate(mediaQuality); //20 * 100000 | ||
| 644 | +// mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024); | ||
| 645 | +// } | ||
| 646 | +// mediaRecorder.setPreviewDisplay(surface); | ||
| 647 | +// | ||
| 648 | +// videoFileName = "video_" + System.currentTimeMillis() + ".mp4"; | ||
| 649 | +// saveVideoPath = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ? context.getExternalFilesDir("") : Environment.getExternalStorageDirectory()).getPath(); | ||
| 650 | +// videoFileAbsPath = saveVideoPath + File.separator + videoFileName; | ||
| 651 | +// mediaRecorder.setOutputFile(videoFileAbsPath); | ||
| 652 | +// | ||
| 653 | +// mediaRecorder.prepare(); | ||
| 654 | +// mediaRecorder.start(); | ||
| 655 | +// isRecorder = true; | ||
| 656 | +// return true; | ||
| 657 | +// } catch (IllegalStateException e) { | ||
| 658 | +// e.printStackTrace(); | ||
| 659 | +// Log.i("CJT", "startRecord IllegalStateException"); | ||
| 660 | +// if (this.errorLisenter != null) { | ||
| 661 | +// this.errorLisenter.onError(); | ||
| 662 | +// } | ||
| 663 | +// } catch (IOException e) { | ||
| 664 | +// e.printStackTrace(); | ||
| 665 | +// Log.i("CJT", "startRecord IOException"); | ||
| 666 | +// if (this.errorLisenter != null) { | ||
| 667 | +// this.errorLisenter.onError(); | ||
| 668 | +// } | ||
| 669 | +// } catch (RuntimeException e) { | ||
| 670 | +// Log.i("CJT", "startRecord RuntimeException"); | ||
| 671 | +// } catch (Exception e) { | ||
| 672 | +// Log.i("CJT", "startRecord Exception"); | ||
| 673 | +// } | ||
| 674 | +// return false; | ||
| 675 | +// } | ||
| 676 | +// | ||
| 677 | +// public void onDestroy() { | ||
| 678 | +// if (isRecorder) { | ||
| 679 | +// return; | ||
| 680 | +// } | ||
| 681 | +// if (mediaRecorder != null) { | ||
| 682 | +// mediaRecorder.setOnErrorListener(null); | ||
| 683 | +// mediaRecorder.setOnInfoListener(null); | ||
| 684 | +// mediaRecorder.setPreviewDisplay(null); | ||
| 685 | +// try { | ||
| 686 | +// mediaRecorder.stop(); | ||
| 687 | +// } catch (RuntimeException e) { | ||
| 688 | +// e.printStackTrace(); | ||
| 689 | +// mediaRecorder = null; | ||
| 690 | +// mediaRecorder = new MediaRecorder(); | ||
| 691 | +// } finally { | ||
| 692 | +// if (mediaRecorder != null) mediaRecorder.release(); | ||
| 693 | +// mediaRecorder = null; | ||
| 694 | +// isRecorder = false; | ||
| 695 | +// } | ||
| 696 | +// } | ||
| 697 | +// doStopPreview(); | ||
| 698 | +// } | ||
| 699 | +// | ||
| 700 | +// //停止录像 | ||
| 701 | +// public void stopRecord(boolean isShort, StopRecordCallback callback) { | ||
| 702 | +// if (!isRecorder) { | ||
| 703 | +// return; | ||
| 704 | +// } | ||
| 705 | +// if (mediaRecorder != null) { | ||
| 706 | +// mediaRecorder.setOnErrorListener(null); | ||
| 707 | +// mediaRecorder.setOnInfoListener(null); | ||
| 708 | +// mediaRecorder.setPreviewDisplay(null); | ||
| 709 | +// try { | ||
| 710 | +// mediaRecorder.stop(); | ||
| 711 | +// } catch (RuntimeException e) { | ||
| 712 | +// e.printStackTrace(); | ||
| 713 | +// mediaRecorder = null; | ||
| 714 | +// mediaRecorder = new MediaRecorder(); | ||
| 715 | +// } finally { | ||
| 716 | +// if (mediaRecorder != null) { | ||
| 717 | +// mediaRecorder.release(); | ||
| 718 | +// } | ||
| 719 | +// mediaRecorder = null; | ||
| 720 | +// isRecorder = false; | ||
| 721 | +// } | ||
| 722 | +// if (isShort) { | ||
| 723 | +// if (FileUtil.deleteFile(videoFileAbsPath)) { | ||
| 724 | +// callback.recordResult(null); | ||
| 725 | +// } | ||
| 726 | +// return; | ||
| 727 | +// } | ||
| 728 | +// doStopPreview(); | ||
| 729 | +// String fileName = saveVideoPath + File.separator + videoFileName; | ||
| 730 | +// callback.recordResult(fileName); | ||
| 731 | +// } | ||
| 732 | +// } | ||
| 733 | +// | ||
| 734 | +// private void findAvailableCameras() { | ||
| 735 | +// Camera.CameraInfo info = new Camera.CameraInfo(); | ||
| 736 | +// int cameraNum = Camera.getNumberOfCameras(); | ||
| 737 | +// for (int i = 0; i < cameraNum; i++) { | ||
| 738 | +// //TODO 存在异常隐患 | ||
| 739 | +// try { | ||
| 740 | +// Camera.getCameraInfo(i, info); | ||
| 741 | +// } catch (Exception e) { | ||
| 742 | +// Log.e("CameraInterface", "相机信息获取异常", e); | ||
| 743 | +// continue; | ||
| 744 | +// } | ||
| 745 | +// switch (info.facing) { | ||
| 746 | +// case Camera.CameraInfo.CAMERA_FACING_FRONT: | ||
| 747 | +// CAMERA_FRONT_POSITION = info.facing; | ||
| 748 | +// break; | ||
| 749 | +// case Camera.CameraInfo.CAMERA_FACING_BACK: | ||
| 750 | +// CAMERA_POST_POSITION = info.facing; | ||
| 751 | +// break; | ||
| 752 | +// } | ||
| 753 | +// } | ||
| 754 | +// } | ||
| 755 | +// | ||
| 756 | +// private int handlerTime = 0; | ||
| 757 | +// | ||
| 758 | +// public boolean handleFocus(final Context context, final float x, final float y, final FocusCallback callback) { | ||
| 759 | +// if (mCamera == null) { | ||
| 760 | +// return false; | ||
| 761 | +// } | ||
| 762 | +// try { | ||
| 763 | +// final Camera.Parameters params = mCamera.getParameters(); | ||
| 764 | +// Rect focusRect = calculateTapArea(x, y, 1f, context); | ||
| 765 | +// mCamera.cancelAutoFocus(); | ||
| 766 | +// if (params.getMaxNumFocusAreas() > 0) { | ||
| 767 | +// List<Camera.Area> focusAreas = new ArrayList<>(); | ||
| 768 | +// focusAreas.add(new Camera.Area(focusRect, 800)); | ||
| 769 | +// params.setFocusAreas(focusAreas); | ||
| 770 | +// } else { | ||
| 771 | +// Log.i(TAG, "focus areas not supported"); | ||
| 772 | +// callback.focusSuccess(); | ||
| 773 | +// return false; | ||
| 774 | +// } | ||
| 775 | +// final String currentFocusMode = params.getFocusMode(); | ||
| 776 | +// | ||
| 777 | +// params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); | ||
| 778 | +// mCamera.setParameters(params); | ||
| 779 | +// mCamera.autoFocus(new Camera.AutoFocusCallback() { | ||
| 780 | +// @Override | ||
| 781 | +// public void onAutoFocus(boolean success, Camera camera) { | ||
| 782 | +// if (success || handlerTime > 10) { | ||
| 783 | +// Camera.Parameters params = camera.getParameters(); | ||
| 784 | +// params.setFocusMode(currentFocusMode); | ||
| 785 | +// camera.setParameters(params); | ||
| 786 | +// handlerTime = 0; | ||
| 787 | +// callback.focusSuccess(); | ||
| 788 | +// } else { | ||
| 789 | +// handlerTime++; | ||
| 790 | +// handleFocus(context, x, y, callback); | ||
| 791 | +// } | ||
| 792 | +// } | ||
| 793 | +// }); | ||
| 794 | +// return true; | ||
| 795 | +// } catch (Exception e) { | ||
| 796 | +// Log.e(TAG, "autoFocus failer"); | ||
| 797 | +// } | ||
| 798 | +// return false; | ||
| 799 | +// } | ||
| 800 | +// | ||
| 801 | +// | ||
| 802 | +// private static Rect calculateTapArea(float x, float y, float coefficient, Context context) { | ||
| 803 | +// float focusAreaSize = 300; | ||
| 804 | +// int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue(); | ||
| 805 | +// int centerX = (int) (x / ScreenUtils.getScreenWidth(context) * 2000 - 1000); | ||
| 806 | +// int centerY = (int) (y / ScreenUtils.getScreenHeight(context) * 2000 - 1000); | ||
| 807 | +// int left = clamp(centerX - areaSize / 2, -1000, 1000); | ||
| 808 | +// int top = clamp(centerY - areaSize / 2, -1000, 1000); | ||
| 809 | +// RectF rectF = new RectF(left, top, left + areaSize, top + areaSize); | ||
| 810 | +// return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF | ||
| 811 | +// .bottom)); | ||
| 812 | +// } | ||
| 813 | +// | ||
| 814 | +// private static int clamp(int x, int min, int max) { | ||
| 815 | +// if (x > max) { | ||
| 816 | +// return max; | ||
| 817 | +// } | ||
| 818 | +// if (x < min) { | ||
| 819 | +// return min; | ||
| 820 | +// } | ||
| 821 | +// return x; | ||
| 822 | +// } | ||
| 823 | +// | ||
| 824 | +// void setErrorLinsenter(ErrorListener errorLisenter) { | ||
| 825 | +// this.errorLisenter = errorLisenter; | ||
| 826 | +// } | ||
| 827 | +// | ||
| 828 | +// | ||
| 829 | +// public interface StopRecordCallback { | ||
| 830 | +// void recordResult(String url); | ||
| 831 | +// } | ||
| 832 | +// | ||
| 833 | +// interface ErrorCallback { | ||
| 834 | +// void onError(); | ||
| 835 | +// } | ||
| 836 | +// | ||
| 837 | +// public interface TakePictureCallback { | ||
| 838 | +// void captureResult(Bitmap bitmap, boolean isVertical); | ||
| 839 | +// } | ||
| 840 | +// | ||
| 841 | +// public interface FocusCallback { | ||
| 842 | +// void focusSuccess(); | ||
| 843 | +// | ||
| 844 | +// } | ||
| 845 | +// | ||
| 846 | +// | ||
| 847 | +// void registerSensorManager(Context context) { | ||
| 848 | +// SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); | ||
| 849 | +// if (sm == null) return; | ||
| 850 | +// Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); | ||
| 851 | +// sm.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); | ||
| 852 | +// } | ||
| 853 | +// | ||
| 854 | +// void unregisterSensorManager(Context context) { | ||
| 855 | +// SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); | ||
| 856 | +// if (sm == null) return; | ||
| 857 | +// sm.unregisterListener(sensorEventListener); | ||
| 858 | +// } | ||
| 859 | +// | ||
| 860 | +// void isPreview(boolean res) { | ||
| 861 | +// this.isPreviewing = res; | ||
| 862 | +// } | ||
| 863 | +//} |
lib_media/src/main/java/com/cnlive/media/ui/widget/record/view/OnLineCameraView.java
0 → 100644
| 1 | +//package com.cnlive.media.ui.widget.record.view; | ||
| 2 | +// | ||
| 3 | +//import android.animation.AnimatorSet; | ||
| 4 | +//import android.animation.ObjectAnimator; | ||
| 5 | +//import android.content.Context; | ||
| 6 | +//import android.content.res.TypedArray; | ||
| 7 | +//import android.graphics.Bitmap; | ||
| 8 | +//import android.hardware.Camera; | ||
| 9 | +//import android.media.AudioManager; | ||
| 10 | +//import android.media.MediaPlayer; | ||
| 11 | +//import android.os.Build; | ||
| 12 | +//import android.os.CountDownTimer; | ||
| 13 | +//import android.util.AttributeSet; | ||
| 14 | +//import android.util.Log; | ||
| 15 | +//import android.util.TypedValue; | ||
| 16 | +//import android.view.Gravity; | ||
| 17 | +//import android.view.LayoutInflater; | ||
| 18 | +//import android.view.MotionEvent; | ||
| 19 | +//import android.view.SurfaceHolder; | ||
| 20 | +//import android.view.View; | ||
| 21 | +//import android.view.ViewGroup; | ||
| 22 | +//import android.view.WindowManager; | ||
| 23 | +//import android.widget.FrameLayout; | ||
| 24 | +//import android.widget.ImageView; | ||
| 25 | +//import android.widget.ProgressBar; | ||
| 26 | +//import android.widget.TextView; | ||
| 27 | +//import android.widget.VideoView; | ||
| 28 | +// | ||
| 29 | +//import androidx.annotation.RequiresApi; | ||
| 30 | +// | ||
| 31 | +//import com.alibaba.android.arouter.launcher.ARouter; | ||
| 32 | +// | ||
| 33 | +//import com.cnlive.libs.base.util.AlertUtil; | ||
| 34 | +//import com.cnlive.media.R; | ||
| 35 | +//import com.cnlive.media.ui.widget.record.FoucsView; | ||
| 36 | +//import com.cnlive.media.ui.widget.record.OnLineCaptureLayout; | ||
| 37 | +//import com.cnlive.media.ui.widget.record.listener.CaptureListener; | ||
| 38 | +//import com.cnlive.media.ui.widget.record.listener.ClickListener; | ||
| 39 | +//import com.cnlive.media.ui.widget.record.listener.ErrorListener; | ||
| 40 | +//import com.cnlive.media.ui.widget.record.listener.JCameraListener; | ||
| 41 | +//import com.cnlive.media.ui.widget.record.listener.TypeListener; | ||
| 42 | +//import com.cnlive.media.ui.widget.record.state.OnLineCameraMachine; | ||
| 43 | +//import com.cnlive.media.utils.FileUtil; | ||
| 44 | +//import com.cnlive.media.utils.LogUtil; | ||
| 45 | +//import com.cnlive.media.utils.ScreenUtils; | ||
| 46 | +// | ||
| 47 | +//import java.util.Timer; | ||
| 48 | +//import java.util.TimerTask; | ||
| 49 | +// | ||
| 50 | +// | ||
| 51 | +///** | ||
| 52 | +// * ===================================== | ||
| 53 | +// * 作 者: 陈嘉桐 | ||
| 54 | +// * 版 本:1.0.4 | ||
| 55 | +// * 创建日期:2017/4/25 | ||
| 56 | +// * 描 述: | ||
| 57 | +// * ===================================== | ||
| 58 | +// */ | ||
| 59 | +//public class OnLineCameraView extends FrameLayout implements OnLineCameraInterface.CameraOpenOverCallback, SurfaceHolder | ||
| 60 | +// .Callback, CameraView { | ||
| 61 | +// | ||
| 62 | +// //Camera状态机 | ||
| 63 | +// private OnLineCameraMachine machine; | ||
| 64 | +// | ||
| 65 | +// private static final int TYPE_FLASH_ON = 0x022; | ||
| 66 | +// private static final int TYPE_FLASH_OFF = 0x023; | ||
| 67 | +// private int type_flash = TYPE_FLASH_OFF; | ||
| 68 | +// | ||
| 69 | +// //拍照浏览时候的类型 | ||
| 70 | +// public static final int TYPE_PICTURE = 0x001; | ||
| 71 | +// public static final int TYPE_VIDEO = 0x002; | ||
| 72 | +// public static final int TYPE_SHORT = 0x003; | ||
| 73 | +// public static final int TYPE_DEFAULT = 0x004; | ||
| 74 | +// | ||
| 75 | +// //录制视频比特率 | ||
| 76 | +// public static final int MEDIA_QUALITY_HIGH = 20 * 100000; | ||
| 77 | +// public static final int MEDIA_QUALITY_MIDDLE = 16 * 100000; | ||
| 78 | +// public static final int MEDIA_QUALITY_LOW = 12 * 100000; | ||
| 79 | +// public static final int MEDIA_QUALITY_POOR = 8 * 100000; | ||
| 80 | +// public static final int MEDIA_QUALITY_FUNNY = 4 * 100000; | ||
| 81 | +// public static final int MEDIA_QUALITY_DESPAIR = 2 * 100000; | ||
| 82 | +// public static final int MEDIA_QUALITY_SORRY = 1 * 80000; | ||
| 83 | +// | ||
| 84 | +// | ||
| 85 | +// public static final int BUTTON_STATE_ONLY_CAPTURE = 0x101; //只能拍照 | ||
| 86 | +// public static final int BUTTON_STATE_ONLY_RECORDER = 0x102; //只能录像 | ||
| 87 | +// public static final int BUTTON_STATE_BOTH = 0x103; //两者都可以 | ||
| 88 | +// | ||
| 89 | +// | ||
| 90 | +// //回调监听 | ||
| 91 | +// private JCameraListener jCameraLisenter; | ||
| 92 | +// private ClickListener leftClickListener; | ||
| 93 | +// private ClickListener rightClickListener; | ||
| 94 | +// | ||
| 95 | +// private VideoView mVideoView; | ||
| 96 | +// private ImageView mPhoto; | ||
| 97 | +// private OnLineCaptureLayout mCaptureLayout; | ||
| 98 | +// private FoucsView mFoucsView; | ||
| 99 | +// private ProgressBar progressbar; | ||
| 100 | +// private MediaPlayer mMediaPlayer; | ||
| 101 | +// | ||
| 102 | +// private int layout_width; | ||
| 103 | +// private float screenProp = 0f; | ||
| 104 | +// | ||
| 105 | +// private Bitmap captureBitmap; //捕获的图片 | ||
| 106 | +// private String videoUrl; //视频URL | ||
| 107 | +// | ||
| 108 | +// | ||
| 109 | +// //切换摄像头按钮的参数 | ||
| 110 | +// private int iconSize = 0; //图标大小 | ||
| 111 | +// private int iconMargin = 0; //右上边距 | ||
| 112 | +// private int iconSrc = 0; //图标资源 | ||
| 113 | +// private int iconLeft = 0; //左图标 | ||
| 114 | +// private int iconRight = 0; //右图标 | ||
| 115 | +// private int duration = 0; //录制时间 | ||
| 116 | +// | ||
| 117 | +// //缩放梯度 | ||
| 118 | +// private int zoomGradient = 0; | ||
| 119 | +// | ||
| 120 | +// private boolean firstTouch = true; | ||
| 121 | +// private float firstTouchLength = 0; | ||
| 122 | +// private boolean recordEnd = false; | ||
| 123 | +// private String contentId = ""; | ||
| 124 | +// private TextView sign, testing, timertext; | ||
| 125 | +// | ||
| 126 | +// public OnLineCameraView(Context context) { | ||
| 127 | +// this(context, null); | ||
| 128 | +// } | ||
| 129 | +// | ||
| 130 | +// public OnLineCameraView(Context context, AttributeSet attrs) { | ||
| 131 | +// this(context, attrs, 0); | ||
| 132 | +// } | ||
| 133 | +// | ||
| 134 | +// public OnLineCameraView(Context context, AttributeSet attrs, int defStyleAttr) { | ||
| 135 | +// super(context, attrs, defStyleAttr); | ||
| 136 | +// //get AttributeSet | ||
| 137 | +// TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.OnLineCameraView, defStyleAttr, 0); | ||
| 138 | +// iconSize = a.getDimensionPixelSize(R.styleable.OnLineCameraView_iconSize, (int) TypedValue.applyDimension( | ||
| 139 | +// TypedValue.COMPLEX_UNIT_SP, 35, getResources().getDisplayMetrics())); | ||
| 140 | +// iconMargin = a.getDimensionPixelSize(R.styleable.OnLineCameraView_iconMargin, (int) TypedValue.applyDimension( | ||
| 141 | +// TypedValue.COMPLEX_UNIT_SP, 15, getResources().getDisplayMetrics())); | ||
| 142 | +// // iconSrc = a.getResourceId(R.styleable.OnLineCameraView_iconSrc, R.drawable.fb_xiangji); | ||
| 143 | +// iconLeft = a.getResourceId(R.styleable.OnLineCameraView_iconLeft, 0); | ||
| 144 | +// iconRight = a.getResourceId(R.styleable.OnLineCameraView_iconRight, 0); | ||
| 145 | +// duration = a.getInteger(R.styleable.OnLineCameraView_duration_max, 10 * 1000); //没设置默认为10s | ||
| 146 | +// a.recycle(); | ||
| 147 | +// initData(); | ||
| 148 | +// initView(); | ||
| 149 | +// } | ||
| 150 | +// | ||
| 151 | +// private void initData() { | ||
| 152 | +// layout_width = ScreenUtils.getScreenWidth(getContext()); | ||
| 153 | +// //缩放梯度 | ||
| 154 | +// zoomGradient = (int) (layout_width / 16f); | ||
| 155 | +// LogUtil.i("zoom = " + zoomGradient); | ||
| 156 | +// machine = new OnLineCameraMachine(getContext(), this, this); | ||
| 157 | +// } | ||
| 158 | +// | ||
| 159 | +// public int getScreenWidth() { | ||
| 160 | +// WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); | ||
| 161 | +// return wm == null ? 0 : wm.getDefaultDisplay().getWidth(); | ||
| 162 | +// } | ||
| 163 | +// | ||
| 164 | +// private Timer timer; | ||
| 165 | +// private TimerTask timerTask; | ||
| 166 | +// private int progress = 0; | ||
| 167 | +// | ||
| 168 | +// public void StartTimer() { | ||
| 169 | +// if (timer == null && timerTask == null) { | ||
| 170 | +// timer = new Timer(); | ||
| 171 | +// timerTask = new TimerTask() { | ||
| 172 | +// @Override | ||
| 173 | +// public void run() { | ||
| 174 | +// progress++; | ||
| 175 | +// progressbar.setProgress(progress); | ||
| 176 | +// } | ||
| 177 | +// }; | ||
| 178 | +// timer.schedule(timerTask, 0, 1000); | ||
| 179 | +// } | ||
| 180 | +// } | ||
| 181 | +// | ||
| 182 | +// public void EndTimer() { | ||
| 183 | +// if (timer != null) timer.cancel(); | ||
| 184 | +// if (timerTask != null) timerTask.cancel(); | ||
| 185 | +// timer = null; | ||
| 186 | +// timerTask = null; | ||
| 187 | +// progressbar.setProgress(0); | ||
| 188 | +// } | ||
| 189 | +// | ||
| 190 | +// | ||
| 191 | +// private CountDownTimer timergo = new CountDownTimer(3 * 60 * 1000, 1000) { | ||
| 192 | +// | ||
| 193 | +// @Override | ||
| 194 | +// public void onTick(long millisUntilFinished) { | ||
| 195 | +// timertext.setText(formatTime(millisUntilFinished)); | ||
| 196 | +// } | ||
| 197 | +// | ||
| 198 | +// @Override | ||
| 199 | +// public void onFinish() { | ||
| 200 | +// endCam(); | ||
| 201 | +// } | ||
| 202 | +// }; | ||
| 203 | +// | ||
| 204 | +// | ||
| 205 | +// public String formatTime(long millisecond) { | ||
| 206 | +// int minute;//分钟 | ||
| 207 | +// int second;//秒数 | ||
| 208 | +// minute = (int) ((millisecond / 1000) / 60); | ||
| 209 | +// second = (int) ((millisecond / 1000) % 60); | ||
| 210 | +// if (minute < 10) { | ||
| 211 | +// if (second < 10) { | ||
| 212 | +// return "0" + minute + ":" + "0" + second; | ||
| 213 | +// } else { | ||
| 214 | +// return "0" + minute + ":" + second; | ||
| 215 | +// } | ||
| 216 | +// } else { | ||
| 217 | +// if (second < 10) { | ||
| 218 | +// return minute + ":" + "0" + second; | ||
| 219 | +// } else { | ||
| 220 | +// return minute + ":" + second; | ||
| 221 | +// } | ||
| 222 | +// } | ||
| 223 | +// } | ||
| 224 | +// | ||
| 225 | +// /** | ||
| 226 | +// * 取消倒计时 | ||
| 227 | +// */ | ||
| 228 | +// public void timerCancel() { | ||
| 229 | +// timergo.cancel(); | ||
| 230 | +// timertext.setText("00:00"); | ||
| 231 | +// } | ||
| 232 | +// | ||
| 233 | +// /** | ||
| 234 | +// * 开始倒计时 | ||
| 235 | +// */ | ||
| 236 | +// public void timerStart() { | ||
| 237 | +// timergo.start(); | ||
| 238 | +// } | ||
| 239 | +// | ||
| 240 | +// | ||
| 241 | +// public void startCam(String contentid) { | ||
| 242 | +// recordEnd = false; | ||
| 243 | +// contentId = contentid; | ||
| 244 | +// mCaptureLayout.showTake(); | ||
| 245 | +// if (machine.record(mVideoView.getHolder().getSurface(), screenProp, getContext())) { | ||
| 246 | +// StartTimer(); | ||
| 247 | +// timerStart(); | ||
| 248 | +// sign.setVisibility(VISIBLE); | ||
| 249 | +// testing.setVisibility(VISIBLE); | ||
| 250 | +// } else { | ||
| 251 | +// AlertUtil.showDeftToast(getContext(), "相机开启失败"); | ||
| 252 | +// Log.e("Camera", "相机开启失败."); | ||
| 253 | +// mCaptureLayout.onError(true); | ||
| 254 | +// } | ||
| 255 | +// } | ||
| 256 | +// | ||
| 257 | +// public void endCam() { | ||
| 258 | +// machine.stopRecord(false, 3 * 60 * 1000); | ||
| 259 | +// recordEnd = true; | ||
| 260 | +// EndTimer(); | ||
| 261 | +// timerCancel(); | ||
| 262 | +// sign.setVisibility(GONE); | ||
| 263 | +// testing.setVisibility(GONE); | ||
| 264 | +// progressbar.setVisibility(GONE); | ||
| 265 | +// timertext.setVisibility(GONE); | ||
| 266 | +// if (jCameraLisenter != null) { | ||
| 267 | +// jCameraLisenter.recordEnd(videoUrl, duration); | ||
| 268 | +// } | ||
| 269 | +// mCaptureLayout.startAlphaAnimation(); | ||
| 270 | +// mCaptureLayout.startTypeBtnAnimator(); | ||
| 271 | +// } | ||
| 272 | +// | ||
| 273 | +// | ||
| 274 | +// private void initView() { | ||
| 275 | +// setWillNotDraw(false); | ||
| 276 | +// int[] cid = {1}; | ||
| 277 | +// View view = LayoutInflater.from(getContext()).inflate(R.layout.online_camera_view, this); | ||
| 278 | +// mVideoView = (VideoView) view.findViewById(R.id.video_preview); | ||
| 279 | +// mVideoView.setLayoutParams(new LayoutParams(ScreenUtils.getScreenWidth(getContext()), ScreenUtils.getScreenHeight(getContext()))); | ||
| 280 | +// mPhoto = (ImageView) view.findViewById(R.id.image_photo); | ||
| 281 | +// machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 282 | +// mCaptureLayout = (OnLineCaptureLayout) view.findViewById(R.id.capture_layout); | ||
| 283 | +// mCaptureLayout.setDuration(duration); | ||
| 284 | +// mCaptureLayout.setIconSrc(iconLeft, iconRight); | ||
| 285 | +// mFoucsView = (FoucsView) view.findViewById(R.id.fouce_view); | ||
| 286 | +// progressbar = (ProgressBar) view.findViewById(R.id.progress_bar_h); | ||
| 287 | +// sign = view.findViewById(R.id.sign); | ||
| 288 | +// testing = view.findViewById(R.id.testing); | ||
| 289 | +// timertext = view.findViewById(R.id.timer); | ||
| 290 | +// progressbar.setMax(180); | ||
| 291 | +// progressbar.setProgress(0); | ||
| 292 | +// mVideoView.getHolder().addCallback(this); | ||
| 293 | +// //拍照 录像 | ||
| 294 | +// mCaptureLayout.setCaptureLisenter(new CaptureListener() { | ||
| 295 | +// | ||
| 296 | +// | ||
| 297 | +// @Override | ||
| 298 | +// public void takePictures() { | ||
| 299 | +// } | ||
| 300 | +// | ||
| 301 | +// @Override | ||
| 302 | +// public void recordStart() { | ||
| 303 | +// } | ||
| 304 | +// | ||
| 305 | +// @Override | ||
| 306 | +// public void recordShort(final long time) { | ||
| 307 | +// mCaptureLayout.setTextWithAnimation("录制时间过短"); | ||
| 308 | +// postDelayed(new Runnable() { | ||
| 309 | +// @Override | ||
| 310 | +// public void run() { | ||
| 311 | +// machine.stopRecord(true, time); | ||
| 312 | +// } | ||
| 313 | +// }, 1500 - time); | ||
| 314 | +// } | ||
| 315 | +// | ||
| 316 | +// @Override | ||
| 317 | +// public void recordEnd(long time) { | ||
| 318 | +// machine.stopRecord(false, time); | ||
| 319 | +// recordEnd = true; | ||
| 320 | +// if (jCameraLisenter != null) { | ||
| 321 | +// jCameraLisenter.recordEnd(videoUrl, duration); | ||
| 322 | +// EndTimer(); | ||
| 323 | +// timerCancel(); | ||
| 324 | +// sign.setVisibility(GONE); | ||
| 325 | +// testing.setVisibility(GONE); | ||
| 326 | +// progressbar.setVisibility(GONE); | ||
| 327 | +// timertext.setVisibility(GONE); | ||
| 328 | +// } | ||
| 329 | +// } | ||
| 330 | +// | ||
| 331 | +// @Override | ||
| 332 | +// public void recordZoom(float zoom) { | ||
| 333 | +// LogUtil.i("recordZoom"); | ||
| 334 | +// machine.zoom(zoom, OnLineCameraInterface.TYPE_RECORDER); | ||
| 335 | +// } | ||
| 336 | +// | ||
| 337 | +// @Override | ||
| 338 | +// public void recordError() { | ||
| 339 | +// if (errorLisenter != null) { | ||
| 340 | +// errorLisenter.AudioPermissionError(); | ||
| 341 | +// } | ||
| 342 | +// } | ||
| 343 | +// }); | ||
| 344 | +// //确认 取消 | ||
| 345 | +// mCaptureLayout.setTypeLisenter(new TypeListener() { | ||
| 346 | +// @Override | ||
| 347 | +// public void cancel() { | ||
| 348 | +// machine.confirm(); | ||
| 349 | +// } | ||
| 350 | +// | ||
| 351 | +// @Override | ||
| 352 | +// public void confirm() { | ||
| 353 | +// ARouter.getInstance().build("/cnmain/ReleaseSuccessAcityity") | ||
| 354 | +// .withString("jumpType", "GiveUp")//话题发布页面跳转 | ||
| 355 | +// .withString("Title", "比赛失败") | ||
| 356 | +// .withString("examinationId", contentId) | ||
| 357 | +// .navigation(getContext()); | ||
| 358 | +// desView(); | ||
| 359 | +// } | ||
| 360 | +// }); | ||
| 361 | +// | ||
| 362 | +// mCaptureLayout.setLeftClickListener(new ClickListener() { | ||
| 363 | +// @Override | ||
| 364 | +// public void onClick() { | ||
| 365 | +// if (leftClickListener != null) { | ||
| 366 | +// leftClickListener.onClick(); | ||
| 367 | +// } | ||
| 368 | +// } | ||
| 369 | +// }); | ||
| 370 | +// mCaptureLayout.setRightClickListener(new ClickListener() { | ||
| 371 | +// @Override | ||
| 372 | +// public void onClick() { | ||
| 373 | +// if (rightClickListener != null) { | ||
| 374 | +// rightClickListener.onClick(); | ||
| 375 | +// } | ||
| 376 | +// } | ||
| 377 | +// }); | ||
| 378 | +// } | ||
| 379 | +// | ||
| 380 | +// public void desView(){ | ||
| 381 | +// machine.cancle(mVideoView.getHolder(), screenProp); | ||
| 382 | +// stopVideo(); | ||
| 383 | +// recordEnd = false; | ||
| 384 | +// machine.flash(Camera.Parameters.FLASH_MODE_OFF); | ||
| 385 | +// OnLineCameraInterface.getInstance().doDestroyCamera(); | ||
| 386 | +// timerCancel(); | ||
| 387 | +// EndTimer(); | ||
| 388 | +// } | ||
| 389 | +// | ||
| 390 | +// public void swit(){ | ||
| 391 | +// machine.swtich(mVideoView.getHolder(), screenProp); | ||
| 392 | +// } | ||
| 393 | +// | ||
| 394 | +// public void setDuration(int duration_ss) { | ||
| 395 | +// if (mCaptureLayout != null) mCaptureLayout.setDuration(duration = duration_ss); | ||
| 396 | +// } | ||
| 397 | +// | ||
| 398 | +// @Override | ||
| 399 | +// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 400 | +// super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 401 | +// float widthSize = mVideoView.getMeasuredWidth(); | ||
| 402 | +// float heightSize = mVideoView.getMeasuredHeight(); | ||
| 403 | +// if (screenProp == 0) { | ||
| 404 | +// screenProp = heightSize / widthSize; | ||
| 405 | +// } | ||
| 406 | +// } | ||
| 407 | +// | ||
| 408 | +// @Override | ||
| 409 | +// public void cameraHasOpened() { | ||
| 410 | +// OnLineCameraInterface.getInstance().doStartPreview(mVideoView.getHolder(), screenProp); | ||
| 411 | +// } | ||
| 412 | +// | ||
| 413 | +// //生命周期onResume | ||
| 414 | +// public void onResume() { | ||
| 415 | +// LogUtil.i("JCameraView onResume"); | ||
| 416 | +// resetState(TYPE_DEFAULT); //重置状态 | ||
| 417 | +// OnLineCameraInterface.getInstance().registerSensorManager(getContext()); | ||
| 418 | +// machine.setDefaultState(); | ||
| 419 | +// machine.start(mVideoView.getHolder(), screenProp); | ||
| 420 | +// } | ||
| 421 | +// | ||
| 422 | +// //生命周期onPause | ||
| 423 | +// public void onStop() { | ||
| 424 | +// LogUtil.i("JCameraView onPause"); | ||
| 425 | +// stopVideo(); | ||
| 426 | +// resetState(TYPE_PICTURE); | ||
| 427 | +// OnLineCameraInterface.getInstance().isPreview(false); | ||
| 428 | +// OnLineCameraInterface.getInstance().unregisterSensorManager(getContext()); | ||
| 429 | +// } | ||
| 430 | +// | ||
| 431 | +// //SurfaceView生命周期 | ||
| 432 | +// @Override | ||
| 433 | +// public void surfaceCreated(SurfaceHolder holder) { | ||
| 434 | +// LogUtil.i("JCameraView SurfaceCreated"); | ||
| 435 | +// if (recordEnd) { | ||
| 436 | +// if (mMediaPlayer != null) { | ||
| 437 | +// mMediaPlayer.setDisplay(holder); | ||
| 438 | +// mMediaPlayer.start(); | ||
| 439 | +// } | ||
| 440 | +// return; | ||
| 441 | +// } | ||
| 442 | +// new Thread() { | ||
| 443 | +// @Override | ||
| 444 | +// public void run() { | ||
| 445 | +// OnLineCameraInterface.getInstance().doOpenCamera(OnLineCameraView.this, Camera.CameraInfo.CAMERA_FACING_FRONT); | ||
| 446 | +// } | ||
| 447 | +// }.start(); | ||
| 448 | +// } | ||
| 449 | +// | ||
| 450 | +// @Override | ||
| 451 | +// public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { | ||
| 452 | +// } | ||
| 453 | +// | ||
| 454 | +// @Override | ||
| 455 | +// public void surfaceDestroyed(SurfaceHolder holder) { | ||
| 456 | +// LogUtil.i("JCameraView SurfaceDestroyed"); | ||
| 457 | +// if (recordEnd) { | ||
| 458 | +// if (mMediaPlayer != null) | ||
| 459 | +// mMediaPlayer.setDisplay(null); | ||
| 460 | +// pausePlayer(); | ||
| 461 | +// return; | ||
| 462 | +// } | ||
| 463 | +// OnLineCameraInterface.getInstance().doDestroyCamera(); | ||
| 464 | +// | ||
| 465 | +// } | ||
| 466 | +// | ||
| 467 | +// | ||
| 468 | +// @Override | ||
| 469 | +// public boolean onTouchEvent(MotionEvent event) { | ||
| 470 | +// switch (event.getAction()) { | ||
| 471 | +// case MotionEvent.ACTION_DOWN: | ||
| 472 | +// if (event.getPointerCount() == 1) { | ||
| 473 | +// //显示对焦指示器 | ||
| 474 | +// setFocusViewWidthAnimation(event.getX(), event.getY()); | ||
| 475 | +// } | ||
| 476 | +// if (event.getPointerCount() == 2) { | ||
| 477 | +// Log.i("CJT", "ACTION_DOWN = " + 2); | ||
| 478 | +// } | ||
| 479 | +// break; | ||
| 480 | +// case MotionEvent.ACTION_MOVE: | ||
| 481 | +// if (event.getPointerCount() == 1) { | ||
| 482 | +// firstTouch = true; | ||
| 483 | +// } | ||
| 484 | +// if (event.getPointerCount() == 2) { | ||
| 485 | +// //第一个点 | ||
| 486 | +// float point_1_X = event.getX(0); | ||
| 487 | +// float point_1_Y = event.getY(0); | ||
| 488 | +// //第二个点 | ||
| 489 | +// float point_2_X = event.getX(1); | ||
| 490 | +// float point_2_Y = event.getY(1); | ||
| 491 | +// | ||
| 492 | +// float result = (float) Math.sqrt(Math.pow(point_1_X - point_2_X, 2) + Math.pow(point_1_Y - | ||
| 493 | +// point_2_Y, 2)); | ||
| 494 | +// | ||
| 495 | +// if (firstTouch) { | ||
| 496 | +// firstTouchLength = result; | ||
| 497 | +// firstTouch = false; | ||
| 498 | +// } | ||
| 499 | +// if ((int) (result - firstTouchLength) / zoomGradient != 0) { | ||
| 500 | +// firstTouch = true; | ||
| 501 | +// machine.zoom(result - firstTouchLength, OnLineCameraInterface.TYPE_CAPTURE); | ||
| 502 | +// } | ||
| 503 | +// } | ||
| 504 | +// break; | ||
| 505 | +// case MotionEvent.ACTION_UP: | ||
| 506 | +// firstTouch = true; | ||
| 507 | +// break; | ||
| 508 | +// } | ||
| 509 | +// return true; | ||
| 510 | +// } | ||
| 511 | +// | ||
| 512 | +// //对焦框指示器动画 | ||
| 513 | +// private void setFocusViewWidthAnimation(float x, float y) { | ||
| 514 | +// machine.foucs(x, y, new OnLineCameraInterface.FocusCallback() { | ||
| 515 | +// @Override | ||
| 516 | +// public void focusSuccess() { | ||
| 517 | +// mFoucsView.setVisibility(INVISIBLE); | ||
| 518 | +// } | ||
| 519 | +// }); | ||
| 520 | +// } | ||
| 521 | +// | ||
| 522 | +// private void updateVideoViewSize(float videoWidth, float videoHeight) { | ||
| 523 | +// if (videoWidth > videoHeight) { | ||
| 524 | +// LayoutParams videoViewParam; | ||
| 525 | +// int height = (int) ((videoHeight / videoWidth) * getWidth()); | ||
| 526 | +// videoViewParam = new LayoutParams(LayoutParams.MATCH_PARENT, height); | ||
| 527 | +// videoViewParam.gravity = Gravity.CENTER; | ||
| 528 | +// mVideoView.setLayoutParams(videoViewParam); | ||
| 529 | +// } | ||
| 530 | +// } | ||
| 531 | +// | ||
| 532 | +// | ||
| 533 | +// public void setSaveVideoPath(String path) { | ||
| 534 | +// OnLineCameraInterface.getInstance().setSaveVideoPath(path); | ||
| 535 | +// } | ||
| 536 | +// | ||
| 537 | +// | ||
| 538 | +// public void setJCameraLisenter(JCameraListener jCameraLisenter) { | ||
| 539 | +// this.jCameraLisenter = jCameraLisenter; | ||
| 540 | +// } | ||
| 541 | +// | ||
| 542 | +// | ||
| 543 | +// private ErrorListener errorLisenter; | ||
| 544 | +// | ||
| 545 | +// //启动Camera错误回调 | ||
| 546 | +// public void setErrorLisenter(ErrorListener errorLisenter) { | ||
| 547 | +// this.errorLisenter = errorLisenter; | ||
| 548 | +// OnLineCameraInterface.getInstance().setErrorLinsenter(errorLisenter); | ||
| 549 | +// } | ||
| 550 | +// | ||
| 551 | +// //设置CaptureButton功能(拍照和录像) | ||
| 552 | +// public void setFeatures(int state) { | ||
| 553 | +// this.mCaptureLayout.setButtonFeatures(state); | ||
| 554 | +// } | ||
| 555 | +// | ||
| 556 | +// | ||
| 557 | +// public void setButtonVisiblity() { | ||
| 558 | +// mCaptureLayout.setVisibility(GONE); | ||
| 559 | +// } | ||
| 560 | +// | ||
| 561 | +// @Override | ||
| 562 | +// public void resetState(int type) { | ||
| 563 | +// switch (type) { | ||
| 564 | +// case TYPE_VIDEO: | ||
| 565 | +// stopVideo(); //停止播放 | ||
| 566 | +// //初始化VideoView | ||
| 567 | +// FileUtil.deleteFile(videoUrl); | ||
| 568 | +// mVideoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 569 | +// machine.start(mVideoView.getHolder(), screenProp); | ||
| 570 | +// break; | ||
| 571 | +// case TYPE_PICTURE: | ||
| 572 | +// mPhoto.setVisibility(INVISIBLE); | ||
| 573 | +// break; | ||
| 574 | +// case TYPE_SHORT: | ||
| 575 | +// break; | ||
| 576 | +// case TYPE_DEFAULT: | ||
| 577 | +// mVideoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 578 | +// break; | ||
| 579 | +// } | ||
| 580 | +// // mSwitchCamera.setVisibility(VISIBLE); | ||
| 581 | +// // mFlashLamp.setVisibility(VISIBLE); | ||
| 582 | +// mCaptureLayout.resetCaptureLayout(); | ||
| 583 | +// } | ||
| 584 | +// | ||
| 585 | +// @Override | ||
| 586 | +// public void confirmState(int type) { | ||
| 587 | +// switch (type) { | ||
| 588 | +// case TYPE_VIDEO: | ||
| 589 | +// int duration = mMediaPlayer.getDuration(); | ||
| 590 | +// stopVideo(); //停止播放 | ||
| 591 | +// // mVideoView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); | ||
| 592 | +// machine.start(mVideoView.getHolder(), screenProp); | ||
| 593 | +// if (jCameraLisenter != null) { | ||
| 594 | +// jCameraLisenter.recordSuccess(videoUrl, duration); | ||
| 595 | +// } | ||
| 596 | +// break; | ||
| 597 | +// case TYPE_PICTURE: | ||
| 598 | +// mPhoto.setVisibility(INVISIBLE); | ||
| 599 | +// if (jCameraLisenter != null) { | ||
| 600 | +// jCameraLisenter.captureSuccess(captureBitmap); | ||
| 601 | +// } | ||
| 602 | +// break; | ||
| 603 | +// case TYPE_SHORT: | ||
| 604 | +// break; | ||
| 605 | +// case TYPE_DEFAULT: | ||
| 606 | +// break; | ||
| 607 | +// } | ||
| 608 | +// } | ||
| 609 | +// | ||
| 610 | +// @Override | ||
| 611 | +// public void showPicture(Bitmap bitmap, boolean isVertical) { | ||
| 612 | +// if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { | ||
| 613 | +// ViewGroup.LayoutParams layoutParams = mPhoto.getLayoutParams(); | ||
| 614 | +// layoutParams.width = ScreenUtils.getScreenWidth(getContext()); | ||
| 615 | +// layoutParams.height = ScreenUtils.getScreenHeight(getContext()); | ||
| 616 | +// mPhoto.setLayoutParams(layoutParams); | ||
| 617 | +// } else { | ||
| 618 | +// if (isVertical) { | ||
| 619 | +// mPhoto.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||
| 620 | +// } else { | ||
| 621 | +// mPhoto.setScaleType(ImageView.ScaleType.FIT_CENTER); | ||
| 622 | +// } | ||
| 623 | +// } | ||
| 624 | +// captureBitmap = bitmap; | ||
| 625 | +// mPhoto.setVisibility(VISIBLE); | ||
| 626 | +// mPhoto.setImageBitmap(captureBitmap); | ||
| 627 | +// | ||
| 628 | +// mCaptureLayout.startAlphaAnimation(); | ||
| 629 | +// mCaptureLayout.startTypeBtnAnimator(); | ||
| 630 | +// } | ||
| 631 | +// | ||
| 632 | +// @Override | ||
| 633 | +// public void playVideo(final String url) { | ||
| 634 | +// videoUrl = url; | ||
| 635 | +// new Thread(new Runnable() { | ||
| 636 | +// @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) | ||
| 637 | +// @Override | ||
| 638 | +// public void run() { | ||
| 639 | +// try { | ||
| 640 | +// if (mMediaPlayer == null) { | ||
| 641 | +// mMediaPlayer = new MediaPlayer(); | ||
| 642 | +// } else { | ||
| 643 | +// mMediaPlayer.reset(); | ||
| 644 | +// } | ||
| 645 | +// mMediaPlayer.setDataSource(url); | ||
| 646 | +// try { | ||
| 647 | +// | ||
| 648 | +// mMediaPlayer.setDisplay(mVideoView.getHolder()); | ||
| 649 | +// } catch (Exception e) { | ||
| 650 | +// Log.e("MediaPlayer", "setDisplay", e); | ||
| 651 | +// } | ||
| 652 | +// mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT); | ||
| 653 | +// mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); | ||
| 654 | +// mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer | ||
| 655 | +// .OnVideoSizeChangedListener() { | ||
| 656 | +// @Override | ||
| 657 | +// public void | ||
| 658 | +// onVideoSizeChanged(MediaPlayer mp, int width, int height) { | ||
| 659 | +// updateVideoViewSize(mMediaPlayer.getVideoWidth(), mMediaPlayer | ||
| 660 | +// .getVideoHeight()); | ||
| 661 | +// } | ||
| 662 | +// }); | ||
| 663 | +// mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { | ||
| 664 | +// @Override | ||
| 665 | +// public void onPrepared(MediaPlayer mp) { | ||
| 666 | +// mMediaPlayer.start(); | ||
| 667 | +// } | ||
| 668 | +// }); | ||
| 669 | +// mMediaPlayer.setLooping(true); | ||
| 670 | +// mMediaPlayer.prepare(); | ||
| 671 | +// } catch (Exception e) { | ||
| 672 | +// Log.e("MediaPlayer", "", e); | ||
| 673 | +// } | ||
| 674 | +// } | ||
| 675 | +// }).start(); | ||
| 676 | +// } | ||
| 677 | +// | ||
| 678 | +// @Override | ||
| 679 | +// public void stopVideo() { | ||
| 680 | +// if (mMediaPlayer != null) { | ||
| 681 | +// mMediaPlayer.stop(); | ||
| 682 | +// mMediaPlayer.release(); | ||
| 683 | +// mMediaPlayer = null; | ||
| 684 | +// } | ||
| 685 | +// } | ||
| 686 | +// | ||
| 687 | +// @Override | ||
| 688 | +// public void setTip(String tip) { | ||
| 689 | +// mCaptureLayout.setTip(tip); | ||
| 690 | +// } | ||
| 691 | +// | ||
| 692 | +// @Override | ||
| 693 | +// public void startPreviewCallback() { | ||
| 694 | +// LogUtil.i("startPreviewCallback"); | ||
| 695 | +// handlerFoucs(mFoucsView.getWidth() / 2, mFoucsView.getHeight() / 2); | ||
| 696 | +// } | ||
| 697 | +// | ||
| 698 | +// @Override | ||
| 699 | +// public boolean handlerFoucs(float x, float y) { | ||
| 700 | +// if (y > mCaptureLayout.getTop()) { | ||
| 701 | +// return false; | ||
| 702 | +// } | ||
| 703 | +// mFoucsView.setVisibility(VISIBLE); | ||
| 704 | +// if (x < mFoucsView.getWidth() / 2) { | ||
| 705 | +// x = mFoucsView.getWidth() / 2; | ||
| 706 | +// } | ||
| 707 | +// if (x > layout_width - mFoucsView.getWidth() / 2) { | ||
| 708 | +// x = layout_width - mFoucsView.getWidth() / 2; | ||
| 709 | +// } | ||
| 710 | +// if (y < mFoucsView.getWidth() / 2) { | ||
| 711 | +// y = mFoucsView.getWidth() / 2; | ||
| 712 | +// } | ||
| 713 | +// if (y > mCaptureLayout.getTop() - mFoucsView.getWidth() / 2) { | ||
| 714 | +// y = mCaptureLayout.getTop() - mFoucsView.getWidth() / 2; | ||
| 715 | +// } | ||
| 716 | +// mFoucsView.setX(x - mFoucsView.getWidth() / 2); | ||
| 717 | +// mFoucsView.setY(y - mFoucsView.getHeight() / 2); | ||
| 718 | +// ObjectAnimator scaleX = ObjectAnimator.ofFloat(mFoucsView, "scaleX", 1, 0.6f); | ||
| 719 | +// ObjectAnimator scaleY = ObjectAnimator.ofFloat(mFoucsView, "scaleY", 1, 0.6f); | ||
| 720 | +// ObjectAnimator alpha = ObjectAnimator.ofFloat(mFoucsView, "alpha", 1f, 0.4f, 1f, 0.4f, 1f, 0.4f, 1f); | ||
| 721 | +// AnimatorSet animSet = new AnimatorSet(); | ||
| 722 | +// animSet.play(scaleX).with(scaleY).before(alpha); | ||
| 723 | +// animSet.setDuration(400); | ||
| 724 | +// animSet.start(); | ||
| 725 | +// return true; | ||
| 726 | +// } | ||
| 727 | +// | ||
| 728 | +// @Override | ||
| 729 | +// public void pausePlayer() { | ||
| 730 | +// if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { | ||
| 731 | +// mMediaPlayer.pause(); | ||
| 732 | +// } | ||
| 733 | +// } | ||
| 734 | +// | ||
| 735 | +// @Override | ||
| 736 | +// public void resumePlayer() { | ||
| 737 | +// if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) { | ||
| 738 | +// mMediaPlayer.start(); | ||
| 739 | +// } | ||
| 740 | +// } | ||
| 741 | +// | ||
| 742 | +// public void setLeftClickListener(ClickListener clickListener) { | ||
| 743 | +// this.leftClickListener = clickListener; | ||
| 744 | +// } | ||
| 745 | +// | ||
| 746 | +// public void setRightClickListener(ClickListener clickListener) { | ||
| 747 | +// this.rightClickListener = clickListener; | ||
| 748 | +// } | ||
| 749 | +// | ||
| 750 | +// public void onDestroy() { | ||
| 751 | +// if (recordEnd) { | ||
| 752 | +// OnLineCameraInterface.getInstance().doDestroyCamera(); | ||
| 753 | +// } | ||
| 754 | +// if (machine != null) machine.onDestroy(); | ||
| 755 | +// } | ||
| 756 | +//} |
lib_media/src/main/java/com/cnlive/media/utils/AlertDialogUtils.java
| @@ -2,6 +2,7 @@ package com.cnlive.media.utils; | @@ -2,6 +2,7 @@ package com.cnlive.media.utils; | ||
| 2 | 2 | ||
| 3 | import android.app.Dialog; | 3 | import android.app.Dialog; |
| 4 | import android.content.Context; | 4 | import android.content.Context; |
| 5 | +import android.text.TextUtils; | ||
| 5 | import android.view.LayoutInflater; | 6 | import android.view.LayoutInflater; |
| 6 | import android.view.View; | 7 | import android.view.View; |
| 7 | import android.view.ViewGroup; | 8 | import android.view.ViewGroup; |
| @@ -52,9 +53,38 @@ public class AlertDialogUtils { | @@ -52,9 +53,38 @@ public class AlertDialogUtils { | ||
| 52 | return dialog; | 53 | return dialog; |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 56 | + public static Dialog showOneButtonDialog(Context context, String btnString, String title, String content, int btnColor, final DialogOneListener l) { | ||
| 57 | + final Dialog dialog = new Dialog(context, R.style.CustomDialogStyleMediaPicker); | ||
| 58 | + View view = LayoutInflater.from(context).inflate(R.layout.layout_alert_dialog_one_btn, null); | ||
| 59 | + TextView titleTextView = view.findViewById(R.id.title); | ||
| 60 | + if (!TextUtils.isEmpty(title)) titleTextView.setText(title); | ||
| 61 | + else titleTextView.setVisibility(View.GONE); | ||
| 62 | + TextView contentTextView = view.findViewById(R.id.content); | ||
| 63 | + if (!TextUtils.isEmpty(content)) contentTextView.setText(content); | ||
| 64 | + else contentTextView.setVisibility(View.GONE); | ||
| 65 | + ((TextView) (view.findViewById(R.id.btn))).setText(btnString); | ||
| 66 | + if (btnColor != 0) | ||
| 67 | + ((TextView) (view.findViewById(R.id.btn))).setTextColor(context.getResources().getColor(btnColor)); | ||
| 68 | + ViewGroup.LayoutParams vl = new ViewGroup.LayoutParams(ScreenUtils.getScreenWidth(context) - DensityUtils.dp2px(context, 100), ViewGroup.LayoutParams.WRAP_CONTENT); | ||
| 69 | + view.findViewById(R.id.btn).setOnClickListener(v -> { | ||
| 70 | + if (l == null) { | ||
| 71 | + dialog.dismiss(); | ||
| 72 | + } else { | ||
| 73 | + l.onBtnClick(); | ||
| 74 | + } | ||
| 75 | + }); | ||
| 76 | + dialog.addContentView(view, vl); | ||
| 77 | + dialog.show(); | ||
| 78 | + return dialog; | ||
| 79 | + } | ||
| 80 | + | ||
| 55 | public interface DialogTwoListener { | 81 | public interface DialogTwoListener { |
| 56 | void onClickLeft(Dialog dialog); | 82 | void onClickLeft(Dialog dialog); |
| 57 | 83 | ||
| 58 | void onClickRight(Dialog dialog); | 84 | void onClickRight(Dialog dialog); |
| 59 | } | 85 | } |
| 86 | + | ||
| 87 | + public interface DialogOneListener { | ||
| 88 | + void onBtnClick(); | ||
| 89 | + } | ||
| 60 | } | 90 | } |
lib_media/src/main/java/com/cnlive/media/utils/AngleUtil.java
0 → 100644
| 1 | +package com.cnlive.media.utils; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * ===================================== | ||
| 5 | + * 作 者: 陈嘉桐 | ||
| 6 | + * 版 本:1.1.4 | ||
| 7 | + * 创建日期:2017/5/2 | ||
| 8 | + * 描 述: | ||
| 9 | + * ===================================== | ||
| 10 | + */ | ||
| 11 | +public class AngleUtil { | ||
| 12 | + public static int getSensorAngle(float x, float y) { | ||
| 13 | + if (Math.abs(x) > Math.abs(y)) { | ||
| 14 | + /** | ||
| 15 | + * 横屏倾斜角度比较大 | ||
| 16 | + */ | ||
| 17 | + if (x > 4) { | ||
| 18 | + /** | ||
| 19 | + * 左边倾斜 | ||
| 20 | + */ | ||
| 21 | + return 270; | ||
| 22 | + } else if (x < -4) { | ||
| 23 | + /** | ||
| 24 | + * 右边倾斜 | ||
| 25 | + */ | ||
| 26 | + return 90; | ||
| 27 | + } else { | ||
| 28 | + /** | ||
| 29 | + * 倾斜角度不够大 | ||
| 30 | + */ | ||
| 31 | + return 0; | ||
| 32 | + } | ||
| 33 | + } else { | ||
| 34 | + if (y > 7) { | ||
| 35 | + /** | ||
| 36 | + * 左边倾斜 | ||
| 37 | + */ | ||
| 38 | + return 0; | ||
| 39 | + } else if (y < -7) { | ||
| 40 | + /** | ||
| 41 | + * 右边倾斜 | ||
| 42 | + */ | ||
| 43 | + return 180; | ||
| 44 | + } else { | ||
| 45 | + /** | ||
| 46 | + * 倾斜角度不够大 | ||
| 47 | + */ | ||
| 48 | + return 0; | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | +} |
lib_media/src/main/java/com/cnlive/media/utils/AudioUtil.java
0 → 100644
| 1 | +package com.cnlive.media.utils; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.media.AudioManager; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * ===================================== | ||
| 8 | + * 作 者: 陈嘉桐 | ||
| 9 | + * 版 本:1.1.4 | ||
| 10 | + * 创建日期:2017/4/26 | ||
| 11 | + * 描 述: | ||
| 12 | + * ===================================== | ||
| 13 | + */ | ||
| 14 | +public class AudioUtil { | ||
| 15 | + public static void setAudioManage(Context context) { | ||
| 16 | + AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); | ||
| 17 | + audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true); | ||
| 18 | + audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true); | ||
| 19 | + audioManager.setStreamVolume(AudioManager.STREAM_ALARM, 0, 0); | ||
| 20 | + audioManager.setStreamVolume(AudioManager.STREAM_DTMF, 0, 0); | ||
| 21 | + audioManager.setStreamVolume(AudioManager.STREAM_NOTIFICATION, 0, 0); | ||
| 22 | + audioManager.setStreamVolume(AudioManager.STREAM_RING, 0, 0); | ||
| 23 | + } | ||
| 24 | +} |
lib_media/src/main/java/com/cnlive/media/utils/CameraParamUtil.java
0 → 100644
| 1 | +package com.cnlive.media.utils; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.hardware.Camera; | ||
| 5 | +import android.util.Log; | ||
| 6 | +import android.view.Surface; | ||
| 7 | +import android.view.WindowManager; | ||
| 8 | + | ||
| 9 | +import com.cnlive.libs.base.util.AlertUtil; | ||
| 10 | + | ||
| 11 | +import java.util.Collections; | ||
| 12 | +import java.util.Comparator; | ||
| 13 | +import java.util.List; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * ===================================== | ||
| 17 | + * 作 者: 陈嘉桐 | ||
| 18 | + * 版 本:1.1.4 | ||
| 19 | + * 创建日期:2017/4/25 | ||
| 20 | + * 描 述: | ||
| 21 | + * ===================================== | ||
| 22 | + */ | ||
| 23 | +public class CameraParamUtil { | ||
| 24 | + private static final String TAG = "JCameraView"; | ||
| 25 | + private CameraSizeComparator sizeComparator = new CameraSizeComparator(); | ||
| 26 | + private static CameraParamUtil cameraParamUtil = null; | ||
| 27 | + | ||
| 28 | + private CameraParamUtil() { | ||
| 29 | + | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public static CameraParamUtil getInstance() { | ||
| 33 | + if (cameraParamUtil == null) { | ||
| 34 | + cameraParamUtil = new CameraParamUtil(); | ||
| 35 | + return cameraParamUtil; | ||
| 36 | + } else { | ||
| 37 | + return cameraParamUtil; | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public Camera.Size getPreviewSize(List<Camera.Size> list, int th, float rate) { | ||
| 42 | + Collections.sort(list, sizeComparator); | ||
| 43 | + int i = 0; | ||
| 44 | + for (Camera.Size s : list) { | ||
| 45 | + if ((s.width > th) && equalRate(s, rate)) { | ||
| 46 | + Log.i(TAG, "MakeSure Preview :w = " + s.width + " h = " + s.height); | ||
| 47 | + break; | ||
| 48 | + } | ||
| 49 | + i++; | ||
| 50 | + } | ||
| 51 | + if (i == list.size()) { | ||
| 52 | + return getBestSize(list, rate); | ||
| 53 | + } else { | ||
| 54 | + return list.get(i); | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + public Camera.Size getPictureSize(List<Camera.Size> list, int th, float rate) { | ||
| 59 | + Collections.sort(list, sizeComparator); | ||
| 60 | + int i = 0; | ||
| 61 | + for (Camera.Size s : list) { | ||
| 62 | + if ((s.width > th) && equalRate(s, rate)) { | ||
| 63 | + Log.i(TAG, "MakeSure Picture :w = " + s.width + " h = " + s.height); | ||
| 64 | + break; | ||
| 65 | + } | ||
| 66 | + i++; | ||
| 67 | + } | ||
| 68 | + if (i == list.size()) { | ||
| 69 | + return getBestSize(list, rate); | ||
| 70 | + } else { | ||
| 71 | + return list.get(i); | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + private Camera.Size getBestSize(List<Camera.Size> list, float rate) { | ||
| 76 | + float previewDisparity = 100; | ||
| 77 | + int index = 0; | ||
| 78 | + for (int i = 0; i < list.size(); i++) { | ||
| 79 | + Camera.Size cur = list.get(i); | ||
| 80 | + float prop = (float) cur.width / (float) cur.height; | ||
| 81 | + if (Math.abs(rate - prop) < previewDisparity) { | ||
| 82 | + previewDisparity = Math.abs(rate - prop); | ||
| 83 | + index = i; | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + return list.get(index); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + | ||
| 90 | + private boolean equalRate(Camera.Size s, float rate) { | ||
| 91 | + float r = (float) (s.width) / (float) (s.height); | ||
| 92 | + return Math.abs(r - rate) <= 0.2; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + public boolean isSupportedFocusMode(List<String> focusList, String focusMode) { | ||
| 96 | + for (int i = 0; i < focusList.size(); i++) { | ||
| 97 | + if (focusMode.equals(focusList.get(i))) { | ||
| 98 | + Log.i(TAG, "FocusMode supported " + focusMode); | ||
| 99 | + return true; | ||
| 100 | + } | ||
| 101 | + } | ||
| 102 | + Log.i(TAG, "FocusMode not supported " + focusMode); | ||
| 103 | + return false; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + public boolean isSupportedPictureFormats(List<Integer> supportedPictureFormats, int jpeg) { | ||
| 107 | + for (int i = 0; i < supportedPictureFormats.size(); i++) { | ||
| 108 | + if (jpeg == supportedPictureFormats.get(i)) { | ||
| 109 | + Log.i(TAG, "Formats supported " + jpeg); | ||
| 110 | + return true; | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | + Log.i(TAG, "Formats not supported " + jpeg); | ||
| 114 | + return false; | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + private class CameraSizeComparator implements Comparator<Camera.Size> { | ||
| 118 | + public int compare(Camera.Size lhs, Camera.Size rhs) { | ||
| 119 | + if (lhs.width == rhs.width) { | ||
| 120 | + return 0; | ||
| 121 | + } else if (lhs.width > rhs.width) { | ||
| 122 | + return 1; | ||
| 123 | + } else { | ||
| 124 | + return -1; | ||
| 125 | + } | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + public int getCameraDisplayOrientation(Context context, int cameraId) { | ||
| 131 | + Camera.CameraInfo info = new Camera.CameraInfo(); | ||
| 132 | + try { | ||
| 133 | + Camera.getCameraInfo(cameraId, info); | ||
| 134 | + } catch (Exception e) { | ||
| 135 | + Log.e("CameraInterface", "像机ID识别错误", e); | ||
| 136 | + AlertUtil.showFailedToast(context,"像机ID识别错误"+cameraId); | ||
| 137 | + } | ||
| 138 | + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); | ||
| 139 | + int rotation = wm.getDefaultDisplay().getRotation(); | ||
| 140 | + int degrees = 0; | ||
| 141 | + switch (rotation) { | ||
| 142 | + case Surface.ROTATION_0: | ||
| 143 | + degrees = 0; | ||
| 144 | + break; | ||
| 145 | + case Surface.ROTATION_90: | ||
| 146 | + degrees = 90; | ||
| 147 | + break; | ||
| 148 | + case Surface.ROTATION_180: | ||
| 149 | + degrees = 180; | ||
| 150 | + break; | ||
| 151 | + case Surface.ROTATION_270: | ||
| 152 | + degrees = 270; | ||
| 153 | + break; | ||
| 154 | + } | ||
| 155 | + int result; | ||
| 156 | + if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { | ||
| 157 | + result = (info.orientation + degrees) % 360; | ||
| 158 | + result = (360 - result) % 360; // compensate the mirror | ||
| 159 | + } else { | ||
| 160 | + // back-facing | ||
| 161 | + result = (info.orientation - degrees + 360) % 360; | ||
| 162 | + } | ||
| 163 | + return result; | ||
| 164 | + } | ||
| 165 | +} |
lib_media/src/main/java/com/cnlive/media/utils/DeviceUtil.java
0 → 100644
| 1 | +package com.cnlive.media.utils; | ||
| 2 | + | ||
| 3 | +import android.os.Build; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * ===================================== | ||
| 7 | + * 作 者: 陈嘉桐 | ||
| 8 | + * 版 本:1.1.4 | ||
| 9 | + * 创建日期:2017/6/9 | ||
| 10 | + * 描 述: | ||
| 11 | + * ===================================== | ||
| 12 | + */ | ||
| 13 | +public class DeviceUtil { | ||
| 14 | + | ||
| 15 | + private static String[] huaweiRongyao = { | ||
| 16 | + "hwH60", //荣耀6 | ||
| 17 | + "hwPE", //荣耀6 plus | ||
| 18 | + "hwH30", //3c | ||
| 19 | + "hwHol", //3c畅玩版 | ||
| 20 | + "hwG750", //3x | ||
| 21 | + "hw7D", //x1 | ||
| 22 | + "hwChe2", //x1 | ||
| 23 | + }; | ||
| 24 | + | ||
| 25 | + public static String getDeviceInfo() { | ||
| 26 | + String handSetInfo = | ||
| 27 | + "手机型号:" + Build.DEVICE + | ||
| 28 | + "\n系统版本:" + Build.VERSION.RELEASE + | ||
| 29 | + "\nSDK版本:" + Build.VERSION.SDK_INT; | ||
| 30 | + return handSetInfo; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public static String getDeviceModel() { | ||
| 34 | + return Build.DEVICE; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public static boolean isHuaWeiRongyao() { | ||
| 38 | + int length = huaweiRongyao.length; | ||
| 39 | + for (int i = 0; i < length; i++) { | ||
| 40 | + if (huaweiRongyao[i].equals(getDeviceModel())) { | ||
| 41 | + return true; | ||
| 42 | + } | ||
| 43 | + } | ||
| 44 | + return false; | ||
| 45 | + } | ||
| 46 | +} |
lib_media/src/main/java/com/cnlive/media/utils/FileUtil.java
0 → 100644
| 1 | +package com.cnlive.media.utils; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.graphics.Bitmap; | ||
| 5 | +import android.os.Build; | ||
| 6 | +import android.os.Environment; | ||
| 7 | + | ||
| 8 | +import java.io.BufferedOutputStream; | ||
| 9 | +import java.io.File; | ||
| 10 | +import java.io.FileOutputStream; | ||
| 11 | +import java.io.IOException; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * ===================================== | ||
| 15 | + * 作 者: 陈嘉桐 | ||
| 16 | + * 版 本:1.1.4 | ||
| 17 | + * 创建日期:2017/4/25 | ||
| 18 | + * 描 述: | ||
| 19 | + * ===================================== | ||
| 20 | + */ | ||
| 21 | +public class FileUtil { | ||
| 22 | + private static final String TAG = "CJT"; | ||
| 23 | + private static String storagePath = ""; | ||
| 24 | + private static String DST_FOLDER_NAME = "JCamera"; | ||
| 25 | + | ||
| 26 | + private static String initPath(Context context) { | ||
| 27 | + if (storagePath.equals("")) { | ||
| 28 | + storagePath = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ? context.getExternalFilesDir("") : Environment.getExternalStorageDirectory()).getAbsolutePath() + File.separator + DST_FOLDER_NAME; | ||
| 29 | + File f = new File(storagePath); | ||
| 30 | + if (!f.exists()) { | ||
| 31 | + f.mkdir(); | ||
| 32 | + } | ||
| 33 | + } | ||
| 34 | + return storagePath; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public static String saveBitmap(Context context,String dir, Bitmap b) { | ||
| 38 | + DST_FOLDER_NAME = dir; | ||
| 39 | + | ||
| 40 | + String path = initPath(context); | ||
| 41 | + long dataTake = System.currentTimeMillis(); | ||
| 42 | + String jpegName = path + File.separator + "picture_" + dataTake + ".jpg"; | ||
| 43 | + try { | ||
| 44 | + FileOutputStream fout = new FileOutputStream(jpegName); | ||
| 45 | + BufferedOutputStream bos = new BufferedOutputStream(fout); | ||
| 46 | + b.compress(Bitmap.CompressFormat.JPEG, 100, bos); | ||
| 47 | + bos.flush(); | ||
| 48 | + bos.close(); | ||
| 49 | + return jpegName; | ||
| 50 | + } catch (IOException e) { | ||
| 51 | + e.printStackTrace(); | ||
| 52 | + return ""; | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + public static boolean deleteFile(String url) { | ||
| 57 | + boolean result = false; | ||
| 58 | + File file = new File(url); | ||
| 59 | + if (file.exists()) { | ||
| 60 | + result = file.delete(); | ||
| 61 | + } | ||
| 62 | + return result; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + public static boolean isExternalStorageWritable() { | ||
| 66 | + String state = Environment.getExternalStorageState(); | ||
| 67 | + if (Environment.MEDIA_MOUNTED.equals(state)) { | ||
| 68 | + return true; | ||
| 69 | + } | ||
| 70 | + return false; | ||
| 71 | + } | ||
| 72 | +} |
lib_media/src/main/java/com/cnlive/media/utils/FileUtils.java
| @@ -224,6 +224,17 @@ public class FileUtils { | @@ -224,6 +224,17 @@ public class FileUtils { | ||
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | } | 226 | } |
| 227 | - | 227 | + /** |
| 228 | + * Java文件操作 获取文件扩展名 | ||
| 229 | + */ | ||
| 230 | + public static String getExtensionName(String filename) { | ||
| 231 | + if ((filename != null) && (filename.length() > 0)) { | ||
| 232 | + int dot = filename.lastIndexOf('.'); | ||
| 233 | + if ((dot > -1) && (dot < (filename.length() - 1))) { | ||
| 234 | + return filename.substring(dot + 1); | ||
| 235 | + } | ||
| 236 | + } | ||
| 237 | + return ""; | ||
| 238 | + } | ||
| 228 | 239 | ||
| 229 | } | 240 | } |
lib_media/src/main/java/com/cnlive/media/utils/IDUtils.java
0 → 100644
| 1 | +package com.cnlive.media.utils; | ||
| 2 | + | ||
| 3 | +public class IDUtils { | ||
| 4 | + private static byte[] lock = new byte[0]; | ||
| 5 | + | ||
| 6 | + // 位数,默认是8位 | ||
| 7 | + private final static long w = 100000000; | ||
| 8 | + | ||
| 9 | + public static String createID() { | ||
| 10 | + long r = 0; | ||
| 11 | + synchronized (lock) { | ||
| 12 | + r = (long) ((Math.random() + 1) * w); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + return System.currentTimeMillis() + String.valueOf(r).substring(1); | ||
| 16 | + } | ||
| 17 | +} | ||
| 0 | \ No newline at end of file | 18 | \ No newline at end of file |
lib_media/src/main/java/com/cnlive/media/utils/LogUtil.java
0 → 100644
| 1 | +package com.cnlive.media.utils; | ||
| 2 | + | ||
| 3 | +import android.util.Log; | ||
| 4 | + | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * ===================================== | ||
| 8 | + * 作 者: 陈嘉桐 | ||
| 9 | + * 版 本:1.1.4 | ||
| 10 | + * 创建日期:2017/9/7 | ||
| 11 | + * 描 述: | ||
| 12 | + * ===================================== | ||
| 13 | + */ | ||
| 14 | +public class LogUtil { | ||
| 15 | + | ||
| 16 | + private static final String DEFAULT_TAG = "CJT"; | ||
| 17 | + | ||
| 18 | + public static void i(String tag, String msg) { | ||
| 19 | +// if (DEBUG) | ||
| 20 | + Log.i(tag, msg); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public static void v(String tag, String msg) { | ||
| 24 | + Log.v(tag, msg); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public static void d(String tag, String msg) { | ||
| 28 | + Log.d(tag, msg); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public static void e(String tag, String msg) { | ||
| 32 | + Log.e(tag, msg); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public static void i(String msg) { | ||
| 36 | + i(DEFAULT_TAG, msg); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + public static void v(String msg) { | ||
| 40 | + v(DEFAULT_TAG, msg); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public static void d(String msg) { | ||
| 44 | + d(DEFAULT_TAG, msg); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public static void e(String msg) { | ||
| 48 | + e(DEFAULT_TAG, msg); | ||
| 49 | + } | ||
| 50 | +} |
lib_media/src/main/java/com/cnlive/media/utils/QiniuVideoUtil.java
| 1 | -package com.cnlive.media.utils; | ||
| 2 | - | ||
| 3 | -import android.content.Context; | ||
| 4 | - | ||
| 5 | -import com.qiniu.pili.droid.shortvideo.PLShortVideoEnv; | ||
| 6 | - | ||
| 7 | -/** | ||
| 8 | - * 作 者 : wkq | ||
| 9 | - * <p> | ||
| 10 | - * 时 间 : 2020/10/29 9:46 | ||
| 11 | - * <p> | ||
| 12 | - * 名 字 : QiniuVideoUtil | ||
| 13 | - * <p> | ||
| 14 | - * 简 介 : 七牛 初始化 | ||
| 15 | - */ | ||
| 16 | -public class QiniuVideoUtil { | ||
| 17 | - /** | ||
| 18 | - * 初始化七牛sdk | ||
| 19 | - * @param context | ||
| 20 | - */ | ||
| 21 | - public static void initVideo(Context context) { | ||
| 22 | - PLShortVideoEnv.init(context.getApplicationContext()); | ||
| 23 | - } | ||
| 24 | - | ||
| 25 | - /** | ||
| 26 | - * 检查授权状态 | ||
| 27 | - * @param context | ||
| 28 | - * @param listener | ||
| 29 | - */ | ||
| 30 | - public static void chcekInitState(Context context, QiniuVideoInitListener listener) { | ||
| 31 | - PLShortVideoEnv.checkAuthentication(context, i -> { | ||
| 32 | - listener.isInitState(i); | ||
| 33 | - }); | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - public interface QiniuVideoInitListener{ | ||
| 37 | - void isInitState(int state); | ||
| 38 | - } | ||
| 39 | -} | 1 | +//package com.cnlive.media.utils; |
| 2 | +// | ||
| 3 | +//import android.content.Context; | ||
| 4 | +// | ||
| 5 | +//import com.qiniu.pili.droid.shortvideo.PLShortVideoEnv; | ||
| 6 | +// | ||
| 7 | +///** | ||
| 8 | +// * 作 者 : wkq | ||
| 9 | +// * <p> | ||
| 10 | +// * 时 间 : 2020/10/29 9:46 | ||
| 11 | +// * <p> | ||
| 12 | +// * 名 字 : QiniuVideoUtil | ||
| 13 | +// * <p> | ||
| 14 | +// * 简 介 : 七牛 初始化 | ||
| 15 | +// */ | ||
| 16 | +//public class QiniuVideoUtil { | ||
| 17 | +// /** | ||
| 18 | +// * 初始化七牛sdk | ||
| 19 | +// * @param context | ||
| 20 | +// */ | ||
| 21 | +// public static void initVideo(Context context) { | ||
| 22 | +// PLShortVideoEnv.init(context.getApplicationContext()); | ||
| 23 | +// } | ||
| 24 | +// | ||
| 25 | +// /** | ||
| 26 | +// * 检查授权状态 | ||
| 27 | +// * @param context | ||
| 28 | +// * @param listener | ||
| 29 | +// */ | ||
| 30 | +// public static void chcekInitState(Context context, QiniuVideoInitListener listener) { | ||
| 31 | +// PLShortVideoEnv.checkAuthentication(context, i -> { | ||
| 32 | +// listener.isInitState(i); | ||
| 33 | +// }); | ||
| 34 | +// } | ||
| 35 | +// | ||
| 36 | +// public interface QiniuVideoInitListener{ | ||
| 37 | +// void isInitState(int state); | ||
| 38 | +// } | ||
| 39 | +//} |
lib_media/src/main/res/drawable/jiashen_upload_pregressbar.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:duration="100" | ||
| 4 | + android:fromDegrees="0" | ||
| 5 | + android:pivotX="50%" | ||
| 6 | + android:pivotY="50%" | ||
| 7 | + android:toDegrees="360"> | ||
| 8 | + <shape | ||
| 9 | + android:innerRadius="15dp" | ||
| 10 | + android:shape="ring" | ||
| 11 | + android:thickness="5dp" | ||
| 12 | + android:useLevel="false"> | ||
| 13 | + <gradient | ||
| 14 | + android:centerY="0.50" | ||
| 15 | + android:endColor="#ff12a0ff" | ||
| 16 | + android:startColor="#ffffff" | ||
| 17 | + android:type="sweep" | ||
| 18 | + android:useLevel="false" /> | ||
| 19 | + </shape> | ||
| 20 | +</animated-rotate> | ||
| 0 | \ No newline at end of file | 21 | \ No newline at end of file |
lib_media/src/main/res/drawable/post1.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 3 | + <item > | ||
| 4 | + <shape android:shape="rectangle"> | ||
| 5 | + <solid android:color="#12A0FF" /> | ||
| 6 | + <corners android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp" android:topLeftRadius="20dp" android:topRightRadius="20dp" /> | ||
| 7 | + </shape> | ||
| 8 | + </item> | ||
| 9 | +</selector> | ||
| 0 | \ No newline at end of file | 10 | \ No newline at end of file |
lib_media/src/main/res/drawable/progressbar.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | + | ||
| 3 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 4 | + <item android:id="@android:id/background"> | ||
| 5 | + <shape> | ||
| 6 | + <corners android:radius="3dp" /> | ||
| 7 | + <solid android:color="#E6E6E6" /> | ||
| 8 | + </shape> | ||
| 9 | + </item> | ||
| 10 | + | ||
| 11 | + <item android:id="@android:id/progress"> | ||
| 12 | + <clip> | ||
| 13 | + <shape> | ||
| 14 | + <corners android:radius="3dp" /> | ||
| 15 | + <gradient | ||
| 16 | + android:angle="45" | ||
| 17 | + android:endColor="#12A0FF" | ||
| 18 | + android:startColor="#12A0FF" /> | ||
| 19 | + </shape> | ||
| 20 | + </clip> | ||
| 21 | + </item> | ||
| 22 | +</layer-list> |
lib_media/src/main/res/layout/camera_intent.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 4 | + android:layout_width="match_parent" | ||
| 5 | + android:layout_height="match_parent" | ||
| 6 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 7 | + android:background="@color/transparent"> | ||
| 8 | + | ||
| 9 | + <com.cnlive.media.ui.widget.record.JCameraView | ||
| 10 | + android:id="@+id/jcameraview" | ||
| 11 | + android:layout_width="wrap_content" | ||
| 12 | + android:layout_height="wrap_content" | ||
| 13 | + android:layout_centerInParent="true" | ||
| 14 | + app:duration_max="10000" | ||
| 15 | + app:iconMargin="20dp" | ||
| 16 | + app:iconSize="30dp" | ||
| 17 | + app:iconSrc="@drawable/fb_xiangji" | ||
| 18 | + android:layout_gravity="center" | ||
| 19 | + /> | ||
| 20 | + | ||
| 21 | + <androidx.recyclerview.widget.RecyclerView | ||
| 22 | + android:id="@+id/recyclerView" | ||
| 23 | + android:layout_width="50dp" | ||
| 24 | + android:layout_height="300dp" | ||
| 25 | + android:layout_gravity="end" | ||
| 26 | + android:layout_marginTop="90dp" | ||
| 27 | + android:layout_marginRight="11dp" | ||
| 28 | + android:minHeight="200dp" /> | ||
| 29 | + | ||
| 30 | + <ImageView | ||
| 31 | + android:id="@+id/cameraback" | ||
| 32 | + android:layout_width="wrap_content" | ||
| 33 | + android:layout_height="wrap_content" | ||
| 34 | + android:src="@drawable/picker_xzq_fh" | ||
| 35 | + android:layout_marginTop="17dp" | ||
| 36 | + android:padding="15dp" | ||
| 37 | + android:layout_marginStart="17dp" | ||
| 38 | + android:layout_marginLeft="17dp" /> | ||
| 39 | +</FrameLayout> | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
lib_media/src/main/res/layout/camera_view.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:layout_width="match_parent" | ||
| 4 | + android:layout_height="match_parent" | ||
| 5 | + android:background="#000000" | ||
| 6 | + android:orientation="vertical"> | ||
| 7 | + | ||
| 8 | + <FrameLayout | ||
| 9 | + android:layout_width="match_parent" | ||
| 10 | + android:layout_height="match_parent"> | ||
| 11 | + | ||
| 12 | + <VideoView | ||
| 13 | + android:id="@+id/video_preview" | ||
| 14 | + android:layout_width="match_parent" | ||
| 15 | + android:layout_height="match_parent" | ||
| 16 | + android:layout_gravity="center" /> | ||
| 17 | + | ||
| 18 | + <ImageView | ||
| 19 | + android:id="@+id/image_photo" | ||
| 20 | + android:layout_width="match_parent" | ||
| 21 | + android:layout_height="match_parent" | ||
| 22 | + android:background="#000" | ||
| 23 | + android:visibility="invisible" /> | ||
| 24 | + </FrameLayout> | ||
| 25 | + | ||
| 26 | + <LinearLayout | ||
| 27 | + android:layout_width="wrap_content" | ||
| 28 | + android:layout_height="48dp" | ||
| 29 | + android:layout_gravity="right" | ||
| 30 | + android:layout_marginRight="15dp" | ||
| 31 | + android:layout_marginTop="30dp" | ||
| 32 | + android:orientation="horizontal"> | ||
| 33 | + | ||
| 34 | + <ImageView | ||
| 35 | + android:id="@+id/image_flash" | ||
| 36 | + android:layout_width="25dp" | ||
| 37 | + android:layout_height="24dp" | ||
| 38 | + android:layout_gravity="center_vertical" | ||
| 39 | + android:layout_margin="16dp" | ||
| 40 | + android:src="@drawable/ic_flash_on" /> | ||
| 41 | + | ||
| 42 | + <ImageView | ||
| 43 | + android:id="@+id/image_switch" | ||
| 44 | + android:layout_width="25dp" | ||
| 45 | + android:layout_height="22dp" | ||
| 46 | + android:layout_gravity="center_vertical" | ||
| 47 | + android:layout_margin="16dp" /> | ||
| 48 | + </LinearLayout> | ||
| 49 | + | ||
| 50 | + <com.cnlive.media.ui.widget.record.CaptureLayout | ||
| 51 | + android:id="@+id/capture_layout" | ||
| 52 | + android:layout_width="match_parent" | ||
| 53 | + android:layout_height="match_parent" | ||
| 54 | + android:layout_marginBottom="30dp" | ||
| 55 | + android:layout_gravity="bottom|center" /> | ||
| 56 | + | ||
| 57 | + <com.cnlive.media.ui.widget.record.FoucsView | ||
| 58 | + android:id="@+id/fouce_view" | ||
| 59 | + android:layout_width="wrap_content" | ||
| 60 | + android:layout_height="wrap_content" | ||
| 61 | + android:layout_gravity="center" | ||
| 62 | + android:visibility="invisible" /> | ||
| 63 | +</FrameLayout> | ||
| 0 | \ No newline at end of file | 64 | \ No newline at end of file |
lib_media/src/main/res/layout/layout_alert_dialog_one_btn.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 4 | + android:layout_width="match_parent" | ||
| 5 | + android:layout_height="wrap_content" | ||
| 6 | + android:background="@drawable/picker_bg_dialog" | ||
| 7 | + android:gravity="center" | ||
| 8 | + android:orientation="vertical"> | ||
| 9 | + | ||
| 10 | + <TextView | ||
| 11 | + android:id="@+id/title" | ||
| 12 | + android:layout_width="wrap_content" | ||
| 13 | + android:layout_height="wrap_content" | ||
| 14 | + android:layout_centerHorizontal="true" | ||
| 15 | + android:layout_marginBottom="10dp" | ||
| 16 | + android:layout_marginLeft="20dp" | ||
| 17 | + android:layout_marginRight="20dp" | ||
| 18 | + android:layout_marginTop="20dp" | ||
| 19 | + android:textColor="@color/color_282828" | ||
| 20 | + android:textSize="18sp" | ||
| 21 | + tools:text="title" /> | ||
| 22 | + | ||
| 23 | + <TextView | ||
| 24 | + android:id="@+id/content" | ||
| 25 | + android:layout_width="wrap_content" | ||
| 26 | + android:layout_height="wrap_content" | ||
| 27 | + android:layout_below="@+id/title" | ||
| 28 | + android:layout_centerHorizontal="true" | ||
| 29 | + android:layout_marginBottom="10dp" | ||
| 30 | + android:layout_marginLeft="20dp" | ||
| 31 | + android:layout_marginRight="20dp" | ||
| 32 | + android:textColor="#666666" | ||
| 33 | + android:textSize="14sp" | ||
| 34 | + tools:text="content"/> | ||
| 35 | + | ||
| 36 | + <View | ||
| 37 | + android:id="@+id/line1" | ||
| 38 | + android:layout_width="match_parent" | ||
| 39 | + android:layout_height="@dimen/list_divider_height" | ||
| 40 | + android:layout_marginTop="10dp" | ||
| 41 | + android:background="@color/colorDivider" /> | ||
| 42 | + | ||
| 43 | + | ||
| 44 | + <TextView | ||
| 45 | + android:id="@+id/btn" | ||
| 46 | + android:layout_width="match_parent" | ||
| 47 | + android:layout_height="wrap_content" | ||
| 48 | + android:gravity="center" | ||
| 49 | + android:paddingBottom="13dp" | ||
| 50 | + android:paddingTop="13dp" | ||
| 51 | + android:textSize="18sp" /> | ||
| 52 | + | ||
| 53 | + | ||
| 54 | +</LinearLayout> | ||
| 0 | \ No newline at end of file | 55 | \ No newline at end of file |
lib_media/src/main/res/layout/list_item_circl.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<RelativeLayout | ||
| 3 | + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="50dp" | ||
| 4 | + android:layout_height="wrap_content" | ||
| 5 | + > | ||
| 6 | + <!-- <RelativeLayout | ||
| 7 | + android:id="@+id/itemm" | ||
| 8 | + android:layout_width="wrap_content" | ||
| 9 | + android:layout_height="wrap_content" | ||
| 10 | + >--> | ||
| 11 | + | ||
| 12 | + <!-- <View | ||
| 13 | + | ||
| 14 | + android:layout_width="wrap_content" | ||
| 15 | + android:layout_height="wrap_content" | ||
| 16 | + android:layout_alignLeft="@+id/userImage" | ||
| 17 | + android:layout_alignTop="@+id/userImage" | ||
| 18 | + android:background="#eeeeee" />--> | ||
| 19 | + | ||
| 20 | + <ImageView | ||
| 21 | + android:id="@+id/userImage" | ||
| 22 | + android:layout_width="50dp" | ||
| 23 | + android:layout_height="wrap_content" | ||
| 24 | + android:src="@drawable/publish_zw" | ||
| 25 | + android:layout_marginBottom="16dp" | ||
| 26 | + /> | ||
| 27 | + | ||
| 28 | + <!-- <TextView | ||
| 29 | + android:id="@+id/userName" | ||
| 30 | + android:layout_width="wrap_content" | ||
| 31 | + android:layout_height="wrap_content" | ||
| 32 | + android:layout_alignBottom="@+id/userImage" | ||
| 33 | + android:layout_alignTop="@+id/userImage" | ||
| 34 | + android:layout_marginLeft="15dp" | ||
| 35 | + android:layout_toRightOf="@+id/userImage" | ||
| 36 | + android:layout_marginRight="7dp" | ||
| 37 | + android:text="白老板" | ||
| 38 | + android:gravity="center" | ||
| 39 | + android:textColor="@color/color_282828" | ||
| 40 | + android:textSize="15sp" | ||
| 41 | + />--> | ||
| 42 | + | ||
| 43 | + <!-- <View | ||
| 44 | + android:id="@+id/divider" | ||
| 45 | + android:layout_width="match_parent" | ||
| 46 | + android:layout_height="1dp" | ||
| 47 | + android:layout_below="@+id/userName" | ||
| 48 | + android:layout_marginTop="20dp" | ||
| 49 | + android:background="#eeeeee" />--> | ||
| 50 | + | ||
| 51 | + <!-- </RelativeLayout>--> | ||
| 52 | + | ||
| 53 | +</RelativeLayout> | ||
| 0 | \ No newline at end of file | 54 | \ No newline at end of file |
lib_media/src/main/res/values/attrs.xml
| 1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
| 2 | <resources> | 2 | <resources> |
| 3 | - | 3 | + <attr name="iconSize" format="dimension" /> |
| 4 | + <attr name="iconMargin" format="dimension" /> | ||
| 5 | + <attr name="iconSrc" format="reference" /> | ||
| 6 | + <attr name="iconLeft" format="reference" /> | ||
| 7 | + <attr name="iconRight" format="reference" /> | ||
| 8 | + <attr name="duration_max" format="integer" /> | ||
| 4 | 9 | ||
| 5 | <declare-styleable name="SubsamplingScaleImageView"> | 10 | <declare-styleable name="SubsamplingScaleImageView"> |
| 6 | - <attr name="src" format="reference"/> | ||
| 7 | - <attr name="assetName" format="string"/> | ||
| 8 | - <attr name="panEnabled" format="boolean"/> | ||
| 9 | - <attr name="zoomEnabled" format="boolean"/> | ||
| 10 | - <attr name="quickScaleEnabled" format="boolean"/> | ||
| 11 | - <attr name="tileBackgroundColor" format="color"/> | 11 | + <attr name="src" format="reference" /> |
| 12 | + <attr name="assetName" format="string" /> | ||
| 13 | + <attr name="panEnabled" format="boolean" /> | ||
| 14 | + <attr name="zoomEnabled" format="boolean" /> | ||
| 15 | + <attr name="quickScaleEnabled" format="boolean" /> | ||
| 16 | + <attr name="tileBackgroundColor" format="color" /> | ||
| 12 | </declare-styleable> | 17 | </declare-styleable> |
| 13 | 18 | ||
| 14 | <declare-styleable name="TypeButtonStyle"> | 19 | <declare-styleable name="TypeButtonStyle"> |
| 15 | - <attr name="typeBg" format="reference"/> | ||
| 16 | - <attr name="typeSize" format="dimension"/> | 20 | + <attr name="typeBg" format="reference" /> |
| 21 | + <attr name="typeSize" format="dimension" /> | ||
| 17 | 22 | ||
| 18 | </declare-styleable> | 23 | </declare-styleable> |
| 19 | 24 | ||
| 20 | <declare-styleable name="MediaShootViewStyle"> | 25 | <declare-styleable name="MediaShootViewStyle"> |
| 21 | 26 | ||
| 22 | - <attr name="innerRadius" format="dimension" formatted="false"/> | ||
| 23 | - <attr name="outerRadius" format="dimension" formatted="false"/> | ||
| 24 | - <attr name="innerColor" format="color" formatted="false"/> | ||
| 25 | - <attr name="outerColor" format="color" formatted="false"/> | 27 | + <attr name="innerRadius" format="dimension" formatted="false" /> |
| 28 | + <attr name="outerRadius" format="dimension" formatted="false" /> | ||
| 29 | + <attr name="innerColor" format="color" formatted="false" /> | ||
| 30 | + <attr name="outerColor" format="color" formatted="false" /> | ||
| 26 | 31 | ||
| 27 | 32 | ||
| 28 | - <attr name="mediaProgressColor" format="color" formatted="false"/> | ||
| 29 | - <attr name="mediaProgressWidth" format="dimension" formatted="false"/> | 33 | + <attr name="mediaProgressColor" format="color" formatted="false" /> |
| 34 | + <attr name="mediaProgressWidth" format="dimension" formatted="false" /> | ||
| 30 | 35 | ||
| 31 | - <attr name="curProgress" format="integer" formatted="false"/> | ||
| 32 | - <attr name="maxProgress" format="integer" formatted="false"/> | 36 | + <attr name="curProgress" format="integer" formatted="false" /> |
| 37 | + <attr name="maxProgress" format="integer" formatted="false" /> | ||
| 33 | 38 | ||
| 34 | </declare-styleable> | 39 | </declare-styleable> |
| 35 | 40 | ||
| 36 | <declare-styleable name="ReturnButtonStyle"> | 41 | <declare-styleable name="ReturnButtonStyle"> |
| 37 | - <attr name="strokeWidth" format="dimension"/> | ||
| 38 | - <attr name="strokeColor" format="color"/> | 42 | + <attr name="strokeWidth" format="dimension" /> |
| 43 | + <attr name="strokeColor" format="color" /> | ||
| 39 | </declare-styleable> | 44 | </declare-styleable> |
| 40 | 45 | ||
| 46 | + <declare-styleable name="JCameraView"> | ||
| 47 | + <attr name="iconSize" /> | ||
| 48 | + <attr name="iconMargin" /> | ||
| 49 | + <attr name="iconSrc" /> | ||
| 50 | + <attr name="iconLeft" /> | ||
| 51 | + <attr name="iconRight" /> | ||
| 52 | + <attr name="duration_max" /> | ||
| 53 | + </declare-styleable> | ||
| 54 | + <declare-styleable name="OnLineCameraView"> | ||
| 55 | + <attr name="iconSize" /> | ||
| 56 | + <attr name="iconMargin" /> | ||
| 57 | + <attr name="iconSrc" /> | ||
| 58 | + <attr name="iconLeft" /> | ||
| 59 | + <attr name="iconRight" /> | ||
| 60 | + <attr name="duration_max" /> | ||
| 61 | + </declare-styleable> | ||
| 41 | </resources> | 62 | </resources> |
| 42 | \ No newline at end of file | 63 | \ No newline at end of file |
lib_media/src/main/res/values/color.xml
| @@ -27,6 +27,7 @@ | @@ -27,6 +27,7 @@ | ||
| 27 | <color name="black">#FF020202</color> | 27 | <color name="black">#FF020202</color> |
| 28 | <color name="daoshu">#8A8080</color> | 28 | <color name="daoshu">#8A8080</color> |
| 29 | <color name="givaup">#999999</color> | 29 | <color name="givaup">#999999</color> |
| 30 | + <color name="color_3F93FD">#3F93FD</color> | ||
| 30 | 31 | ||
| 31 | <color name="color_defult_bg">#161c1e</color> | 32 | <color name="color_defult_bg">#161c1e</color> |
| 32 | <color name="color_defult_foot_bg">#21282C</color> | 33 | <color name="color_defult_foot_bg">#21282C</color> |