【Android 获取本地视频+视频剪裁+视频录制】

【android】 同时被 2 个专栏收录
43 篇文章 1 订阅
5 篇文章 0 订阅

效果图如下:

在这里插入图片描述

获取本地视频

关键代码:

 /**
     * 重要说明:
     * <p>
     * 疑问一:
     * 该方法,查到的 视频路径 和 视频的缩略图 是一样的,并且格式都是 .mp4 。视频的缩略图应该是 .jpg或.png的后缀啊,
     * 为什么会这样呢?抱歉,本人查了不少资料,还不知道具体原因。如果您知道原因,欢迎留言,评论。
     * <p>
     * <p>
     * 疑问二:
     * 除此之外,还有一个问题就是:明明手机的本地是有很多视频,但是有的机型就是查不到。
     * <p>
     * 亲测:小米2s,本地是很多视频的,但是获取不到,要么只查到几个,
     * 而 小米8,魅族note8,就可以查到本地所有的视频。
     * <p>
     * 我又下载了 抖音和快手 app,他们也是存在同样的情况:
     * 小米2s中,该方法从本地查到了2个视频,他们也是只查到了2个视频,其实本地是不止2个视频的。
     * <p>
     * 至于为什么有的机型,查不到本地所有的视频呢? 抱歉,同样也是不清楚具体原因。如果您知道原因,欢迎留言,评论。
     */
    private List<LocalVideoBean> getLocalAllVideo() {

        List<LocalVideoBean> sysVideoList = new ArrayList<>();
        // MediaStore.Video.Thumbnails.DATA:视频缩略图的文件路径
       /* String[] thumbColumns = {MediaStore.Video.Thumbnails.DATA,
                MediaStore.Video.Thumbnails.VIDEO_ID};*/

        // 视频其他信息的查询条件
        String[] mediaColumns = {MediaStore.Video.Media._ID,
                MediaStore.Video.Media.DATA, MediaStore.Video.Media.DURATION, MediaStore.Video.Media.SIZE, MediaStore.Video.Thumbnails.DATA};

        Cursor cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                mediaColumns, null, null, MediaStore.Video.VideoColumns.DATE_ADDED + " DESC");

        if (cursor == null) {
            return sysVideoList;
        }
        if (cursor.moveToFirst()) {
            do {
                LocalVideoBean info = new LocalVideoBean();

                info.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)));
                info.setDuration(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)));
                info.setSize(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)));
                info.setThumbPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Thumbnails.DATA)));

                sysVideoList.add(info);
            } while (cursor.moveToNext());

        }
        cursor.close();

        return sysVideoList;


    }

LocalVideoAdapter.java

public class LocalVideoAdapter extends BaseQuickAdapter<LocalVideoBean, BaseViewHolder> {


    public LocalVideoAdapter(@Nullable List<LocalVideoBean> data) {
        super(R.layout.item_local_video, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, LocalVideoBean item) {

        TextView tvTip = helper.getView(R.id.video_tip);

        ImageView imageView = helper.getView(R.id.image_view);

        RequestOptions options = new RequestOptions();
        options.error(R.drawable.default_image)
                .placeholder(R.drawable.default_image)
                .override(130, 130);


        //说明:虽然获取的视频缩略图的路径,但是真实返回的还是一个视频的路径
        //因此,这里的file其实是一个视频文件
        File file = new File(item.getThumbPath());

        //glid虽然加载的为视频file,但是只会把视频的第一帧的图片加载显示出来
        //如果这里不想用glide,去显示图片,也可以通过media.getFrameAtTime()方法,获取视频的第一帧,
        // 参考文章地址:https://blog.csdn.net/bzlj2912009596/article/details/80446256
        Glide.with(mContext)
                .load(Uri.fromFile(file))//这个方法在华为手机上,没问题。

                //经过测试发现,在华为手机上,这个方法的加载,直接把手机卡死了,小米8未出现同样问题,
                //初步判断是太耗内存,上面的方法就没问题。
                //.load(new File(item.getThumbPath()))

                .apply(options)
                .into(imageView);


        //bitmap 太大,加载卡顿,不理想
        //Bitmap videoThumbBit = VideoThumbUtils.getVideoThumb(item.getThumbPath());
        //Bitmap videoThumbBit = VideoThumbUtils.getVideoThumbnail(item.getThumbPath(), 100, 100);
       /* Glide.with(mContext)
                .load(videoThumbBit)
                .apply(options)
                .into(imageView);*/


        helper.setText(R.id.video_duration, TimeUtils.convertSecondsToTime(item.getDuration() / 1000));

        if (item.getDuration() / 1000 > 15) {
            tvTip.setVisibility(View.VISIBLE);
        } else {
            tvTip.setVisibility(View.GONE);
        }

    }


}

LocalVideoBean.java

public class LocalVideoBean {
    private String path;
    private long duration;
    private long size;
    private String thumbPath;
    private Bitmap bitmap;

    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public long getDuration() {
        return duration;
    }

