Преглед изворни кода

不再使用ffmpeg来取视频帧(x86模拟器加载插件不兼容该库)

zengjiebin пре 7 година
родитељ
комит
dde79a68ad

+ 87 - 0
app/src/main/java/cn/finalteam/rxgalleryfinal/utils/CameraUtil.java

@@ -0,0 +1,87 @@
+package cn.finalteam.rxgalleryfinal.utils;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.MediaStore;
+import android.util.Log;
+
+import com.sheep.jiuyan.samllsheep.SheepApp;
+import com.sheep.jiuyan.samllsheep.utils.ClassFileHelper;
+import com.sheep.jiuyan.samllsheep.utils.G;
+import com.yalantis.ucrop.UCrop;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import cn.finalteam.rxgalleryfinal.api.CameraCallBack;
+
+/**
+ * Created by realicing on 2018/12/10.
+ * realicing@sina.com
+ */
+public class CameraUtil {
+
+    public static String openCamera(Activity activity, boolean isImage) {
+        Intent captureIntent = isImage ? new Intent(MediaStore.ACTION_IMAGE_CAPTURE) : new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
+        if (captureIntent.resolveActivity(activity.getPackageManager()) == null) {
+            G.shortToast("相机不可用");
+            return null;
+        }
+
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
+        String filename = String.format(isImage ? IMAGE_STORE_FILE_NAME : VIDEO_STORE_FILE_NAME, dateFormat.format(new Date()));
+        File fileImagePath = new File(ClassFileHelper.DIR, filename);
+        String mImagePath = fileImagePath.getAbsolutePath();
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileImagePath));
+        } else {
+            ContentValues contentValues = new ContentValues(1);
+            contentValues.put(MediaStore.Images.Media.DATA, mImagePath);
+            Uri uri = SheepApp.getInstance().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
+            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+        }
+        if (!isImage) {
+            captureIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 15000L);
+        }
+        // video : 1: 高质量  0 低质量
+        //        captureIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
+        activity.startActivityForResult(captureIntent, isImage ? TAKE_IMAGE_REQUEST_CODE : TAKE_VIDEO_REQUEST_CODE);
+        return mImagePath;
+    }
+
+    public static void onActivityResult(Activity activity, int requestCode, String path, CameraCallBack cameraCallBack) {
+        Log.i(MediaUtils.class.getSimpleName(), "onActivityResult: requestCode=" + requestCode);
+        switch (requestCode) {
+            case TAKE_IMAGE_REQUEST_CODE:
+                if (path == null) {
+                    Log.i(MediaUtils.class.getSimpleName(), "拍照成功");
+                    cameraCallBack.onGetImageSuccess(null);
+                    break;
+                }
+                String cropFilePath = path.substring(0, path.lastIndexOf(".")) + "temp.png";
+                Log.i(MediaUtils.class.getSimpleName(), "拍照成功: " + cropFilePath);
+                cameraCallBack.onGetImageSuccess(cropFilePath);
+                UCrop.of(Uri.parse(path), Uri.parse(cropFilePath))
+                        .start(activity);
+                break;
+            case TAKE_VIDEO_REQUEST_CODE:
+                Log.i(MediaUtils.class.getSimpleName(), "摄像成功");
+                cameraCallBack.onGetVideoSuccess();
+                break;
+            case UCrop.REQUEST_CROP:
+                Log.i(MediaUtils.class.getSimpleName(), "裁剪成功");
+                cameraCallBack.onCropImageSuccess();
+                break;
+        }
+    }
+
+    public static final String IMAGE_STORE_FILE_NAME = "IMG_%s.jpg";
+    public static final String VIDEO_STORE_FILE_NAME = "IMG_%s.mp4";
+    public static final int TAKE_IMAGE_REQUEST_CODE = 1001;
+    public static final int TAKE_VIDEO_REQUEST_CODE = 1002;
+}

+ 3 - 2
app/src/main/java/com/sheep/gamegroup/module/find/activity/ActMediaChoose.java

@@ -34,6 +34,7 @@ import java.util.List;
 
 import butterknife.BindView;
 import cn.finalteam.rxgalleryfinal.api.CameraCallBack;
