Android播放视频快进帧预览图完美解決方案
播放视频快进预览图完美解決方案,使用方法如下,使用FFmpeg,不影响原有播放器,
就是先截取缩略图保存下来,快进时选用图片显示,最优方案,播放性能最好,体验完美。
参考github:
https://github.com/wseemann/FFmpegMediaMetadataRetriever
下载jar
解压之后拷贝如下两个aar到项目libs目录下
使用方法:
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(mUri);
mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
Bitmap b = mmr.getFrameAtTime(2000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST); // frame at 2 seconds
byte [] artwork = mmr.getEmbeddedPicture();
mmr.release();
代码:
package com.tianci.player.preview;import android.graphics.Bitmap;
import android.net.Uri;
import android.widget.ImageView;
import com.tianci.localmedia.util.SkyLocalContext;
import com.tianci.utils.MediaLogUtils;
import com.tianci.utils.Utils;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;import wseemann.media.FFmpegMediaMetadataRetriever;public class PreviewImageUtils {private static FFmpegMediaMetadataRetriever ffmmr = null;private static final String savePath = SkyLocalContext.getContext().getCacheDir().getPath() + "/preview/";private String filePath = null;private String fileName = null;private boolean isStop = false;private int mDuration = 0;private String outDir = null;private static PreviewImageUtils mInstance;public static PreviewImageUtils getInstance(){if (null == mInstance){synchronized (PreviewImageUtils.class){if (null==mInstance){mInstance = new PreviewImageUtils();}}}return mInstance;}public PreviewImageUtils(){}private void getDuration(String url){try{if (ffmmr!=null){ffmmr.release();ffmmr = null;}ffmmr =new FFmpegMediaMetadataRetriever();ffmmr.setDataSource(url);String durationStr = ffmmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);mDuration = Integer.parseInt(durationStr)/1000;ffmmr.release();ffmmr = null;}catch (Exception e){e.printStackTrace();}}public void startDecode(String oldUrl, String url){Bitmap bitmap = null;filePath = url;isStop = false;getDuration(url);MediaLogUtils.d("startDecode-----------------url:"+url);File file = new File(url);if (file!=null&&file.exists()){fileName = file.getName();}else {return;}deleteBitmap(oldUrl);try {getFrameAtTime(url, mDuration, 50);getFrameAtTime(url, mDuration, 30);getFrameAtTime(url, mDuration, 20);getFrameAtTime(url, mDuration, 10);getFrameAtTime(url, mDuration, 5);getFrameAtTime(url, mDuration, 3);MediaLogUtils.d("startDecode------end-----------mDuration:"+mDuration);}catch (Exception e){e.printStackTrace();ffmmr = null;}}private void getFrameAtTime(String url, int duration, int step){Bitmap bitmap = null;try {if (ffmmr!=null){ffmmr.release();ffmmr = null;}ffmmr =new FFmpegMediaMetadataRetriever();ffmmr.setDataSource(url);for (int i=0; i< duration; i+=step){int pos = i*1000*1000;if (hasFile(i, fileName)){continue;}if (ffmmr!=null){bitmap = ffmmr.getScaledFrameAtTime(pos, 160, 90);if (bitmap!=null)saveBitmap(bitmap, i, fileName);}Thread.sleep(10);if (isStop){break;}}ffmmr.release();ffmmr = null;}catch (Exception e){e.printStackTrace();}}private void deleteFile(String path) {MediaLogUtils.d("deleteFile-----------------path:"+path);File file=new File(path);if (file!=null&&!file.exists()){MediaLogUtils.d("空目录");return;}try{File[] files=file.listFiles();if (files == null){MediaLogUtils.d("空目录");return;}for(int i =0;i<files.length;i++){files[i].delete();}}catch (Exception e){e.printStackTrace();}}public void setStop(Boolean stop){isStop = stop;}private void deleteBitmap(String path){try {File file = new File(path);if (file.exists()){String deleteDir = savePath + file.getName();deleteFile(deleteDir);}}catch (Exception e){e.printStackTrace();}}private synchronized void saveBitmap(Bitmap bitmap , int position, String name) {outDir = savePath+name;try {File dirFile = new File(outDir);if (!dirFile.exists()) { //如果不存在,那就建立这个文件夹dirFile.mkdirs();dirFile.setWritable(true);dirFile.setReadable(true);Runtime.getRuntime().exec("chmod 777 -R " + dirFile.getAbsolutePath());}File file = new File(outDir, position+".jpg");FileOutputStream fos = new FileOutputStream(file);bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);if (file.exists()){file.setWritable(true);file.setReadable(true);Runtime.getRuntime().exec("chmod 777 -R " + file.getAbsolutePath());}fos.flush();fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public static synchronized void setPreview(ImageView imageView, String url, int position){MediaLogUtils.d("setPreview()--------------url:"+url);MediaLogUtils.d("setPreview()--------------position:"+position);String previewPath = null;String name = null;File file = new File(url);if (file.exists()){name = file.getName();}previewPath = savePath+name+"/"+position+".jpg";File showPicFile = new File(previewPath);if (showPicFile!=null&&showPicFile.exists()){Uri uri = Uri.parse(previewPath);imageView.setImageURI(uri);}}private boolean hasFile(int position, String name){try {String filePath = savePath+name+"/"+position+".jpg";File file = new File(filePath);if (file!=null&&file.exists()){return true;}}catch (Exception e){e.printStackTrace();}return false;}
}
在播放器起播的时候使用
PreviewImageUtils.getInstance().setStop(true);
PreviewImageUtils.getInstance().startDecode(null, url);
效果图:
Android播放视频快进帧预览图完美解決方案相关推荐
- Android TV 快进帧预览
前言 入职新公司,刚接手的AndroidTV项目,初次接触TV开发,被各种骚东西搞得头皮发麻,写点东西记录一下. 正文 MediaMetadataRetriever 1. 获取视频帧的关键类:Medi ...
- 【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 摄像头预览数据回调接口 )
文章目录 安卓直播推流专栏博客总结 一. Android 端数据采集涉及到的相关概念 二. Camera 预览图像尺寸设置 三. 获取摄像头采集的数据格式 安卓直播推流专栏博客总结 Android R ...
- Android 10.0获取本地视频及其预览图
打开本地视频选择器 private void openLocalVideo(){Intent intent = new Intent();intent.setAction(Intent.ACTION_ ...
- python 循环播放音乐_python gstreamer实现视频快进/快退/循环播放功能
这篇文章主要介绍了python gstreamer 实现视频快进/快退/循环播放功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 Gstreamer到底是个啥? ...
- HTML5-video标签-实现点击预览图播放或暂停视频
HTML5-video标签-实现点击预览图播放或暂停视频 刚刚参加工作,开始更多的接触到一些新的知识,促使我开始了解html5和css3的新特性.这时我才真的发现到html5和css3的强大. 之前关 ...
- Silverlight 5 beta新特性探索系列:9.视频快进快退和TextSearch对象对文字项查询
本节讲诉两个新特性:一.在Silverlight 5中可以控制MediaElement对象播放的视频进行快进快退控制.二.在Silverlight 5中的文字项进行搜索查询. 一.对于MediaEle ...
- JavaScript+HTML设置视频预览图
第一种: 设置video属性poster <video class="videoContent" controls poster="img/poster.png&q ...
- Android Camera2 教程 · 第三章 · 预览
Android Camera2 教程 · 第三章 · 预览 DarylGo关注 Android Camera 上一章<Camera2 开启相机>我们学习了如何开启和关闭相机,接下来我们来学 ...
- SkeyeVSS综合安防监控Onvif、RTSP、GB28181视频云无插件直播点播解决方案之监控视频实时多屏预览
SkeyeVSS综合安防监控Onvif.RTSP.GB28181视频云无插件直播点播解决方案之监控视频实时多屏预览 SkeyeVSS支持一分屏.四分屏.九分屏.16分屏.25分屏.36分屏等几种N*N ...
最新文章
- 视觉在无人驾驶中的应用及分类_机器视觉可以应用于水果自动分类拣选,你见过吗?...
- python中的encode()和decode()函数
- 推荐给程序猿们好用的谷歌插件
- 连接mysql语言_杂谈各个语言连接数据库如何实现的-第一讲
- LALR(1)语法分析生成器--xbytes
- ios8 定位问题解决思路
- Spyder打开报错解决办法
- Python学习总结之四 -- 这就是Python的字典
- servlet的应用------request对象和bean实体的反射关系
- CentOS添加并挂载新硬盘
- c语言分治法求众数重数_分治法求众数 - osc_twlari2q的个人空间 - OSCHINA - 中文开源技术交流社区...
- java getSource()和 getActionCommand()区别
- 不同调制方式性能优劣指标
- 马哥linux架构班笔记,51CTO博客-专业IT技术博客创作平台-技术成就梦想
- C#使用itextsharp生成PDF文件含页脚页眉
- html flash 背景,使FLASH背景变透明的方法介绍
- Flink从入门到真香(12、Flink一大利器-时间窗口)
- 【vue.js】+云存储(实现图片上传功能)
- 最全前端资源---快过来 最新鲜的资源这里都有
- Quartz 定时任务相关介绍表