
最近项目中用到了好多视频播放的地方,还是是交谈发送的集锦消息,但是类似内涵段子的集锦页面,就会涉及其他常识,但是网上的常识都很零星,一会找缓存方式,一会找预览图片的方式,一会找视频动态修改尺寸的方式,所以找的人好烦,但是自己写一篇来记录各种知识点,也方便他人查阅
获取视频首帧当预览图(MediaMetadataRetriever)
在VideoView中,所以直接设置播放路径,然后seekTo(1)其实也能形成预览效果,所以,所以VideoView较多,增设播放路径的方式会造成几个问题android videoview,增设路径后VideoView会取网上拉取视频(缓冲池大小),这种产生流量浪费,但是,多个VideoView会导致显示首帧非常特别慢,且有严重的卡顿
那怎么解决这个难题,我的看法是,还是用首帧当预览图,但是我是在ImageView里面显示预览图,但是预览的时候不用VideoView了,获取预览图作为变的简单化,省流量,还方便,下来我们了解下MediaMetadataRetriever类如何获取视频的首帧。MediaMetadataRetriever类不但可以获取视频首帧,还可以获取文章,时长,图文等资料,你们按照需要可以获取,我在这里就不一一举例,在获取到首帧后,我们做下缓存处理,以便下一次预览不用每次从网上拉取,然后用Glide加载显示
ThreadPoolUtils.execute(new Runnable() {
@Override
public void run() {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
Bitmap bitmap = null;
try {
//这里要用FileProvider获取的Uri
if (url.contains("http")) {
retriever.setDataSource(url, new HashMap<String, String>());
} else {
retriever.setDataSource(url);
}
bitmap = retriever.getFrameAtTime();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
retriever.release();
} catch (RuntimeException ex) {
ex.printStackTrace();
}
}
showImageMessage(bitmap, positionTag, vv);
}
});
自序:当然还有一种办法来做预览显示,就是让后台将预览图处理好,然后拿到图片地址直接用Glide显示,都不用自己缓存,但是后台可以生成GIF,也可以用Glide显示,且变得高大上
预览图加载完毕后,点击预览图,然后我们可以做这些处理,如隐藏ImageView且显示VideoView,如果跳到视频播映按钮等,这些加载逻辑大家可以发挥自己得想象
VideoView加载一个网络视频
VideoView加载视频其实很简单,我们直接看源码吧
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<VideoView
android:id="@+id/mVideoView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
/**
* 香港卫视:
* CCTV1高清:

* CCTV3高清:
* CCTV5高清:
* CCTV5+高清:
* CCTV6高清:
* 苹果提供的检测源(点播):
*/
private void initView() {
String url="http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8";
VideoView videoView=findViewById(R.id.mVideoView);
videoView.setVideoPath(url);
videoView.requestFocus();
videoView.start();
}
如此一个网络视频就可以播放了
视频控件长宽的形状调整
视频是播放出来了,什么看都有点不和谐,大白边框太丑了,那缩小吧,一不小心缩变形了,看起来更怪异,什么才能根据视频的比重来表明呢?我们下面不是讲过MediaMetadataRetriever吗?我们可以按照获取的首帧图片的形状确定视频的形状,MediaMetadataRetriever还可以采用
int videoWidth=retriever.METADATA_KEY_VIDEO_WIDTH;
int videoHeight=retriever.METADATA_KEY_VIDEO_HEIGHT;
来确认视频的形状。从而动态设置VideoView的形状,咦,增设那么大的控件,什么才表明那么小的集锦?哈哈,难题来了,小视频什么动态适配控件大小?
小视频适配大控件(动态调整视频显示的形状)
不说方法了,我应该百度的,普通的LayoutParams只能调整控件的形状,当视频比控件小时,集锦没法表明大默认大小,但是这么来调整呢?请看源码↓
自定义VideoView控件CustomVideoView.java
/**
* @author Created by MrRight on 2017/10/24.
*/
public class CustomVideoView extends VideoView{
private Context mContext;
final int defaultHeight=200; //单位DP
public CustomVideoView(Context context) {
super(context);
mContext=context;
}
public CustomVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext=context;
}
public CustomVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext=context;
}
//widthMeasureSpec 和 heightMeasureSpec的值 由父容器决定
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super .onMeasure(widthMeasureSpec,heightMeasureSpec);
// 默认高度,为了自动获取到focus
int width = MeasureSpec.getSize(widthMeasureSpec);

int height = width;
// 这个之前是默认的深蹲图像
if (this.width > && this.height > ) {
width = this.width;
height = this.height;
}
setMeasuredDimension(width, height);
}
private int width,height;
public void setMeasure(int width, int height) {
this.width = width;
this.height = height;
}
}
如何用呢!!很简单,继续看源码↓
videoViewParent.post(new Runnable() {
@Override
public void run() {
int[] widthAndHeight=getWidthAndHeight(holder.videoViewParent,dynamicsBean.getWeight(),dynamicsBean.getHeight());
videoView.getHolder().setFixedSize(widthAndHeight[], widthAndHeight[1]);
// 重绘VideoView大小,这个办法是在重写VideoView时对外抛出方法
videoView.setMeasure(widthAndHeight[], widthAndHeight[1]);
// 请求调整
videoView.requestLayout();
}
});
就这样,集锦可以按你的需求行进动态调整了!!
VideoView有很多,真的是很多,许多是重复的,至于什么重复的?为什么重复?有兴趣的自己去瞧瞧!首先看第一个非常重要的一个:点击事件和双击事件的,他们有没有试过设置OnClick事件?是不是没有什么用啊?没用就对了,点击事件的正确动作是↓↓↓
/*
* 对VideoView setOnClickListener时,发现无效,搜索一番后寻找解决方案;
* 同时VideoView的点击双击和滑动事件,通过对VideoView的OnTouchListener设置进行,
* 首先实例化一个手势识别器,并前往它的onTouchEvent。
* 然后初始化GestureDetector ,这上面有一个坑,所以纯粹的设置OnGestureListenerandroid videoview,发现当onDown的返回值为true的
* 时候可以响应单击长摁和滑动事件,为false的时候只会响应长摁事件;如果想要双击事件,就要对GestureDetector设
* 置OnDoubleTapListener,需要提醒的的是,在OnGestureListener的onDown返回值为false的时候OnDoubleTapListener
* 里面所有的下跌是不会去响应的
*/
holder.videoView.setOnTouchListener(new View.OnTouchListener() {
GestureDetector mGesture;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mGesture == null) {
mGesture = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {

//回到false的话没法响应长摁事件
return true;
}
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
}
@Override
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-118551-1.html
到现在潮水般的旅日
不说别的也不说倒贴只是真心单纯希望四只越来越好嗯就这样越来越美
然后苏联海军菜打出我舰奉命撞击你舰的警告之后才撞击的