+import cn.finalteam.rxgalleryfinal.utils.CameraUtil;
 import cn.finalteam.rxgalleryfinal.utils.MediaUtils;
 
 /**
@@ -68,7 +69,7 @@ public class ActMediaChoose extends BaseActivity {
             public void onClick(View view) {
 //                Jump2View.getInstance().goActEditVideo(video);
                 boolean isVideo = mAdapter.getItem(viewPager.getCurrentItem()) instanceof FgtMediaPickerVideo;
-                MediaUtils.openCamera(ActMediaChoose.this, !isVideo);
+                CameraUtil.openCamera(ActMediaChoose.this, !isVideo);
             }
         });
 
@@ -126,7 +127,7 @@ public class ActMediaChoose extends BaseActivity {
                         return;
                 }
             }
-            MediaUtils.onActivityResult(this, requestCode, null, new CameraCallBack() {
+            CameraUtil.onActivityResult(this, requestCode, null, new CameraCallBack() {
                 @Override
                 public void onGetImageSuccess(String cropFilePath) {
                     if (mAdapter.getItem(1) instanceof IRefresh) {

+ 8 - 7
app/src/main/java/com/sheep/gamegroup/module/plugin/util/PluginUtil.java

@@ -15,6 +15,7 @@ import com.sheep.gamegroup.util.Md5Util;
 import com.sheep.gamegroup.util.TestUtil;
 import com.sheep.jiuyan.samllsheep.BuildConfig;
 import com.sheep.jiuyan.samllsheep.SheepApp;
+import com.sheep.jiuyan.samllsheep.utils.ClassFileHelper;
 import com.sheep.jiuyan.samllsheep.utils.G;
 import com.zhy.http.okhttp.OkHttpUtils;
 import com.zhy.http.okhttp.callback.FileCallBack;
@@ -40,17 +41,17 @@ public class PluginUtil {
     public static final String[] ABIS = { "armeabi-v7a", "arm64-v8a", "x86"};
     public static Observable<Plugin> startPlugin(Plugin plugin) {
         return Observable.create((ObservableOnSubscribe<Plugin>) emitter -> {
-            if(TextUtils.equals(getCPU_ABI(), "x86")){
-                emitter.onError(new Throwable("暂不支持该设备"));
-                return;
-            }
+//            if(TextUtils.equals(getCPU_ABI(), "x86") && TestUtil.isSheep()){
+//                emitter.onError(new Throwable("暂不支持该设备"));
+//                return;
+//            }
             if (PluginManager.getInstance(SheepApp.getInstance()).getLoadedPlugin(plugin.getPackageName()) == null) {
 //                String cpuAbi = getCPU_ABI();
 //                String pluginPath = String.format(Locale.CHINA, "%s/media_%s.apk", ClassFileHelper.DIR, cpuAbi);
-////                String pluginPath = ClassFileHelper.DIR + "/app-release.apk";
+                String pluginPath = ClassFileHelper.DIR + "/media_release.apk";
 //                LogUtil.println(PluginUtil.class.getSimpleName(), "CPU_ABI =", cpuAbi, "pluginPath =", pluginPath);
-//                File file = new File(pluginPath);
-                File pluginFile = getFile(plugin);
+                File file = new File(pluginPath);
+                File pluginFile = TestUtil.isTest() && file.exists() ? file : getFile(plugin);
                 if(!pluginFile.exists()){
                     emitter.onError(new Throwable("更新数据中,请稍候"));
                     return;

+ 21 - 1
app/src/main/java/com/sheep/gamegroup/util/TestUtil.java

@@ -27,6 +27,7 @@ import android.widget.TextView;
 
 import com.alibaba.fastjson.JSON;
 import com.bumptech.glide.Glide;
+import com.kfzs.cfyl.share_library.util.CallBackAPI;
 import com.kfzs.duanduan.utils.ApkUtils;
 import com.kfzs.duanduan.view.DialogStorageLow;
 import com.sheep.gamegroup.absBase.AbsObserver;
@@ -40,6 +41,8 @@ import com.sheep.gamegroup.model.entity.LoginUser;
 import com.sheep.gamegroup.model.entity.UserEntity;
 import com.sheep.gamegroup.model.entity.Video;
 import com.sheep.gamegroup.model.util.SheepSubscriber;
+import com.sheep.gamegroup.module.plugin.module.Plugin;
+import com.sheep.gamegroup.module.plugin.util.PluginUtil;
 import com.sheep.gamegroup.usage.AppUsageManager;
 import com.sheep.gamegroup.util.viewHelper.CacheImageUtil;
 import com.sheep.gamegroup.view.activity.ActInstallApkList;
@@ -258,7 +261,7 @@ public class TestUtil {
      */
     public static void test(final Activity activity) {
         final String[] items = {"复制token", "添加token", "复制打点数据", "从jenkins下载小绵羊安装包", "测试表情包",
-                "游戏搜索", "测试bitmap", "剪切视频", "我的关注", "足迹",
+                "游戏搜索", "测试插件","测试bitmap", "剪切视频", "我的关注", "足迹",
                 "测试联通卡", "测试联通卡2", "测试签名1", "测试签名2", "测试孔剑秋faq正式服",
                 "跳转QQ1", "跳转QQ2", "跳转QQ3", "跳转白白QQ", "龙猫竞猜", "龙猫竞猜-scheme",
                 "有米科技", "手机型号测试", "测试通知栏", "测试自定义通知栏", "测试自定义通知栏2",
@@ -277,6 +280,9 @@ public class TestUtil {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         switch (items[which]) {
+                            case "测试插件":
+                                testPlugin(activity);
+                                break;
                             case "测试bitmap":
                                 testBitmap();
                                 break;
@@ -613,6 +619,20 @@ public class TestUtil {
         dialog.show();
     }
 
+    //测试插件
+    private static void testPlugin(Activity activity) {
+        PluginUtil.startPlugin(Plugin.media)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new AbsObserver<Plugin>(){
+                    @Override
+                    public void onNext(Plugin plugin) {
+                        CallBackAPI.get().goAct(activity, "MainActivity");
+                    }
+                });
+
+    }
+
     //根据原始图片生成滤镜图片
     private static void testBitmap() {
         Bitmap bmp = BitmapFactory.decodeResource(SheepApp.getInstance().getResources(), R.drawable.icon_lj);

+ 1 - 1
app/src/main/java/com/sheep/jiuyan/samllsheep/SheepApp.java

@@ -167,8 +167,8 @@ public class SheepApp extends MultiDexApplication {
             initUtils();
             detectFileUriExposure();
             ChannelContent.getInstance().initChannelContent(this);
+            refWatcher = LeakCanary.install(this);
         }
-        refWatcher = LeakCanary.install(this);
     }
 
     /**

+ 3 - 2
media/app/build.gradle

@@ -14,7 +14,7 @@ android {
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 
         ndk {
-            abiFilters "armeabi-v7a"//, 'x86'//, 'armeabi-v7a', 'x86_64', 'arm64-v8a'
+            abiFilters "armeabi-v7a", 'x86'//, 'armeabi-v7a', 'x86_64', 'arm64-v8a'
         }
     }
 
@@ -58,7 +58,8 @@ dependencies {
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'com.android.support.test:runner:1.0.2'
     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
-    implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'
+    //显示图片视频帧,在插件中不兼容x86模拟器,所以不再考虑
+//    implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'
     implementation project(':share_library')
     implementation("com.android.support:recyclerview-v7:$supportLibVersion")
     implementation 'com.android.support.constraint:constraint-layout:1.1.3'

+ 86 - 0
media/app/src/main/AndroidManifest.xml

@@ -1,6 +1,89 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     package="com.kfzs.cfyl.media">
 
+    <!-- Required  一些系统要求的权限,如访问网络等 -->
+    <uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" />
+    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission
+        android:name="android.permission.WRITE_SETTINGS"
+        tools:ignore="ProtectedPermissions" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission
+        android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
+        tools:ignore="ProtectedPermissions" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+
+    <!-- Optional for location -->
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用于开启 debug 版本的应用在6.0 系统上 层叠窗口权限 -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <!-- 极光推送end -->
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
+    <uses-permission android:name="android.permission.REQUEST_MEDIA_PROJECTION" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.GET_TASKS" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission
+        android:name="android.permission.PACKAGE_USAGE_STATS"
+        tools:ignore="ProtectedPermissions" />
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+    <!-- 必须的权限配置 -->
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission
+        android:name="android.permission.READ_LOGS"
+        tools:ignore="ProtectedPermissions" />
+    <!-- 保存资源到SD卡 -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- 推荐的权限 -->
+    <!-- 添加如下权限,以便使用更多的第三方SDK和更精准的统计数据 -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
+    <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
+
+    <!-- 百度定位权限 start -->
+    <!-- 这个权限用于进行网络定位 -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <!-- 这个权限用于访问GPS定位 -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <!-- 用于读取手机当前的状态 -->
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- 访问网络,网络定位需要上网 -->
+    <uses-permission android:name="android.permission.INTERNET" />
+    <!-- SD卡读取权限,用户写入离线定位数据 -->
+    <uses-permission
+        android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
+        tools:ignore="ProtectedPermissions" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.INTERNET" />
     <application
         android:allowBackup="true"
         android:name=".MediaApp"
@@ -19,6 +102,9 @@
                 <action android:name="android.intent.action.VIEW" />
             </intent-filter>
         </activity>
+        <activity android:name=".activity.ActCutVideo1"
+            android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
+            android:screenOrientation="portrait"/>
         <activity android:name=".activity.ActCutVideo"
             android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
             android:screenOrientation="portrait"/>

+ 65 - 0
media/app/src/main/java/com/kfzs/cfyl/media/activity/ActCutVideo1.java

@@ -0,0 +1,65 @@
+package com.kfzs.cfyl.media.activity;
+
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.support.v4.app.Fragment;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.VideoView;
+
+import com.alibaba.fastjson.JSONObject;
+import com.kfzs.cfyl.media.BaseContainerActivity;
+import com.kfzs.cfyl.media.R;
+import com.kfzs.cfyl.media.api.IdChooser;
+import com.kfzs.cfyl.media.customview.VideoFramesView;
+import com.kfzs.cfyl.media.fragment.FgtDiscoveryTopic;
+import com.kfzs.cfyl.media.util.G;
+import com.kfzs.cfyl.media.util.KeyEventUtil;
+import com.kfzs.cfyl.media.util.ListUtil;
+import com.kfzs.cfyl.media.util.VideoUtil;
+import com.kfzs.cfyl.media.util.ViewUtil;
+import com.kfzs.cfyl.share_library.util.LogUtil;
+import com.sheep.gamegroup.model.entity.Video;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import rx.functions.Action1;
+
+/**
+ * Created by realicing on 2018/11/9.
+ * realicing@sina.com
+ * 添加话题并剪切视频
+ */
+public class ActCutVideo1 extends BaseContainerActivity {
+
+
+    @Override
+    protected int getLayoutId() {
+        return R.layout.act_cut_video1;
+    }
+
+
+    private Video data;
+
+    private ArrayList<String> arrayList;//主题列表
+
+
+    @Override
+    protected Fragment initFragment() {
+        return new FgtDiscoveryTopic();
+    }
+    @Override
+    public void initView() {
+        super.initView();
+
+        Intent intent = getIntent();
+        arrayList = intent.getStringArrayListExtra(ArrayList.class.getSimpleName());
+        if (arrayList != null && fragment instanceof FgtDiscoveryTopic)
+            ((FgtDiscoveryTopic) fragment).loadData(arrayList);
+        data = JSONObject.parseObject(intent.getStringExtra(String.class.getSimpleName()), Video.class);
+    }
+}

+ 57 - 0
media/app/src/main/java/com/kfzs/cfyl/media/activity/MainActivity.java

@@ -1,7 +1,22 @@
 package com.kfzs.cfyl.media.activity;
 
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.os.Environment;
+import android.support.v7.app.AlertDialog;
+import android.view.View;
+
 import com.kfzs.cfyl.media.BaseActivity;
 import com.kfzs.cfyl.media.R;
+import com.kfzs.cfyl.media.util.ListUtil;
+import com.kfzs.cfyl.share_library.util.CallBackAPI;
+import com.sheep.gamegroup.model.entity.Video;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.finalteam.rxgalleryfinal.bean.MediaBean;
+import cn.finalteam.rxgalleryfinal.utils.MediaUtils;
 
 /**
  * Created by realicing on 2018/12/6.
@@ -16,6 +31,48 @@ public class MainActivity extends BaseActivity {
 
     @Override
     public void initView() {
+        onClickHelloWorld(null);
+    }
+
+    private void goCut() {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                List<MediaBean> mediaBeanList = MediaUtils.getMediaWithVideoList(getApplicationContext(), 1, 1);
+                MediaBean mediaBean = ListUtil.getItem(mediaBeanList, 0);
+                if(mediaBean != null) {
+                    final Video video = Video.from(mediaBean);
+                    final ArrayList<String> list = new ArrayList<>();
+                    list.add("1asdfaqewfawe");
+                    list.add("2asdfaqewfawe");
+                    list.add("3asdfaqewfawe");
+                    list.add("4asdfaqewfawe");
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            CallBackAPI.get().goCutVideo(MainActivity.this, video, list);
+                        }
+                    });
+                }
+            }
+        }).start();
+    }
+
+    public void onClickHelloWorld(View view) {
+        Activity activity = this;
+        final String[] items = {"剪切视频", "编辑视频"};
+        AlertDialog dialog = new AlertDialog.Builder(activity).setTitle("请选择测试项目")
+                .setItems(items, new DialogInterface.OnClickListener() {
 
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        switch (items[which]) {
+                            case "剪切视频":
+                                goCut();
+                                break;
+                        }
+                    }
+                }).create();
+        dialog.show();
     }
 }

+ 133 - 120
media/app/src/main/java/com/kfzs/cfyl/media/customview/VideoFramesView.java

@@ -7,6 +7,7 @@ import android.graphics.Bitmap;
 import android.media.MediaMetadataRetriever;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -22,7 +23,6 @@ import com.chad.library.adapter.base.BaseViewHolder;
 import com.kfzs.cfyl.media.R;
 import com.kfzs.cfyl.media.bean.VideoFrame;
 import com.kfzs.cfyl.media.glide.VideoFrameTransform;
-import com.kfzs.cfyl.media.util.VideoUtil;
 import com.kfzs.cfyl.share_library.util.LogUtil;
 import com.sheep.gamegroup.model.entity.Video;
 
@@ -181,109 +181,110 @@ public class VideoFramesView extends RelativeLayout {
      * @return
      */
     public VideoFramesView initVideo(Video data) {
-        if (data == null || data.getFilePath() == null) {
+        if (data == null) {
+            LogUtil.println(VideoFramesView.class.getSimpleName(), "showList", "error", "data is null");
+            return this;
+        }
+        if (data.getFilePath() == null) {
             LogUtil.println(VideoFramesView.class.getSimpleName(), "showList", "error", "videoPath is null");
             return this;
         }
         File videoFile = new File(data.getFilePath());
         if (!videoFile.exists()) {
             LogUtil.println(VideoFramesView.class.getSimpleName(), "showList", "error", "videoFile not exists");
-            return this;
         }
         if (!videoFile.canRead()) {
             LogUtil.println(VideoFramesView.class.getSimpleName(), "showList", "error", "videoFile cant read");
-            return this;
         }
         if (data.getDuration() < 1) {
             LogUtil.println(VideoFramesView.class.getSimpleName(), "showList", "error", "duration < 1");
-            return this;
         }
         this.video = data;
         return this;
     }
 
-    private List<Bitmap> bitmapList = new ArrayList<>();
-
-    /**
-     * 显示视频帧图片列表
-     */
-    public VideoFramesView showVideoList1(final Activity activity) {
-        final int size = 10;
-        long duration = video.getDuration();
-        final long per = duration * 1000L / size;
-        int max = 20;
-        int width = max, height = max;
-        if (video.getWidth() > video.getHeight()) {
-            width = max * video.getWidth() / video.getHeight();
-        } else {
-            height = max * video.getHeight() / video.getWidth();
-        }
-        for (int i = 0; i < size; i++) {
-            final int finalWidth = width;
-            final int finalHeight = height;
-            final int finalI = i;
-            new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    Bitmap bitmap = VideoUtil.getVideoFrameBitmap(video, finalI * per, finalWidth, finalHeight);
-                    bitmapList.add(bitmap);
-                    activity.runOnUiThread(new Runnable() {
-                        @Override
-                        public void run() {
-                            if (recyclerView.getAdapter() != null)
-                                recyclerView.getAdapter().notifyDataSetChanged();
-                        }
-                    });
-                }
-            }).start();
-        }
-        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
-        BaseQuickAdapter<Bitmap, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<Bitmap, BaseViewHolder>(R.layout.item_iv_mh, bitmapList) {
-            @Override
-            protected void convert(BaseViewHolder helper, Bitmap item) {
-                ImageView imageView = helper.getView(R.id.item_iv);
-                imageView.setImageBitmap(item);
-            }
-        };
-        recyclerView.setAdapter(baseQuickAdapter);
-
-        return this;
-    }
-
-    /**
-     * 显示视频帧图片列表
-     */
-    public VideoFramesView showVideoList2(final Activity activity) {
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                final int size = 10;
-                final List<Bitmap> bitmapList = VideoUtil.getVideoFrameBitmapList(video, size);
-                activity.runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
-                        BaseQuickAdapter<Bitmap, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<Bitmap, BaseViewHolder>(R.layout.item_iv_mh, bitmapList) {
-                            @Override
-                            protected void convert(BaseViewHolder helper, Bitmap item) {
-                                ImageView imageView = helper.getView(R.id.item_iv);
-                                imageView.setImageBitmap(item);
-                            }
-                        };
-                        recyclerView.setAdapter(baseQuickAdapter);
-                    }
-                });
-
-            }
-        }).start();
-
-        return this;
-    }
-
+//    private List<Bitmap> bitmapList = new ArrayList<>();
+//
+//    /**
+//     * 显示视频帧图片列表
+//     */
+//    public VideoFramesView showVideoList1(final Activity activity) {
+//        final int size = 10;
+//        long duration = video.getDuration();
+//        final long per = duration * 1000L / size;
+//        int max = 20;
+//        int width = max, height = max;
+//        if (video.getWidth() > video.getHeight()) {
+//            width = max * video.getWidth() / video.getHeight();
+//        } else {
+//            height = max * video.getHeight() / video.getWidth();
+//        }
+//        for (int i = 0; i < size; i++) {
+//            final int finalWidth = width;
+//            final int finalHeight = height;
+//            final int finalI = i;
+//            new Thread(new Runnable() {
+//                @Override
+//                public void run() {
+//                    Bitmap bitmap = VideoUtil.getVideoFrameBitmap(video, finalI * per, finalWidth, finalHeight);
+//                    bitmapList.add(bitmap);
+//                    activity.runOnUiThread(new Runnable() {
+//                        @Override
+//                        public void run() {
+//                            if (recyclerView.getAdapter() != null)
+//                                recyclerView.getAdapter().notifyDataSetChanged();
+//                        }
+//                    });
+//                }
+//            }).start();
+//        }
+//        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
+//        BaseQuickAdapter<Bitmap, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<Bitmap, BaseViewHolder>(R.layout.item_iv_mh, bitmapList) {
+//            @Override
+//            protected void convert(BaseViewHolder helper, Bitmap item) {
+//                ImageView imageView = helper.getView(R.id.item_iv);
+//                imageView.setImageBitmap(item);
+//            }
+//        };
+//        recyclerView.setAdapter(baseQuickAdapter);
+//
+//        return this;
+//    }
+//
+//    /**
+//     * 显示视频帧图片列表
+//     */
+//    public VideoFramesView showVideoList2(final Activity activity) {
+//        new Thread(new Runnable() {
+//            @Override
+//            public void run() {
+//                final int size = 10;
+//                final List<Bitmap> bitmapList = VideoUtil.getVideoFrameBitmapList(video, size);
+//                activity.runOnUiThread(new Runnable() {
+//                    @Override
+//                    public void run() {
+//                        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
+//                        BaseQuickAdapter<Bitmap, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<Bitmap, BaseViewHolder>(R.layout.item_iv_mh, bitmapList) {
+//                            @Override
+//                            protected void convert(BaseViewHolder helper, Bitmap item) {
+//                                ImageView imageView = helper.getView(R.id.item_iv);
+//                                imageView.setImageBitmap(item);
+//                            }
+//                        };
+//                        recyclerView.setAdapter(baseQuickAdapter);
+//                    }
+//                });
+//
+//            }
+//        }).start();
+//
+//        return this;
+//    }
+//
     /**
      * 显示视频帧图片列表
      */
