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. Android面试准备20190422

    1.即时推送原理,采用的push推送模式,保持一个长连接,服务端和客户端连接后不再断开.所谓长连接,即是在一个TCP上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发送检测 ...

  2. MUI手势锁

    通过mui提供的手势锁插件实现,手势锁样式.存储需要自己完成. 1.样式展示 2.实现 2.1 html 需要一个div容器 <div class="mui-content" ...

  3. Linux下docker报错syntax error:unexpected protocol at end of statement

    ---恢复内容开始--- [Linux]Shell脚本“syntax error: unexpected end of file”原因及处理 :::https://blog.csdn.net/u013 ...

  4. 在linux上添加硬盘

    首先呢我们需要添加一个硬盘,如下所示: 接着我们需要新建一个硬盘 代码如下: mkdir /bak fdisk -l 接着我们继续第二步,分区 代码如下: fdisk /dev/sdb n   add ...

  5. python基础之Day20part1

    一.hash算法 什么是hash? 类似工厂加工的过程,传bytes串,经过运算返回字符 hash相当于工厂,传给hash算法的内容是原材料,hash值为产品 为何用hash? hash三大特性: 1 ...

  6. 转载 linux基本操作

    转载地址 https://segmentfault.com/a/1190000014840829 前言 只有光头才能变强 这个学期开了Linux的课程了,授课的老师也是比较负责任的一位.总的来说也算是 ...

  7. Spark1.5.0 + Hadoop2.7.1整合

    Hadoop2.7.1已经配置完毕. Hosts分配如下: master 172.16.15.140 slave1 172.15.15.141 slave2 172.16.15.142 一.安装Sca ...

  8. java35

    1.变量的访问:就近原则 2.this.name 本类的name 3.枚举:一个事物的固定状态 修饰符 enum 枚举名称{ } 4.枚举相当于一个特殊的类,默认继承了Enum 5.枚举不能直接创建对 ...

  9. 在centos7上配置jenkins

    在Linux(centos7)环境下配置jenkins,并用github作为仓库. 配置jenkins https://blog.csdn.net/wangfei0904306/article/det ...

  10. W7500S2E串口转以太网

    概述 W7500S2E是一系列串口转以太网模块,支持TCP Server.TCP Client和UDP三种工作模式,串口波特率最高可达460,800bps,并提供配套的上位机配置软件,也可通过网页或A ...