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.
* <p>
* 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);
}

Android MediaPlayer SeekTo 在 8.0 版本上优化说明的更多相关文章

  1. Thinkphp 3.0版本上传文件加图片缩略图实例解析

    先看html加个表单,注意这里的action 路径要选 对. <div> <form action="__URL__/add_img" enctype=" ...

  2. android GET 请求在5.0版本的取不到数据,报IO异常兼容问题解决

    使用lib类库xUtils-2.6.10.jar作为数据请求的框架,在android的5.0版会有兼容问题,取不到GET请求的数据. 但是POST没有问题,难取到数据. public static R ...

  3. PHP1.0版本上传OSS报错,仿照2.0版本传入的居然是句柄

    代码如下:          $oss_sdk_service = new ALIOSS();              $oss_sdk_service->set_debug_mode(FAL ...

  4. Android Studio 1.1.0版本以上 优化编译

    本文不写内容,只是借用别人链接.不过大概内容都如下链接: http://blog.csdn.net/hyr83960944/article/details/38388429 http://bbs.it ...

  5. js磁力线代码(非压缩,自己在压缩的版本上优化了代码,易于阅读)

    拿去白嫖吧: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=" ...

  6. Android MediaPlayer和VideoView的使用

          MediaPlayer MediaPlayer类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码和播放音视频.它支持三种不同的媒体来源: 本地资源 内部 ...

  7. Android MediaPlayer 在 6.0 以上版本使用倍速播放功能说明

    Android MediaPlayer 在API 23即6.0版本开始支持倍速播放,下面我们来介绍一下如何使用MediaPlayer进行倍速播放. 一.核心接口 MediaPlayer.setPlay ...

  8. 结对编程--基于android平台的黄金点游戏(2.0版本)

    在昨天上传完博客之后发现一个重大的bug...故在此推出2.0版本. 博文详情见:http://www.cnblogs.com/RayShea/p/5372398.html coding地址:http ...

  9. Cocos2dx-3.0版本 从开发环境搭建(Win32)到项目移植Android平台过程详解

    作为重量级的跨平台开发的游戏引擎,Cocos2d-x在现今的手游开发领域占有重要地位.那么问题来了,作为Cocos2dx的学习者,它的可移植特性我们就需要掌握,要不然总觉得少一门技能.然而这个时候各种 ...

随机推荐

  1. hive上传数据到oracle

    # Oracle 建立hive外部表 使用oracle的大数据连接器向建立hive的外部表,在通过在oracle中根据外部表建立内部表(create table as select * from ex ...

  2. anaconda使用方法

    我是用的win10.想写爬虫,所以使用了  anaconda .总结一下使用的方法. 安装阶段跳过.: 再终端输入  jupyter notebook  然后就会在. 浏览器显示一个网页.其实这个也不 ...

  3. Java-Oracle数据库连接

    Oracle数据库先创建一个表和添加一些数据,下面是连接数据库的具体实现.(导入jar包:ojdbc14.jar) import java.sql.Connection; import java.sq ...

  4. hbase-bloom filter

    bloom fliter的作用主要用于提升hbase的读性能,但是会牺牲一定的存储空间. 原理: bloom fliter是一种空间效率很高的随机数据结构,初始状态时,bloom filter是一个包 ...

  5. docker使用代理(测试docker 17.06)

    环境:debian9 service docker stop sudo HTTP_PROXY=http://127.0.0.1:1080 dockerd sudo docker pull gcr.io ...

  6. Codeforces 524 解题报告

    打的很快乐的一次比赛hiahiahia, 才A掉4题rating就涨了100+ 距离比赛\(3\)天了, 由于博主实在太颓, 又补掉了\(E\)题, 到现在才发解题报告 A. 语法题, 读入输出就行了 ...

  7. 设计模式学习心得<外观模式 Facade>

    外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 这种模式涉及 ...

  8. mysql8.0 1251错误

    ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; ALTER USER '; FLUSH PR ...

  9. keepalived高可用简介与配置

    keepalived简介 keepalived介绍 Keepalived 软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP ...

  10. DOM生成XML文件

    /** * 从数据库读取学生信息的数据集合,然后Dom创建数据树,再转成XML格式数据,输出生成xml文件 * @author pikaqiu * */ public class TestGenXml ...