-    public VideoFramesView showVideoList3(final Activity activity) {
+    public VideoFramesView showVideoList(final Activity activity) {
         List<VideoFrame> videoFrameList = new ArrayList<>();
         final int size = 10;
         long duration = video.getDuration();
@@ -299,13 +300,13 @@ public class VideoFramesView extends RelativeLayout {
         for (int i = 0; i < size; i++) {
             videoFrameList.add(new VideoFrame().setVideoPath(path).setAtTime(i * per).setWidth(width).setHeight(height));
         }
-        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), 10));
+        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
         BaseQuickAdapter<VideoFrame, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<VideoFrame, BaseViewHolder>(R.layout.item_iv_mh, videoFrameList) {
             @Override
             protected void convert(BaseViewHolder helper, VideoFrame item) {
                 ImageView imageView = helper.getView(R.id.item_iv);
                 Glide.with(activity.getApplicationContext()).load(item.getVideoPath())
-                        .apply(RequestOptions.frameOf(item.getAtTime()).set(VideoBitmapDecoder.FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST).transform(new VideoFrameTransform(item, false)))
+                        .apply(RequestOptions.frameOf(item.getAtTime()).set(VideoBitmapDecoder.FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST).transform(new VideoFrameTransform(item)))
                         .into(imageView);
             }
         };
