android高仿微信视频编辑页-视频多张图片提取

上一篇中介绍了有关视频提取图片的知识点,如果对这个不太了解 建议看下android提取视频多张图片和视频信息之前这篇.
这里实现的是仿微信的视频编辑页面,主要是播放视频和显示该视频的一系列图片,可以滑动图片的列表,视频也跟着动(seekto),然后可以拖动滑块实现视频的seekto。最后会进行视频的剪切操作,就是剪切2个滑块之前的区域,视频重复播放2个滑块之间的区域。
先看下效果图:

源码

https://github.com/ta893115871/VideoEdit

实现思路

实现是:上面是videoview(你也可以用一些开源的视频播放器),底部是recycleview(显示视频的提取图片)+自定义view rankbar (用于制定需要截取的视频)。

一.高效率提取视频图片

android提取视频多张图片和视频信息这篇文章中用

Bitmap bitmap = metadataRetriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);

返回的是bitmap图片然后保存到sd中然后用glide进行展示,因为这里展示的图片是小图且没有必要很清晰,所以需要对bitmap进行处理然后再保存再展示,以达到快速提取的目标:

    /*** 设置固定的宽度,高度随之变化,使图片不会变形** @param bm Bitmap* @return Bitmap*/private Bitmap scaleImage(Bitmap bm) {if (bm == null) {return null;}int width = bm.getWidth();int height = bm.getHeight();float scaleWidth = extractW * 1.0f / width;
//        float scaleHeight =extractH*1.0f / height;Matrix matrix = new Matrix();matrix.postScale(scaleWidth, scaleWidth);Bitmap newBm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,true);if (!bm.isRecycled()) {bm.recycle();bm = null;}return newBm;}

二.recycleview滑动展示的视频提取的图片

这里demo中的展示视频缩率图的整个的宽是固定的,所以以宽为准的高度随之变化,大家可以根据具体的需要做相应的处理。
因为视频的时长不固定,而且一般的短视频考虑到服务器以及成本,所以视频一般不会太长,比如微信:最长可以支持上传10s的视频 (我的需求是最长支持60s的视频),通过观察微信如下规则:

  1. 视频时长<=10s的就展示固定的10张图片,则提取图片的时间平均长度:视频时长/10=interval
  2. 视频时长>10s的展示更多的图片,则提取的图片的时间平均长度:10s/10=interval,不一定是这个算法哈,这里只是从技术的角度预定一个规则哈。
  3. 一旦视频时长>10s,视频的缩率图是可以滑动的,而且可以根据左边的滑块视频自动的seekto展示那一秒的视频。
    这里的demo会按60s来算,也就是将123步骤中的10s改为60s的规则。
    所以我们要根据视频的时长来计算提取视频图片的个数和整个展示这些图片的宽,计算如下:
    long startPosition = 0;long endPosition = duration;int thumbnailsCount;int rangeWidth;boolean isOver_60_s;//MAX_CUT_DURATION为60 秒//MAX_COUNT_RANGE为10张if (endPosition <= MAX_CUT_DURATION) {isOver_60_s = false;thumbnailsCount = MAX_COUNT_RANGE;rangeWidth = mMaxWidth;} else {isOver_60_s = true;thumbnailsCount = (int) (endPosition * 1.0f / (MAX_CUT_DURATION * 1.0f) * MAX_COUNT_RANGE);rangeWidth = mMaxWidth / MAX_COUNT_RANGE * thumbnailsCount;}mRecyclerView.addItemDecoration(new EditSpacingItemDecoration(UIUtil.dip2px(this, 35), thumbnailsCount));

超过60s的视频提取的图片个数为是:视频时长/60s * 10张。整个展示这些图片的宽也就是recycleview的宽rangeWidth为:mMaxWidth( 屏幕或者减去设计师的宽)/10张*视频提取的图片个数。
既然可以滑动底部的recycleview的视频缩率图,根据滑动的位置来计算视频应该展示seenkto哪一秒,所以我们需要知道滑动的距离以及每毫秒所占的px(像素)averageMsPx,所以:

averageMsPx = duration(时长) * 1.0f(乘以1.0为了精确) / rangeWidth (recycleview的宽,不是可见区域) * 1.0f;

然后就可以利用recycleview的OnScrollListener方法进行监听处理,具体的代码可以下载去看,这里只是梳理下思路。

三.videoview的使用

这个没啥好说的了,就是android为了方便开发者的使用而封装的控件。
我的需求是使用的ijk播放器(地址:https://github.com/Bilibili/ijkplayer),这里就用的videoview不过都一样。获取播放的进度可以用handler实现来保证视频一直在所选中的范围内重复播放。

    private Handler handler = new Handler();private Runnable run = new Runnable() {@Overridepublic void run() {videoProgressUpdate();handler.postDelayed(run, 1000);}};private void videoProgressUpdate() {long currentPosition = mVideoView.getCurrentPosition();Log.d(TAG, "----onProgressUpdate-cp---->>>>>>>" + currentPosition);if (currentPosition >= (rightProgress)) {mVideoView.seekTo((int) leftProgress);positionIcon.clearAnimation();if (animator != null && animator.isRunning()) {animator.cancel();}anim();}}

四.videoview的坑和视频进度指针

就是中间那个黄色的渐变矩形,就是一个imageview通过动画不断的设置它的leftMargin即可。动画就是使用ValueAnimator来生成一系列的数字,然后监听回调即可。有人会说为什么不根据进度进行设置呢?我尝试过用视频的进度进行处理,当时用的ijk播放器,好多都是异步回调的,比如seekto方法,这个就很难控制了,导致进度不准确,而且进度顿顿的感觉。后来采用了动画就很好了,反正本地视频一般不会卡吧。这个可以去看下代码。

这个demo中我改为videoview后发现以下问题:
我测试了下:有时候seekto方法你调用完了,立马去获取进度可能为0。所以指针的位置不对了。
WTF?!why?因为

  1. 视频seekto方法
    VideoView的seekTo是异步执行的,会有seek未完成但播放已经开始的现象。
    所以我们应该在seekComplete回调当中处理,但是呢?VideoView是基于MediaPlayer实现的,但没提供setOnSeekCompleteListener方法。我们可以设置videoview的OnPrepared监听才拿到MediaPlayer,对MediaPlayer进行设置。
    mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {//设置MediaPlayer的OnSeekComplete监听mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {@Overridepublic void onSeekComplete(MediaPlayer mp) {Log.d(TAG, "------ok----real---start-----" );if (!isSeeking) {videoStart();}}});}});
  1. 锁屏/home键 指针位置不正确,改为从左边开始重新播放就行了。

当前这些问题在demo中都已经修复,具体可以看下代码

五.自定义两侧拖动控件-RankBar

这个算是除了视频提取图片外的比较重要的部分了。目标呢就是这个控件可以回调出来一个方法,可以知道按下去,滑动中,抬起来等状态,可以知道左右的2个视频时间,可以知道拖动的是哪个,这个回调看起来这样。

  private final RangeSeekBar.OnRangeSeekBarChangeListener mOnRangeSeekBarChangeListener = new RangeSeekBar.OnRangeSeekBarChangeListener() {@Overridepublic void onRangeSeekBarValuesChanged(RangeSeekBar bar, long minValue, long maxValue, int action, boolean isMin, RangeSeekBar.Thumb pressedThumb) {Log.d(TAG, "-----minValue----->>>>>>" + minValue);Log.d(TAG, "-----maxValue----->>>>>>" + maxValue);leftProgress = minValue + scrollPos;rightProgress = maxValue + scrollPos;Log.d(TAG, "-----leftProgress----->>>>>>" + leftProgress);Log.d(TAG, "-----rightProgress----->>>>>>" + rightProgress);switch (action) {case MotionEvent.ACTION_DOWN:Log.d(TAG, "-----ACTION_DOWN---->>>>>>");videoPause();break;case MotionEvent.ACTION_MOVE:Log.d(TAG, "-----ACTION_MOVE---->>>>>>");mVideoView.seekTo((int) (pressedThumb == RangeSeekBar.Thumb.MIN ?leftProgress : rightProgress));break;case MotionEvent.ACTION_UP:Log.d(TAG, "-----ACTION_UP--leftProgress--->>>>>>" + leftProgress);//从minValue开始播mVideoView.seekTo((int) leftProgress);videoStart();break;default:break;}}};

自定义view不是这篇的重点,但是只要搞清楚自定义的一些方法和步骤就可以搞定一些简单的控件。
下面是extend view的一些步骤:

  1. 分析控件的基本可变可扩展可暴漏的属性:attr文件
  2. 重写构造方法获取属性值,处理默认值
  3. 重写onMeasure方法,设置宽高,处理wrap_content(给定默认值)
  4. 重新onDraw方法 ,比如:绘制图片,文件,bitmap的缩放等
  5. 处理事件,如果是extend view 则一般只需要处理onTouchEvent,进行事件的消费,一般返回true,因为要消费啊,可以你需要处理多指触摸的情况,滑动的临界值等等。事件的走向。
  6. 善后处理,比如onSaveInstanceState,onRestoreInstanceState的处理
  7. 回调接口的书写

最后,如果有什么问题,大家可以探讨一下哈。知识是开放的,大家一起学习。

android高仿微信视频编辑页-视频多张图片提取相关推荐

  1. android+高仿视频录制,android高仿微信视频编辑页

    android高仿微信视频编辑页-视频多张图片提取 上一篇中介绍了有关视频提取图片的知识点,如果对这个不太了解 建议看下android提取视频多张图片和视频信息之前这篇. 这里实现的是仿微信的视频编辑 ...

  2. android+高仿视频录制,Android高仿微信拍照控件,实战推荐!

    原标题:Android高仿微信拍照控件,实战推荐! 作者:陈嘉桐 转自:ttps://github.com/CJT2325 控件介绍 不知道是不是在微信更新到6.0版本之后,微信将它的拍照和录制视频的 ...

  3. android仿微信聊天功能,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  4. android 微信高仿,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  5. php支付密码控件,Android高仿微信支付密码输入控件实例代码

    这篇文章主要为大家详细介绍了Android高仿微信支付密码输入控件的具体实现代码,供大家参考,具体内容如下 像微信支付密码控件,在app中是一个多么司空见惯的功能.最近,项目需要这个功能,于是乎就实现 ...

  6. android com.mylhyl,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. photopicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

  7. android高仿微信聊天页面,Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)

    目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图: 仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高 ...

  8. android仿微信充值布局,Android 高仿微信支付数字键盘功能

    现在很多app的支付.输入密码功能,都已经开始使用自定义数字键盘,不仅更加方便.其效果着实精致. 下面带着大家学习下,如何高仿微信的数字键盘,可以拿来直接用在自身的项目中. 先看下效果图: 1. 自定 ...

  9. android 微信高仿,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. PhotoPicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

最新文章

  1. 消息队列面试经典十连问
  2. [ADO.NET] 如何 使用 OLE DB 讀寫 Excel / 建立 Excel 檔案 (一)
  3. 看一家公司发展得如何就看这家公司的财务部门
  4. webstorm如何自动换行_怎样在word中自动生成目录
  5. JavaScript如何获取/计算页面元素的offset?
  6. WPF 修改(优化)Menu菜单的样式
  7. matlab lti全响应,《LTI系统的响应——实验报告》.doc
  8. ROS学习笔记02:ROS架构与基础
  9. 用摸鱼学来解释隐马尔可夫模型(HMM)
  10. EditText属性详解
  11. 《金牌网管师——助理级网吧网管》目录
  12. c#中计算三角形面积公式_高中数学|向量公式之用平面向量求三角形面积
  13. 电视机计算机英语,电视电脑的优缺点英语作文
  14. 计算公式(java实现)
  15. 使用OBS双电脑直播(主副电脑)推流至哔哩哔哩
  16. 系统集成项目管理工程师需要考论文吗?
  17. 在chrome上调试安卓手机页面及部分异常解决
  18. 如何使用会声会影制作手机竖屏效果
  19. linux添加xfs磁盘,centos7 LV XFS添加磁盘
  20. Mac从零搭建开发环境

热门文章

  1. LayuI固定块关闭
  2. Parcelbale接口
  3. oracle kill所有plsql developer进程
  4. JVM性能优化, Part 5:Java的伸缩性
  5. 거든---表示条件,后接祈使,劝诱,意志语句
  6. 图像处理------简单脸谱检测算法
  7. 网络测试利器netperf安装和使用
  8. Sniff网络基础原理和软件实现技巧详解
  9. ETL数据导入/导出工具 HData
  10. AngularJS 开发辅助工具