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>() {
            @Override
            public 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>() {
            @Override
            public void accept(Bitmap bitmap) throws Exception {
                if (bitmap != null) {
                    mThumbs.add(bitmap);
                    mAdapter.notifyDataSetChanged();
                }
            }
        });
    }
复制代码

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

后台截取返回组图

  1. 经过尝试,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帧预览,就发现这么点东西,水平有限,代码不好就凑合看吧。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值