@@ -313,40 +314,52 @@ public class VideoFramesView extends RelativeLayout {
 
         return this;
     }
-    /**
-     * 显示视频帧图片列表
-     */
-    public VideoFramesView showVideoList(final Activity activity) {
-        List<VideoFrame> videoFrameList = new ArrayList<>();
-        final int size = 10;
-        long duration = video.getDuration();
-        final long per = duration * 1000L / size;
-        int max = 20;
-        int width = max, height = max;
-        if (video.getWidth() > video.getHeight()) {
-            width = max * video.getWidth() / video.getHeight();
-        } else {
-            height = max * video.getHeight() / video.getWidth();
-        }
-        String path = video.getFilePath();
-        for (int i = 0; i < size; i++) {
-            videoFrameList.add(new VideoFrame().setVideoPath(path).setAtTime(i * per)
-                    .setWidth(width).setHeight(height)
-                    .setWidth(video.getWidth()).setHeight(video.getHeight())
-            );
-        }
-        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
-        BaseQuickAdapter<VideoFrame, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<VideoFrame, BaseViewHolder>(R.layout.item_iv_mh, videoFrameList) {
-            @Override
-            protected void convert(BaseViewHolder helper, VideoFrame item) {
-                ImageView imageView = helper.getView(R.id.item_iv);
-                Glide.with(activity.getApplicationContext()).load(R.drawable.qiandao).apply(new RequestOptions().transform(new VideoFrameTransform(item))).into(imageView);
-            }
-        };
-        recyclerView.setAdapter(baseQuickAdapter);
-
-        return this;
-    }
+//    /**
+//     * 显示视频帧图片列表
+//     */
+//    public VideoFramesView showVideoList(final Activity activity) {
+//        if(TextUtils.equals(android.os.Build.CPU_ABI, "x86")) {//x86不兼容,不能在模拟器中连续调用FFmpegMediaMetadataRetriever
+//            return showVideoList1(activity);
+//        } else {
+//            return showVideoList2(activity);
+//        }
+//    }
+//    /**
+//     * 显示视频帧图片列表
+//     */
+//    public VideoFramesView showVideoList2(final Activity activity) {
+//        List<VideoFrame> videoFrameList = new ArrayList<>();
+//        final int size = 10;
+//        long duration = video.getDuration();
+//        final long per = duration * 1000L / size;
+//        int max = 20;
+//        int width = max, height = max;
+//        if (video.getWidth() > video.getHeight()) {
+//            width = max * video.getWidth() / video.getHeight();
+//        } else {
+//            height = max * video.getHeight() / video.getWidth();
+//        }
+//        String path = video.getFilePath();
+//        for (int i = 0; i < size; i++) {
+//            videoFrameList.add(new VideoFrame().setVideoPath(path).setAtTime(i * per)
+//                    .setWidth(width).setHeight(height)
+//                    .setWidth(video.getWidth()).setHeight(video.getHeight())
+//            );
+//        }
+//        recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
+//        BaseQuickAdapter<VideoFrame, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<VideoFrame, BaseViewHolder>(R.layout.item_iv_mh, videoFrameList) {
+//            @Override
+//            protected void convert(BaseViewHolder helper, VideoFrame item) {
+//                ImageView imageView = helper.getView(R.id.item_iv);
+//                Glide.with(activity.getApplicationContext()).load(R.drawable.qiandao)
+//                        .apply(new RequestOptions().transform(new VideoFrameTransform(item)))
+//                        .into(imageView);
+//            }
+//        };
+//        recyclerView.setAdapter(baseQuickAdapter);
+//
+//        return this;
+//    }
 
     private Action1<Float> onTimeChangeListener;
 

