欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > Android >内容正文

Android

Android TV 快进帧预览

发布时间:2025/6/17 Android 40 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Android TV 快进帧预览 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

前言

入职新公司,刚接手的AndroidTV项目,初次接触TV开发,被各种骚东西搞得头皮发麻,写点东西记录一下。

正文

MediaMetadataRetriever

1. 获取视频帧的关键类:MediaMetadataRetriever

(1) 属于在android api的那个包下:android.media.MediaMetadataRetriever

(2) 类简单介绍: MediaMetadataRetriever类提供了用于从输入媒体文件检索帧和元数据的统一接口。

(3) 这个是android提供的类,用来获取本地和网络media相关文件的信息。

2. 大概使用

public void getThumbs(SipaTvPlayer player, String url) {long duration = player.getDuration();int divisor = 0;if (duration > 1000 * 60 * 2) {//如果视频时长超过两分钟divisor = 10;} else {divisor = 2;}int finalDivisor = divisor;io.reactivex.Observable<Bitmap> observable = io.reactivex.Observable.create(new ObservableOnSubscribe<Bitmap>() {@Overridepublic void subscribe(ObservableEmitter<Bitmap> e) throws Exception {mRetriever = new MediaMetadataRetriever();if (Build.VERSION.SDK_INT >= 14) {mRetriever.setDataSource(url, new HashMap<String, String>());} else {mRetriever.setDataSource(url);}for (int i = 1 * 1000; i < duration; i += finalDivisor * 1000) {//获取每隔divisor秒的视频帧预览图Bitmap bitmap = mRetriever.getFrameAtTime(i * 1000, MediaMetadataRetriever.OPTION_CLOSEST);e.onNext(bitmap);Log.i(TAG, "bitmap---i: " + i / 1000);}}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());observable.subscribe(new Consumer<Bitmap>() {@Overridepublic void accept(Bitmap bitmap) throws Exception {if (bitmap != null) {mThumbs.add(bitmap);mAdapter.notifyDataSetChanged();}}});} 复制代码

注意: 使用MediaMetadataRetriever在移动端能获取到本地或网络视频的对应微秒值的帧截图,但过程相当耗时,很有可能会ANR,所以一般异步方式获取,因为过于耗时(能力有限,不知道能不能解决这个问题),所以不建议用于TV开发中的快进帧预览功能,可用于视频列表获取关键帧预览等对实时性要求不高的使用场景。

后台截取返回组图

  • 经过尝试,MediaMetadataRetriever获取帧耗时emmm...真的慢,然后观察鹅厂还有Yk等主流TV的快进帧预览效果那叫一个流畅,后面通过抓包发现YK的请求返回的数据里面包含一张10*10的小图组成的大图,对比视频帧预览图发现跟小图一直,然后猜想其实现方式就是后台返回帧预览组图,然后TV端将大图截成100张小图,也就是帧预览图然后列表展示。真相大白,大鹅厂还是吊,各种加密,能力有限看不出来,估计也差不多。
  • 2. 明白了过程那剩下的就是后台返回组图(那边怎么搞不管),TV端获取图片,截成小图,列表展示。

    (1) 将网络图片转Bitmap(网上随便找的)

    public class BitmapUtils {/*** 得到本地或者网络上的bitmap url - 网络或者本地图片的绝对路径,比如:* <p>* A.网络路径: url=&quot;http://blog.foreverlove.us/girl2.png&quot; ;* <p>* B.本地路径:url=&quot;file://mnt/sdcard/photo/image.png&quot;;* <p>* C.支持的图片格式 ,png, jpg,bmp,gif等等** @param url* @return*/public static Bitmap GetLocalOrNetBitmap(String url) {Bitmap bitmap = null;InputStream in = null;BufferedOutputStream out = null;try {// 说明:Constant.IO_BUFFER_SIZE 是一个常量而已,可以改成常数,比如2*1024,其实取决于你的图片大小,自己根据图片的大小自己设定吧。。。。in = new BufferedInputStream(new URL(url).openStream(), Constant.IO_BUFFER_SIZE);final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();out = new BufferedOutputStream(dataStream, Constant.IO_BUFFER_SIZE);copy(in, out);out.flush();byte[] data = dataStream.toByteArray();bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);data = null;return bitmap;} catch (IOException e) {e.printStackTrace();return null;}}} 复制代码

    (2)截取小图

    /**** @param bitmap 源图(要截取的帧预览组图)* @return 截取的图片列表*/private List<Bitmap> getThumbBitmaps(Bitmap bitmap) {//MAX_COLUMNS 列数 MAX_LINES 行数 一般10*10 跟后台定好int width = bitmap.getWidth() / MAX_COLUMNS;int height = bitmap.getHeight() / MAX_LINES;ArrayList<Bitmap> bitmaps = new ArrayList<>();for (int y = 0; y < MAX_LINES; y++) {for (int x = 0; x < MAX_COLUMNS; x++) {bitmaps.add(Bitmap.createBitmap(bitmap, x * width, y * height, width, height));}}return bitmaps;} 复制代码

    好了,关于AndroidTV帧预览,就发现这么点东西,水平有限,代码不好就凑合看吧。

    总结

    以上是生活随笔为你收集整理的Android TV 快进帧预览的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。