播放视频快进预览图完美解決方案,使用方法如下,使用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播放视频快进帧预览图完美解決方案相关推荐

  1. Android TV 快进帧预览

    前言 入职新公司,刚接手的AndroidTV项目,初次接触TV开发,被各种骚东西搞得头皮发麻,写点东西记录一下. 正文 MediaMetadataRetriever 1. 获取视频帧的关键类:Medi ...

  2. 【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 摄像头预览数据回调接口 )

    文章目录 安卓直播推流专栏博客总结 一. Android 端数据采集涉及到的相关概念 二. Camera 预览图像尺寸设置 三. 获取摄像头采集的数据格式 安卓直播推流专栏博客总结 Android R ...

  3. Android 10.0获取本地视频及其预览图

    打开本地视频选择器 private void openLocalVideo(){Intent intent = new Intent();intent.setAction(Intent.ACTION_ ...

  4. python 循环播放音乐_python gstreamer实现视频快进/快退/循环播放功能

    这篇文章主要介绍了python gstreamer 实现视频快进/快退/循环播放功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 Gstreamer到底是个啥? ...

  5. HTML5-video标签-实现点击预览图播放或暂停视频

    HTML5-video标签-实现点击预览图播放或暂停视频 刚刚参加工作,开始更多的接触到一些新的知识,促使我开始了解html5和css3的新特性.这时我才真的发现到html5和css3的强大. 之前关 ...

  6. Silverlight 5 beta新特性探索系列:9.视频快进快退和TextSearch对象对文字项查询

    本节讲诉两个新特性:一.在Silverlight 5中可以控制MediaElement对象播放的视频进行快进快退控制.二.在Silverlight 5中的文字项进行搜索查询. 一.对于MediaEle ...

  7. JavaScript+HTML设置视频预览图

    第一种: 设置video属性poster <video class="videoContent" controls poster="img/poster.png&q ...

  8. Android Camera2 教程 · 第三章 · 预览

    Android Camera2 教程 · 第三章 · 预览 DarylGo关注 Android Camera 上一章<Camera2 开启相机>我们学习了如何开启和关闭相机,接下来我们来学 ...

  9. SkeyeVSS综合安防监控Onvif、RTSP、GB28181视频云无插件直播点播解决方案之监控视频实时多屏预览

    SkeyeVSS综合安防监控Onvif.RTSP.GB28181视频云无插件直播点播解决方案之监控视频实时多屏预览 SkeyeVSS支持一分屏.四分屏.九分屏.16分屏.25分屏.36分屏等几种N*N ...

最新文章

  1. 视觉在无人驾驶中的应用及分类_机器视觉可以应用于水果自动分类拣选,你见过吗?...
  2. python中的encode()和decode()函数
  3. 推荐给程序猿们好用的谷歌插件
  4. 连接mysql语言_杂谈各个语言连接数据库如何实现的-第一讲
  5. LALR(1)语法分析生成器--xbytes
  6. ios8 定位问题解决思路
  7. Spyder打开报错解决办法
  8. Python学习总结之四 -- 这就是Python的字典
  9. servlet的应用------request对象和bean实体的反射关系
  10. CentOS添加并挂载新硬盘
  11. c语言分治法求众数重数_分治法求众数 - osc_twlari2q的个人空间 - OSCHINA - 中文开源技术交流社区...
  12. java getSource()和 getActionCommand()区别
  13. 不同调制方式性能优劣指标
  14. 马哥linux架构班笔记,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  15. C#使用itextsharp生成PDF文件含页脚页眉
  16. html flash 背景,使FLASH背景变透明的方法介绍
  17. Flink从入门到真香(12、Flink一大利器-时间窗口)
  18. 【vue.js】+云存储(实现图片上传功能)
  19. 最全前端资源---快过来 最新鲜的资源这里都有
  20. Quartz 定时任务相关介绍表

热门文章

  1. 分享关于饿了么的需求文档
  2. Centos查看端口占用
  3. Python爬虫之XPath基础教程:用代码抓取网页数据
  4. 模拟退火算法 python实现旅行家问题
  5. 【认识硬件】之 锁紧座
  6. 要想步入程序开发行列,就不得不知道的事情汇总
  7. vue中如何返回历史路由_如何配置局域网中的多台无线路由器【图文教程】
  8. 铜陵新松工业机器人项目_首期投资约12亿元 新松机器人(苏州)未来科技城项目在苏州相城开工奠基...
  9. 删除临时文件夹中的特定名称模式目录
  10. Xtrabackup全量备份(官网)