+ 9 - 10
media/app/src/main/java/com/kfzs/cfyl/media/glide/VideoFrameTransform.java

@@ -6,7 +6,6 @@ import android.support.annotation.NonNull;
 import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
 import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
 import com.kfzs.cfyl.media.bean.VideoFrame;
-import com.kfzs.cfyl.media.util.VideoUtil;
 
 import java.security.MessageDigest;
 import java.util.Locale;
@@ -18,23 +17,23 @@ import java.util.Locale;
 public class VideoFrameTransform extends BitmapTransformation {
 
     private VideoFrame videoFrame;
-    private boolean isTransform = true;
+//    private boolean isTransform = true;
 
     public VideoFrameTransform(VideoFrame videoFrame) {
         super();
         this.videoFrame = videoFrame;
     }
-    public VideoFrameTransform(VideoFrame videoFrame, boolean isTransform) {
-        super();
-        this.videoFrame = videoFrame;
-        this.isTransform = isTransform;
-    }
+//    public VideoFrameTransform(VideoFrame videoFrame, boolean isTransform) {
+//        super();
+//        this.videoFrame = videoFrame;
+//        this.isTransform = isTransform;
+//    }
 
     @Override
     protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
-        if(isTransform) {
-            return VideoUtil.getVideoFrameBitmap(videoFrame);
-        }
+//        if(isTransform) {
+//            return VideoUtil.getVideoFrameBitmap(videoFrame);
+//        }
         return toTransform;
     }
 

