Commit ef93fa9fd4ba56f8c1751de847aef781800b814b
1 parent
6f705fd0
调整视频录制,删除七牛短视频sdk
Showing
21 changed files
with
3155 additions
and
1473 deletions
Too many changes to show.
To preserve performance only 21 of 59 files are displayed.
app/build.gradle
| ... | ... | @@ -13,6 +13,11 @@ android { |
| 13 | 13 | ndk { |
| 14 | 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 | 54 | implementation 'androidx.multidex:multidex:2.0.1' |
| 50 | 55 | // implementation 'com.cnlive.media:NewMediaPicker:1.1.4.28' |
| 51 | 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 | 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 | 8 | import android.os.Build; |
| 9 | 9 | import android.os.Bundle; |
| 10 | 10 | import android.os.Environment; |
| 11 | +import android.util.Log; | |
| 11 | 12 | import android.view.View; |
| 12 | 13 | |
| 13 | 14 | import com.cnlive.media.ImagePicker; |
| ... | ... | @@ -60,7 +61,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe |
| 60 | 61 | .maxVideoSize(100 * 1024 * 1024) |
| 61 | 62 | .isReturnUri(AndroidQUtil.isAndroidQ()) |
| 62 | 63 | .selectMode(PickerConfig.PICKER_IMAGE) |
| 63 | - .defaultSelectList(new ArrayList<Media>()) | |
| 64 | + .defaultSelectList(select) | |
| 64 | 65 | // .doCrop(1, 1, 40, 40) |
| 65 | 66 | .needCamera(true) |
| 66 | 67 | .builder() |
| ... | ... | @@ -87,8 +88,12 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe |
| 87 | 88 | new ImagePicker |
| 88 | 89 | .Builder() |
| 89 | 90 | .setJumpCameraMode(PickerConfig.CAMERA_MODE_ALL) |
| 91 | + .needCamera(true) | |
| 92 | + .setFrontCamera(false) | |
| 93 | + .defaultSelectList(select) | |
| 90 | 94 | .builder() |
| 91 | 95 | .startCamera(this, select, PickerConfig.PICKER_IMAGE, PickerConfig.DEFAULT_RESULT_CODE); |
| 96 | +// OnLineAnswerActivity.start(MainActivity.this, System.currentTimeMillis() / 1000, "102", new ArrayList<Media>()); | |
| 92 | 97 | break; |
| 93 | 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 | 4 | |
| 5 | 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 | 10 | public class MediaApplication extends Application { |
| ... | ... | @@ -14,6 +13,5 @@ public class MediaApplication extends Application { |
| 14 | 13 | super.onCreate(); |
| 15 | 14 | // ARouter.init(this); |
| 16 | 15 | MultiDex.install(this); |
| 17 | - QiniuVideoUtil.initVideo(this); | |
| 18 | 16 | } |
| 19 | 17 | } | ... | ... |
config.gradle
lib_media/build.gradle
| ... | ... | @@ -57,7 +57,7 @@ dependencies { |
| 57 | 57 | implementation "com.alibaba:arouter-api:$rootProject.arouterApiVersion" |
| 58 | 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 | 61 | implementation "com.qiniu:qiniu-android-sdk:$rootProject.qiniuAndroidSdk" |
| 62 | 62 | |
| 63 | 63 | implementation "com.cnlive.base:lib_util:$rootProject.libCnUtil" | ... | ... |
lib_media/src/main/AndroidManifest.xml
| ... | ... | @@ -17,11 +17,13 @@ |
| 17 | 17 | <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" /> |
| 18 | 18 | <uses-permission android:name="com.sec.android.provider.badge.permission.READ" /> |
| 19 | 19 | <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" /> |
| 20 | + | |
| 20 | 21 | <uses-feature android:name="android.hardware.camera" /> |
| 21 | 22 | <uses-feature android:name="android.hardware.camera.autofocus" /> |
| 23 | + | |
| 22 | 24 | <application |
| 23 | - android:resizeableActivity="true" | |
| 24 | - android:largeHeap="true"> | |
| 25 | + android:largeHeap="true" | |
| 26 | + android:resizeableActivity="true"> | |
| 25 | 27 | <activity |
| 26 | 28 | android:name="com.cnlive.media.ui.activity.MediaActivity" |
| 27 | 29 | android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" |
| ... | ... | @@ -60,6 +62,19 @@ |
| 60 | 62 | android:screenOrientation="portrait" |
| 61 | 63 | android:theme="@style/Theme.AppCompat.NoActionBar" |
| 62 | 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 | 79 | </application> |
| 65 | 80 | </manifest> |
| 66 | 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 | 4 | import android.app.Fragment; |
| 5 | 5 | import android.content.Context; |
| 6 | 6 | import android.content.Intent; |
| 7 | +import android.util.Log; | |
| 7 | 8 | |
| 8 | 9 | import com.cnlive.media.model.ImagePickerCropParams; |
| 9 | 10 | import com.cnlive.media.model.ImagePickerOptions; |
| 10 | 11 | import com.cnlive.media.media.entity.Media; |
| 12 | +import com.cnlive.media.ui.activity.DiyCameraActivity; | |
| 11 | 13 | import com.cnlive.media.ui.activity.MediaActivity; |
| 12 | 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 | 16 | import java.util.ArrayList; |
| 17 | 17 | |
| ... | ... | @@ -70,7 +70,7 @@ public class ImagePicker { |
| 70 | 70 | * @param resultCode 结果码 |
| 71 | 71 | */ |
| 72 | 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 | 74 | intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions); |
| 75 | 75 | intent.putExtra(PickerConfig.RESULT_CODE, resultCode); |
| 76 | 76 | intent.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true); |
| ... | ... | @@ -84,14 +84,16 @@ public class ImagePicker { |
| 84 | 84 | * @param requestCode 请求码 |
| 85 | 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 | 163 | return this; |
| 162 | 164 | } |
| 163 | 165 | |
| 166 | + public Builder setFrontCamera(boolean frontCamera) { | |
| 167 | + mOptions.setFrontCamera(frontCamera); | |
| 168 | + return this; | |
| 169 | + } | |
| 170 | + | |
| 164 | 171 | public Builder maxTime(int maxTime) { |
| 165 | 172 | mOptions.setMaxTime(maxTime); |
| 166 | 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 | 28 | import com.cnlive.media.PickerConfig; |
| 29 | 29 | import com.cnlive.media.media.entity.Folder; |
| 30 | 30 | import com.cnlive.media.media.entity.Media; |
| 31 | +import com.cnlive.media.ui.activity.DiyCameraActivity; | |
| 31 | 32 | import com.cnlive.media.ui.activity.ImageCropActivity; |
| 32 | 33 | import com.cnlive.media.ui.activity.MediaActivity; |
| 33 | -import com.cnlive.media.ui.activity.RecordActivity; | |
| 34 | 34 | import com.cnlive.media.ui.adapter.FolderAdapter; |
| 35 | 35 | import com.cnlive.media.ui.adapter.PreviewBottomMediaAdapter; |
| 36 | 36 | import com.cnlive.media.ui.fragment.MediaPickerFragment; |
| ... | ... | @@ -49,10 +49,10 @@ import com.cnlive.media.utils.observable.MeidaResultObservable; |
| 49 | 49 | import com.cnlive.media.utils.observable.SelectStateUpdateObservable; |
| 50 | 50 | import com.cnlive.media.R; |
| 51 | 51 | import com.hannesdorfmann.mosby3.mvp.MvpView; |
| 52 | -import com.qiniu.pili.droid.shortvideo.PLShortVideoEnv; | |
| 53 | 52 | |
| 54 | 53 | import java.util.ArrayList; |
| 55 | 54 | |
| 55 | +import static com.cnlive.media.PickerConfig.DEFAULT_RESULT_CODE; | |
| 56 | 56 | import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_CAMERA; |
| 57 | 57 | import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_READ; |
| 58 | 58 | |
| ... | ... | @@ -105,8 +105,6 @@ public class MediaView implements MvpView { |
| 105 | 105 | |
| 106 | 106 | private void initState() { |
| 107 | 107 | StatusBarUtil2.setColor(mActivity, mActivity.getResources().getColor(R.color.status_bar_color), 0); |
| 108 | -// //初始化七牛录制 | |
| 109 | - PLShortVideoEnv.init(mActivity.getApplicationContext()); | |
| 110 | 108 | MediaAddObservable.getInstance().addObserver(mActivity); |
| 111 | 109 | MeidaResultObservable.getInstance().addObserver(mActivity); |
| 112 | 110 | MediaSelectStateObservable.getInstance().addObserver(mActivity); |
| ... | ... | @@ -536,13 +534,13 @@ public class MediaView implements MvpView { |
| 536 | 534 | ), |
| 537 | 535 | false); |
| 538 | 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 | 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 | 2 | |
| 3 | 3 | import android.os.Parcel; |
| 4 | 4 | import android.os.Parcelable; |
| 5 | +import android.util.Log; | |
| 5 | 6 | |
| 6 | 7 | import com.cnlive.media.PickerConfig; |
| 7 | 8 | import com.cnlive.media.media.entity.Media; |
| ... | ... | @@ -49,7 +50,17 @@ public class ImagePickerOptions implements Parcelable { |
| 49 | 50 | public boolean isReturnUri = false; |
| 50 | 51 | //直接跳转相机 控制相机的模式 0 全支持 1 照片 2 视频 |
| 51 | 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 | 64 | public boolean isPreview() { |
| 54 | 65 | return isPreview; |
| 55 | 66 | } |
| ... | ... | @@ -59,7 +70,6 @@ public class ImagePickerOptions implements Parcelable { |
| 59 | 70 | } |
| 60 | 71 | |
| 61 | 72 | |
| 62 | - | |
| 63 | 73 | public int getJumpCameraMode() { |
| 64 | 74 | return jumpCameraMode; |
| 65 | 75 | } |
| ... | ... | @@ -197,6 +207,30 @@ public class ImagePickerOptions implements Parcelable { |
| 197 | 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 | 235 | @Override |
| 202 | 236 | public int describeContents() { |
| ... | ... | @@ -222,6 +256,7 @@ public class ImagePickerOptions implements Parcelable { |
| 222 | 256 | isReturnUri = in.readByte() != 0; |
| 223 | 257 | jumpCameraMode = in.readInt(); |
| 224 | 258 | isPreview = in.readByte() != 0; |
| 259 | + frontCamera = in.readByte() != 0; | |
| 225 | 260 | } |
| 226 | 261 | |
| 227 | 262 | public static final Creator<ImagePickerOptions> CREATOR = new Creator<ImagePickerOptions>() { |
| ... | ... | @@ -255,6 +290,7 @@ public class ImagePickerOptions implements Parcelable { |
| 255 | 290 | dest.writeByte((byte) (selectGift ? 1 : 0)); |
| 256 | 291 | dest.writeByte((byte) (isReturnUri ? 1 : 0)); |
| 257 | 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 | +} | ... | ... |