Android 仿淘宝京东商品详情视频+图片与图片第一帧获取
程序员文章站
2022-05-31 14:04:40
...
近日项目有个新需求就是把原本的商品详情只有图片展示,改为视频+图片方式展示.
此博客只提供记录,与思路具体根据自己需求实现.首先想到的是Google搜索下别人的实现方式来参考实现发现不怎么适合项目需求,用饺子视频实现视频播放功能后发现视频的封面饺子视频是采用图片来做视频封面的.在适配器里面根据视频格式来判断是视频还是图片,或者根据后台字段来判断,这个根据后台返回数据来处理.
参考案例 视频图片
@Override
public Object instantiateItem(ViewGroup container, final int position) {
String url = imgUrls.get(position % imgUrls.size());
if (!url.contains(".mp4")) {
ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
// imageView.setScaleType(ImageView.ScaleType.FIT_XY);
Glide.with(context).load(url).into(imageView);
container.addView(imageView);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// bannerListener.bannerClick(position % imgUrls.size());
}
});
return imageView;
} else {
// final VideoView videoView = new VideoView(mContext);
// Uri uri = Uri.parse(url);
// videoView.setVideoURI(uri);
// videoView.start();
JZVideoPlayerStandard jzVideoPlayerStandard = new JZVideoPlayerStandard(context);
jzVideoPlayerStandard.setUp(url, JZVideoPlayerStandard.SCREEN_WINDOW_NORMAL, "播放测试");
// Glide.with(this).load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png").into(myJZVideoPlayerStandard.thumbImageView);
Glide.with(context).load(imgUrls.get(1)).into(jzVideoPlayerStandard.thumbImageView);
JZVideoPlayer.setJzUserAction(null);
container.addView(jzVideoPlayerStandard);
// videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
bannerListener.playEnd();
// }
// });
return jzVideoPlayerStandard;
}
}
public void setBannerListener(BannerListener bannerListener) {
this.bannerListener = bannerListener;
}
此时就差一个视频封面,一开始采用了自带的来获取Bitmap方式再用Glide来展示,
public static Bitmap getBitmapFormUrl(String url) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
if (Build.VERSION.SDK_INT >= 14) {
retriever.setDataSource(url, new HashMap<String, String>());
} else {
retriever.setDataSource(url);
}
/*getFrameAtTime()--->在setDataSource()之后调用此方法。 如果可能,该方法在任何时间位置找到代表性的帧,
并将其作为位图返回。这对于生成输入数据源的缩略图很有用。**/
bitmap = retriever.getFrameAtTime();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} finally {
try {
retriever.release();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
return bitmap;
}
发现是可以实现基本功能,但是进去详情的时候总是感觉卡了一下才加载完成,后面发现采用自带的获取视频首帧占用内存特别大,容易OOM,
public static void loadVideoScreenshot(final Context context, String uri, ImageView imageView, long frameTimeMicros) {
RequestOptions requestOptions = RequestOptions.frameOf(frameTimeMicros);
requestOptions.set(FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST);
requestOptions.transform(new BitmapTransformation() {
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return toTransform;
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
try {
messageDigest.update((context.getPackageName() + "RotateTransform").getBytes("utf-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
});
Glide.with(context).load(uri).apply(requestOptions).into(imageView);
}
最后实现的方式是以,饺子视频+Glide加载视频首帧的方式实现.核心部分代码
//核心代码
JZVideoPlayerStandard jzVideoPlayerStandard=new JZVideoPlayerStandard(context);
String url = imagePath[position % imagePath.length];
LogUtils.e("m_tag_123", "返回图片地址为:" + url);
if (!url.contains(".mp4")) { //图片
RequestBuilder<Drawable> thumbnail = ImageCacheUtils.getDrawableRequest(context, productId);
if (thumbnail != null && position == 0 && requestOptions != null) {
Glide.with(context).load(imagePath[position % imagePath.length] + ImageMaxUtils.ProductDetail_vpPic).apply(requestOptions).into(iv);
} else {
Glide.with(context).load(imagePath[position % imagePath.length] + ImageMaxUtils.ProductDetail_vpPic)
.thumbnail(Glide.with(context).load(imagePath[position % imagePath.length] + ImageMaxUtils.thumbnail_Request)).into(iv);
}
try {
if (ivList.size() <= (position % imagePath.length)) {
ivList.add(iv);
}
} catch (Exception e) {
e.printStackTrace();
}
container.addView(view);
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.productBannarOnItemOnclick(position % imagePath.length);
}
}
});
return view;
} else { //视频
jzVideoPlayerStandard = new JZVideoPlayerStandard(context);
jzVideoPlayerStandard.setUp(url, JZVideoPlayerStandard.SCREEN_WINDOW_NORMAL, "");
// Glide.with(context).load("http://p.qpic.cn/videoyun/0/2449_43b6f696980311e59ed467f22794e792_1/640").into(jzVideoPlayerStandard.thumbImageView); //网络图片设置
// Drawable drawable = new BitmapDrawable(context.getResources(), Img_video);
// Glide.with(context).load(drawable).into(jzVideoPlayerStandard.thumbImageView); //使用本地截取视频预览图
loadVideoScreenshot(context, url, 1); //使用Glide截取视频预览图
JZVideoPlayer.setJzUserAction(null);
container.addView(jzVideoPlayerStandard);
return jzVideoPlayerStandard;
}
/**
* 使用Glide
* @param context
* @param uri
* @param frameTimeMicros
*/
@SuppressLint("CheckResult")
public static void loadVideoScreenshot(final Context context, String uri, long frameTimeMicros) {
RequestOptions requestOptions = RequestOptions.frameOf(frameTimeMicros);
requestOptions.set(FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST);
requestOptions.transform(new BitmapTransformation() {
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return toTransform;
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
try {
messageDigest.update((context.getPackageName() + "RotateTransform").getBytes("utf-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
});
Glide.with(context).load(uri).apply(requestOptions).into(jzVideoPlayerStandard.thumbImageView);
}
最终实际效果:
上一篇: 提蹲抖踢蜷走 六字养生健身法
下一篇: 15分钟减肥瑜伽动作 快速高效燃烧脂肪