    public void setDuration(long duration) {
        this.duration = duration;
    }

    public String getThumbPath() {
        return thumbPath;
    }

    public void setThumbPath(String thumbPath) {
        this.thumbPath = thumbPath;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }
}

视频剪裁

关键代码:

 //得到视频路径,new 出视频file,我们就可以对视频进行剪裁处理了(文字,滤镜...)
    //这里推荐一个开源框架,Android-Video-Trimmer: https://github.com/iknow4/Android-Video-Trimmer 还不错。
    // 缺点是:使用ffmpeg进行视频裁剪。会让你的app增大许多,20-30M
    private void videoCrop(String videoPath) {

        if (!TextUtils.isEmpty(videoPath)) {
            Bundle bundle = new Bundle();
            bundle.putString(VIDEO_PATH_KEY, videoPath);

            Intent intent = new Intent(MainActivity.this, VideoTrimmerActivity.class);
            intent.putExtras(bundle);
            startActivityForResult(intent, VIDEO_TRIM_REQUEST_CODE);
        }


    }

结果处理关键代码:

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        Log.i(TAG, "onActivityResult: requestCode=" + requestCode + " resultCode=" + resultCode);

        if (resultCode == RESULT_OK && requestCode == 66) {
            if (data != null) {
                LocalVideoBean localVideoBean = getVideoPath(data);

                tvPath.setText("视频路径:\n" + localVideoBean.getPath() + "\n\n" + " 视频缩略图路径:\n" + localVideoBean.getThumbPath());
                videoCrop(localVideoBean.getPath());


            } else {
                Toast.makeText(this, "data is null", Toast.LENGTH_SHORT).show();
            }


        } else if (requestCode == VIDEO_REQUESTCODE && resultCode == 11) {

            String video_path = data.getStringExtra("video_path");
            String poster_path = data.getStringExtra("poster_path");


            tvPath.setText("视频路径:\n" + video_path + "\n\n" + " 视频缩略图路径:\n" + poster_path);
            videoCrop(video_path);

        } else if (requestCode == VIDEO_REQUESTCODE && resultCode == 22) {//拍摄的视频路径,可以返回到这里

        } else if (requestCode == VideoTrimmerActivity.VIDEO_TRIM_REQUEST_CODE && resultCode == RESULT_OK) {
            if (data != null) {
                String clippingPath = data.getStringExtra("clippingPath");
                tv_clipping_path.setText("剪裁结果路径:\n" + clippingPath);
            }


        }


    }

视频拍摄

VideoRecorder

WeiXinRecordedDemo

CameraView :https://github.com/CJT2325/CameraView
说明:截止2019-02-25 start 1.7k 最新更新于2年前

CameraView :https://github.com/natario1/CameraView
说明:截止2019-02-25 start 1.7k 最新更新于几天前

cameraview: https://github.com/google/cameraview
说明:截止2019-02-25 start 4.2k 最新更新于2年前


项目源码

ps:项目源码中,都已经做了很详细的说明。

  • 0
    点赞
  • 14
    评论
  • 12
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值