博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android MediaPlayer SeekTo 在 8.0 版本上优化说明
阅读量:5105 次
发布时间:2019-06-13

本文共 4785 字,大约阅读时间需要 15 分钟。

android使用 mediaPlayer 播放video视频过程中, 当用户退出当前播放,再从后台恢复播放时,需要跳转到之前退出的时间点继续播放。使用的方法基本都是 SeekTo 之前的时间点,但是经常遇到恢复播放时位置不准的问题,而且甚至有重头开始播放的现象。这个是因为SeekTo是回到上一时间点附近的关键帧导致的。

针对这个问题,在最新的android 8.0平台上,已经有了新的解决方案:

SeekTo() 方法在android O 平台新增了一个多参数的方法:

void seekTo(long msec, @SeekMode int mode)

这里的Mode 传入

int SEEK_CLOSEST = 0x03

就不会出现播放视频位置不准确的现象了。

/**     * Seek modes used in method seekTo(long, int) to move media position     * to a specified location.     *     * Do not change these mode values without updating their counterparts     * in include/media/IMediaSource.h!     */    /**     * This mode is used with {
@link #seekTo(long, int)} to move media position to * a sync (or key) frame associated with a data source that is located * right before or at the given time. * * @see #seekTo(long, int) */ public static final int SEEK_PREVIOUS_SYNC = 0x00; /** * This mode is used with {
@link #seekTo(long, int)} to move media position to * a sync (or key) frame associated with a data source that is located * right after or at the given time. * * @see #seekTo(long, int) */ public static final int SEEK_NEXT_SYNC = 0x01; /** * This mode is used with {
@link #seekTo(long, int)} to move media position to * a sync (or key) frame associated with a data source that is located * closest to (in time) or at the given time. * * @see #seekTo(long, int) */ public static final int SEEK_CLOSEST_SYNC = 0x02; /** * This mode is used with {
@link #seekTo(long, int)} to move media position to * a frame (not necessarily a key frame) associated with a data source that * is located closest to or at the given time. * * @see #seekTo(long, int) */ public static final int SEEK_CLOSEST = 0x03; /** @hide */ @IntDef( value = { SEEK_PREVIOUS_SYNC, SEEK_NEXT_SYNC, SEEK_CLOSEST_SYNC, SEEK_CLOSEST, }) @Retention(RetentionPolicy.SOURCE) public @interface SeekMode {} private native final void _seekTo(long msec, int mode); /** * Moves the media to specified time position by considering the given mode. *

* When seekTo is finished, the user will be notified via OnSeekComplete supplied by the user. * There is at most one active seekTo processed at any time. If there is a to-be-completed * seekTo, new seekTo requests will be queued in such a way that only the last request * is kept. When current seekTo is completed, the queued request will be processed if * that request is different from just-finished seekTo operation, i.e., the requested * position or mode is different. * * @param msec the offset in milliseconds from the start to seek to. * When seeking to the given time position, there is no guarantee that the data source * has a frame located at the position. When this happens, a frame nearby will be rendered. * If msec is negative, time position zero will be used. * If msec is larger than duration, duration will be used. * @param mode the mode indicating where exactly to seek to. * Use {

@link #SEEK_PREVIOUS_SYNC} if one wants to seek to a sync frame * that has a timestamp earlier than or the same as msec. Use * {
@link #SEEK_NEXT_SYNC} if one wants to seek to a sync frame * that has a timestamp later than or the same as msec. Use * {
@link #SEEK_CLOSEST_SYNC} if one wants to seek to a sync frame * that has a timestamp closest to or the same as msec. Use * {
@link #SEEK_CLOSEST} if one wants to seek to a frame that may * or may not be a sync frame but is closest to or the same as msec. * {
@link #SEEK_CLOSEST} often has larger performance overhead compared * to the other options if there is no sync frame located at msec. * @throws IllegalStateException if the internal player engine has not been * initialized * @throws IllegalArgumentException if the mode is invalid. */ public void seekTo(long msec, @SeekMode int mode) { if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) { final String msg = "Illegal seek mode: " + mode; throw new IllegalArgumentException(msg); } // TODO: pass long to native, instead of truncating here. if (msec > Integer.MAX_VALUE) { Log.w(TAG, "seekTo offset " + msec + " is too large, cap to " + Integer.MAX_VALUE); msec = Integer.MAX_VALUE; } else if (msec < Integer.MIN_VALUE) { Log.w(TAG, "seekTo offset " + msec + " is too small, cap to " + Integer.MIN_VALUE); msec = Integer.MIN_VALUE; } _seekTo(msec, mode); }

转载于:https://www.cnblogs.com/renhui/p/9584966.html

你可能感兴趣的文章
IO流
查看>>
mybatis调用存储过程,获取返回的游标
查看>>
Android Handler学习笔记
查看>>
设计模式之装饰模式(结构型)
查看>>
面向对象的设计原则
查看>>
解释性语言和编译性语言的区别
查看>>
Swift3.0服务端开发(三) Mustache页面模板与日志记录
查看>>
Java读取.properties配置文件的几种方法
查看>>
【转】 FPGA设计的四种常用思想与技巧
查看>>
移动端页面头部定义
查看>>
职责链模式(Chain of Responsibility)
查看>>
C++:同名隐藏和赋值兼容规则
查看>>
EntityFrameWork 实现实体类和DBContext分离在不同类库
查看>>
Microsoft .NET 远程处理:技术概述(代理模式)
查看>>
新手算法学习之路----二叉树(在一个二叉查找树中插入一个节点)
查看>>
autopep8
查看>>
GIT在Linux上的安装和使用简介
查看>>
java 类型转型
查看>>
基于C#编程语言的Mysql常用操作
查看>>
【转】Java反射 之 反射基础
查看>>