+ 102 - 69
media/app/src/main/java/com/kfzs/cfyl/media/util/VideoUtil.java

@@ -12,11 +12,10 @@ import com.kfzs.cfyl.share_library.util.LogUtil;
 import com.sheep.gamegroup.model.entity.Video;
 
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
 import java.util.Locale;
 
 import rx.functions.Action1;
-import wseemann.media.FFmpegMediaMetadataRetriever;
+//import wseemann.media.FFmpegMediaMetadataRetriever;
 
 /**
  * Created by realicing on 2018/12/6.
@@ -24,73 +23,107 @@ import wseemann.media.FFmpegMediaMetadataRetriever;
  */
 public class VideoUtil {
 
-    public static Bitmap getVideoFrameBitmap(VideoFrame videoFrame) {
-        long time = System.currentTimeMillis();
-        long durationTime = time;
-        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
-        try {
-            mmr.setDataSource(videoFrame.getVideoPath());
-            durationTime = System.currentTimeMillis();
-            return mmr.getScaledFrameAtTime(videoFrame.getAtTime(), FFmpegMediaMetadataRetriever.OPTION_CLOSEST, videoFrame.getWidth(), videoFrame.getHeight());
-        } catch (Exception e) {
-            e.printStackTrace();
-            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
-        } finally {
-            mmr.release();
-            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功");
-        }
-        return null;
-    }
-    public static Bitmap getVideoFrameBitmap(Video video, long atTime, int width, int height) {
-        long time = System.currentTimeMillis();
-        long durationTime = time;
-        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
-        try {
-            mmr.setDataSource(video.getFilePath());
-            durationTime = System.currentTimeMillis();
-            Bitmap bitmap = mmr.getScaledFrameAtTime(atTime, FFmpegMediaMetadataRetriever.OPTION_CLOSEST, width, height);
-            return bitmap;
-        } catch (Exception e) {
-            e.printStackTrace();
-            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
-        } finally {
-            mmr.release();
-            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功");
-        }
-        return null;
-    }
-    public static ArrayList<Bitmap> getVideoFrameBitmapList(Video video, int size) {
-        ArrayList<Bitmap> arrayList = new ArrayList<>();
-        long time = System.currentTimeMillis();
-        long durationTime = time;
-        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
-        long duration = video.getDuration();
-        long per = duration * 1000L / size;
-        int max = 20;
-        int width = max, height = max;
-        if(video.getWidth() > video.getHeight()){
-            width = max * video.getWidth() / video.getHeight();
-        } else {
-            height = max * video.getHeight() / video.getWidth();
-        }
-        try {
-            mmr.setDataSource(video.getFilePath());
-            durationTime = System.currentTimeMillis();
-            for (int i = 0; i < size; i++) {
-                //这里单位为微秒
-                long atTime = i * per;
-                Bitmap bitmap = mmr.getScaledFrameAtTime(atTime, FFmpegMediaMetadataRetriever.OPTION_CLOSEST, width, height);
-                arrayList.add(bitmap);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
-        } finally {
-            mmr.release();
-            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功 "+ arrayList.size());
-        }
-        return arrayList;
-    }
+//    public static Bitmap getVideoFrameBitmap(VideoFrame videoFrame) {
+//        long time = System.currentTimeMillis();
+//        long durationTime = time;
+//        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
+//        try {
+//            mmr.setDataSource(videoFrame.getVideoPath());
+//            durationTime = System.currentTimeMillis();
+//            return mmr.getScaledFrameAtTime(videoFrame.getAtTime(), FFmpegMediaMetadataRetriever.OPTION_CLOSEST, videoFrame.getWidth(), videoFrame.getHeight());
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
+//        } finally {
+//            mmr.release();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功");
+//        }
+//        return null;
+//    }
+//    public synchronized static Bitmap getVideoFrameBitmap2(VideoFrame videoFrame) {
+//        long time = System.currentTimeMillis();
+//        long durationTime = time;
+//        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
+//        try {
+//            mmr.setDataSource(videoFrame.getVideoPath());
+//            durationTime = System.currentTimeMillis();
+//            return mmr.getScaledFrameAtTime(videoFrame.getAtTime(), FFmpegMediaMetadataRetriever.OPTION_CLOSEST, videoFrame.getWidth(), videoFrame.getHeight());
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
+//        } finally {
+//            mmr.release();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功");
+//        }
+//        return null;
+//    }
+//    public static Bitmap getVideoFrameBitmap(VideoFrame videoFrame) {
+//        long time = System.currentTimeMillis();
+//        long durationTime = time;
+//        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
+//        try {
+//            mmr.setDataSource(videoFrame.getVideoPath());
+//            durationTime = System.currentTimeMillis();
+//            return mmr.getScaledFrameAtTime(videoFrame.getAtTime(), FFmpegMediaMetadataRetriever.OPTION_CLOSEST, videoFrame.getWidth(), videoFrame.getHeight());
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
+//        } finally {
+//            mmr.release();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功");
+//        }
+//        return null;
+//    }
+//    public static Bitmap getVideoFrameBitmap(Video video, long atTime, int width, int height) {
+//        long time = System.currentTimeMillis();
+//        long durationTime = time;
+//        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
+//        try {
+//            mmr.setDataSource(video.getFilePath());
+//            durationTime = System.currentTimeMillis();
+//            Bitmap bitmap = mmr.getScaledFrameAtTime(atTime, FFmpegMediaMetadataRetriever.OPTION_CLOSEST, width, height);
+//            return bitmap;
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
+//        } finally {
+//            mmr.release();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功");
+//        }
+//        return null;
+//    }
+//    public static ArrayList<Bitmap> getVideoFrameBitmapList(Video video, int size) {
+//        ArrayList<Bitmap> arrayList = new ArrayList<>();
+//        long time = System.currentTimeMillis();
+//        long durationTime = time;
+//        FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
+//        long duration = video.getDuration();
+//        long per = duration * 1000L / size;
+//        int max = 20;
+//        int width = max, height = max;
+//        if(video.getWidth() > video.getHeight()){
+//            width = max * video.getWidth() / video.getHeight();
+//        } else {
+//            height = max * video.getHeight() / video.getWidth();
+//        }
+//        try {
+//            mmr.setDataSource(video.getFilePath());
+//            durationTime = System.currentTimeMillis();
+//            for (int i = 0; i < size; i++) {
+//                //这里单位为微秒
+//                long atTime = i * per;
+//                Bitmap bitmap = mmr.getScaledFrameAtTime(atTime, FFmpegMediaMetadataRetriever.OPTION_CLOSEST, width, height);
+//                arrayList.add(bitmap);
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t"+ (durationTime - time) + "\t" + e.getMessage());
+//        } finally {
+//            mmr.release();
+//            Log.i("videoUtil", (System.currentTimeMillis() - time) + "\t" + (durationTime - time) + "\t 成功 "+ arrayList.size());
+//        }
+//        return arrayList;
+//    }
 
     public static void tryCutVideo(final String filePath, final long clipPoint, final long clipDuration, final Action1<Object> action1) {
         new Thread(new Runnable() {

+ 109 - 0
media/app/src/main/res/layout/act_cut_video1.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#000000"
+    tools:context=".activity.ActCutVideo">
+
+    <VideoView
+        android:id="@+id/videoView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#99000000" />
+
+    <com.github.ybq.android.spinkit.SpinKitView
+        android:id="@+id/video_loading"
+        style="@style/SpinKitView.Large.ThreeBounce"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:SpinKit_Color="@color/colorAccent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        android:id="@+id/video_back_iv"
+        android:layout_width="?attr/actionBarSize"
+        android:layout_height="?attr/actionBarSize"
+        android:layout_marginTop="20dp"
+        android:onClick="onClickBackImg"
+        android:scaleType="centerInside"
+        android:src="@drawable/narrow_back_white"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/edit_video_topic_tv"
+        android:layout_width="0dp"
+        android:layout_height="30dp"
+        android:background="@drawable/shape_white_20_solid_rectangle_15"
+        android:gravity="center|start"
+        android:maxLength="100"
+        android:onClick="onClickTopic"
+        android:paddingStart="18dp"
+        android:paddingEnd="18dp"
+        android:text="#添加话题#"
+        android:textColor="#FEFFFF"
+        android:textSize="13sp"
+        app:layout_constraintBottom_toBottomOf="@id/video_back_iv"
+        app:layout_constraintEnd_toStartOf="@id/edit_video_sure_tv"
+        app:layout_constraintStart_toEndOf="@id/video_back_iv"
+        app:layout_constraintTop_toTopOf="@id/video_back_iv" />
+
+    <TextView
+        android:id="@+id/edit_video_sure_tv"
+        android:layout_width="75dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="31dp"
+        android:layout_marginEnd="16dp"
+        android:background="@drawable/selector_button_full_main"
+        android:gravity="center"
+        android:onClick="onClickSure"
+        android:paddingTop="6dp"
+        android:paddingBottom="6dp"
+        android:text="下一步"
+        android:textColor="#FEFFFF"
+        android:textSize="15sp"
+        app:layout_constraintBottom_toBottomOf="@id/video_back_iv"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/edit_video_topic_tv"
+        app:layout_constraintTop_toTopOf="@id/video_back_iv" />
+
+    <FrameLayout
+        android:id="@+id/frame_container"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginTop="27dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/edit_video_topic_tv" />
+
+    <com.kfzs.cfyl.media.customview.VideoFramesView
+        android:id="@+id/videoFramesView"
+        android:layout_width="match_parent"
+        android:layout_height="69dp"
+        android:layout_marginStart="36dp"
+        android:layout_marginEnd="36dp"
+        android:layout_marginBottom="17dp"
+        app:layout_constraintBottom_toBottomOf="parent" />
+
+    <TextView
+        android:id="@+id/edit_video_time_tv"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="15dp"
+        android:layout_marginBottom="100dp"
+        android:text="@string/has_choose_x_second"
+        android:textColor="#ffffffff"
+        android:textSize="12sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+</android.support.constraint.ConstraintLayout>

+ 8 - 2
media/app/src/main/res/layout/main_activity.xml

@@ -2,10 +2,16 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical">
+    xmlns:tools="http://schemas.android.com/tools"
+    android:orientation="vertical"
+    tools:context=".activity.MainActivity">
 
     <TextView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="第一个页面" />
+        android:layout_marginTop="100dp"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:onClick="onClickHelloWorld"
+        android:text="HelloWorld" />
 </LinearLayout>

app/src/main/java/cn/finalteam/rxgalleryfinal/utils/FilenameUtils.java → media/share_library/src/main/java/cn/finalteam/rxgalleryfinal/utils/FilenameUtils.java


+ 18 - 77
app/src/main/java/cn/finalteam/rxgalleryfinal/utils/MediaUtils.java

@@ -1,38 +1,23 @@
 package cn.finalteam.rxgalleryfinal.utils;
 
-import android.app.Activity;
 import android.content.ContentResolver;
-import android.content.ContentValues;
 import android.content.Context;
-import android.content.Intent;
 import android.database.Cursor;
 import android.graphics.BitmapFactory;
+import android.media.ExifInterface;
 import android.media.MediaMetadataRetriever;
 import android.net.Uri;
 import android.os.Build;
 import android.provider.MediaStore;
-import android.support.annotation.Nullable;
-import android.support.media.ExifInterface;
 import android.text.TextUtils;
-import android.util.Log;
-import android.widget.Toast;
 
-import com.sheep.gamegroup.util.LogUtil;
-import com.sheep.jiuyan.samllsheep.SheepApp;
-import com.sheep.jiuyan.samllsheep.utils.ClassFileHelper;
-import com.sheep.jiuyan.samllsheep.utils.FileUtil;
-import com.sheep.jiuyan.samllsheep.utils.G;
-import com.yalantis.ucrop.UCrop;
+import com.kfzs.cfyl.share_library.util.LogUtil;
 
 import java.io.File;
 import java.io.IOException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
-import java.util.Locale;
 
-import cn.finalteam.rxgalleryfinal.api.CameraCallBack;
 import cn.finalteam.rxgalleryfinal.bean.BucketBean;
 import cn.finalteam.rxgalleryfinal.bean.MediaBean;
 
@@ -90,7 +75,7 @@ public class MediaUtils {
                     //检查并重新设置宽高
                     if (item != null && item.getOriginalPath() != null) {
                         if (item.getHeight() <= 0 || item.getWidth() <= 0) {
-                            BitmapFactory.Options options = FileUtil.getImageOptions(item.getOriginalPath());
+                            BitmapFactory.Options options = getImageOptions(item.getOriginalPath());
                             item.setWidth(options.outWidth);
                             item.setHeight(options.outHeight);
                         }
@@ -156,7 +141,7 @@ public class MediaUtils {
                             try {
 
                             MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
-                            metadataRetriever.setDataSource(SheepApp.getInstance(), Uri.parse(item.getOriginalPath()));
+                            metadataRetriever.setDataSource(context, Uri.parse(item.getOriginalPath()));
                             String width = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); // 视频宽度
                             String height = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); // 视频高度
 //                            String rotation = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); // 视频旋转方向
@@ -260,7 +245,6 @@ public class MediaUtils {
      * <p>
      * 判断图片 Size ,如果小于等于0则返回 Null,避免出现 No such file or directory
      */
-    @Nullable
     private static MediaBean parseImageCursorAndCreateThumImage(Context context, Cursor cursor) {
         long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.SIZE));
         String originalPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
@@ -479,62 +463,19 @@ public class MediaUtils {
         return bucketBeenList;
     }
 
-    public static String openCamera(Activity activity, boolean isImage) {
-        Intent captureIntent = isImage ? new Intent(MediaStore.ACTION_IMAGE_CAPTURE) : new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
-        if (captureIntent.resolveActivity(activity.getPackageManager()) == null) {
-            G.shortToast("相机不可用");
-            return null;
-        }
-
-        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
-        String filename = String.format(isImage ? IMAGE_STORE_FILE_NAME : VIDEO_STORE_FILE_NAME, dateFormat.format(new Date()));
-        File fileImagePath = new File(ClassFileHelper.DIR, filename);
-        String mImagePath = fileImagePath.getAbsolutePath();
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
-            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileImagePath));
-        } else {
-            ContentValues contentValues = new ContentValues(1);
-            contentValues.put(MediaStore.Images.Media.DATA, mImagePath);
-            Uri uri = SheepApp.getInstance().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
-            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
-        }
-        if (!isImage) {
-            captureIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 15000L);
-        }
-        // video : 1: 高质量  0 低质量
-        //        captureIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
-        activity.startActivityForResult(captureIntent, isImage ? TAKE_IMAGE_REQUEST_CODE : TAKE_VIDEO_REQUEST_CODE);
-        return mImagePath;
-    }
-
-    public static void onActivityResult(Activity activity, int requestCode, String path, CameraCallBack cameraCallBack) {
-        Log.i(MediaUtils.class.getSimpleName(), "onActivityResult: requestCode=" + requestCode);
-        switch (requestCode) {
-            case TAKE_IMAGE_REQUEST_CODE:
-                if (path == null) {
-                    Log.i(MediaUtils.class.getSimpleName(), "拍照成功");
-                    cameraCallBack.onGetImageSuccess(null);
-                    break;
-                }
-                String cropFilePath = path.substring(0, path.lastIndexOf(".")) + "temp.png";
-                Log.i(MediaUtils.class.getSimpleName(), "拍照成功: " + cropFilePath);
-                cameraCallBack.onGetImageSuccess(cropFilePath);
-                UCrop.of(Uri.parse(path), Uri.parse(cropFilePath))
-                        .start(activity);
-                break;
-            case TAKE_VIDEO_REQUEST_CODE:
-                Log.i(MediaUtils.class.getSimpleName(), "摄像成功");
-                cameraCallBack.onGetVideoSuccess();
-                break;
-            case UCrop.REQUEST_CROP:
-                Log.i(MediaUtils.class.getSimpleName(), "裁剪成功");
-                cameraCallBack.onCropImageSuccess();
-                break;
-        }
+    /**
+     * 获取图片配置信息
+     * @param filePath
+     * @return
+     */
+    public static BitmapFactory.Options getImageOptions(String filePath) {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        /**
+         * 最关键在此,把options.inJustDecodeBounds = true;
+         * 这里再decodeFile(),返回的bitmap为空,但此时调用options.outHeight时,已经包含了图片的高了
+         */
+        options.inJustDecodeBounds = true;
+        BitmapFactory.decodeFile(filePath, options); // 此时返回的bitmap为null
+        return options;
     }
-
-    public static final String IMAGE_STORE_FILE_NAME = "IMG_%s.jpg";
-    public static final String VIDEO_STORE_FILE_NAME = "IMG_%s.mp4";
-    public static final int TAKE_IMAGE_REQUEST_CODE = 1001;
-    public static final int TAKE_VIDEO_REQUEST_CODE = 1002;
 }

+ 2 - 2
app/src/main/java/cn/finalteam/rxgalleryfinal/utils/StorageUtils.java

@@ -32,7 +32,7 @@ public final class StorageUtils {
      * @param context Application context
      * @return Cache {@link File directory}.<br />
      * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
-     * {@link android.content.Context#getCacheDir() Context.getCacheDir()} returns null).
+     * {@link Context#getCacheDir() Context.getCacheDir()} returns null).
      */
     public static File getCacheDirectory(Context context) {
         return getCacheDirectory(context, true);
@@ -47,7 +47,7 @@ public final class StorageUtils {
      * @param preferExternal Whether prefer external location for cache
      * @return Cache {@link File directory}.<br />
      * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
-     * {@link android.content.Context#getCacheDir() Context.getCacheDir()} returns null).
+     * {@link Context#getCacheDir() Context.getCacheDir()} returns null).
      */
     public static File getCacheDirectory(Context context, boolean preferExternal) {
         File appCacheDir = null;

+ 6 - 0
media/share_library/src/main/java/com/kfzs/cfyl/share_library/util/CallBackAPI.java

@@ -43,4 +43,10 @@ public class CallBackAPI {
         intent.putExtra(Video.class.getSimpleName(), data);
         activity.startActivityForResult(intent, Constant.MEDIA_ACTION_EDIT_VIDEO);
     }
+    //编辑视频
+    public void goAct(Activity activity, String act) {
+        Intent intent = new Intent();
+        intent.setClassName("com.kfzs.cfyl.media", "com.kfzs.cfyl.media.activity."+act);
+        activity.startActivityForResult(intent, Constant.MEDIA_ACTION_EDIT_VIDEO);
+    }
 }