android seekto实现_关于Android VideoView seekTo不准确的解决方案

本文章为原创,转载时请注明出处

实现 Android 的视频播放,通常有以下几种方式

1.使用自带的播放器,指定 Action 为 ACTION_VIEW,Data 为 Uri,Type 为其 MIME 类型。

2.使用 VideoView 来播放,在布局文件中使用 VideoView 结合

MediaController 来实现对其控制。

3.使用 MediaPlayer 类和 SurfaceView 来实现,这种方式很灵活。

使用 VideoView 播放视频的步骤:

1.在界面布局文件中定义 VideoView 组件,或在程序中创建

VideoView 组件

2.调用 VideoView 的如下两个方法来加载指定的视频

setVidePath(String path) // 加载path文件代表的视

setVideoURI(Uri uri) // 加载uri所对应的视频

3.调用 start()、stop()、pause()方法来控制视频的播放

4.通过与 MediaController 类结合使用,开发者可以不用自己控制播放与暂停

调用 seekTo 方法跳转不准的问题

典型场景:

当用户从后台恢复播放界面时,需要跳转到之前退出的时间点继续播放原来的视频。其实现逻辑大致上是:

在暂停时保存当前 VideoView 的 currantPosition 进度

恢复播放时,调用 seekTo 方法,传入 currantPosition 作为跳转参数

按照官方提供的 API 来看,这是最合理的使用方式。但在某些情况下,我们会遇到视频恢复播放时进度位置不准的问题,甚至有些会重头开始播放。

下面就针对使用 VideoView 播放视频时 seekTo 跳转不准的问题进行分析。

问题定位

1. 消除方法异步执行的影响

首先明确一点: *** VideoView 的 seekTo 方法是异步执行的***,因此会有 seek 未完成但播放已经开始的现象。需要消除 seekTo 对恢复播放的影响,应该在 seek 操作完成的 seekComplete 回调方法中执行 ViedeoView 的 start 方法。

Tip: seekComplete 属于 MediaPlayer 类的 OnPreparedListener 监听器的一个回调方法。虽然 VideoView 是基于 MediaPlayer 实现的,但没提供 setOnSeekCompleteListener 设置监听器的方法,所以我们要拿到 VideoView 内部持有 MediaPlayer 对象。

// 设置 VideoView 的 OnPrepared 监听,拿到 MediaPlayer 对象。

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer mp) {

//设置 MediaPlayer 的 OnSeekComplete 监听

mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {

@Override

public void onSeekComplete(MediaPlayer mp) {

// seekTo 方法完成时的回调

if(isPause){

videoView.start();

isPause = false;

}

}

});

}

});

2. 消除视频源的问题

其实 seekTo 跳转的位置其实并不是参数所带的 position,而是离 position 最近的视频关键帧。

关于视频关键帧建议大家可以去了解一下相关知识,大致上就是视频播放时需要从一个关键帧的位置开始。

所以当视频在跳转到相应的 position 位置缺少关键帧的情况下,调用 seekTo 方法是无法在当前位置开始播放。这时会寻找离指定 position 最近的关键帧位置开始播放。

关于视频源造成的问题,可以采取以下解决措施:

替换成满足需求的视频源文件(寻找合格的视频文件)

对视频源文件进行处理,增加其关键帧数量,比如可以1s设置一个关键帧(基于目前已有的视频文件进行处理)。

如果选择第二种方式,要增加视频的关键帧数量,可以推荐大家使用FFmpeg进行增加关键帧的处理工作。 http://ffmpeg.org/

FFmpeg 工具相关命令行语句:

ffmpeg.exe -i "D:\in.mp4" -c:v libx264 -preset superfast -x264opts keyint=25 -acodec copy -f mp4 "D:\out.mp4"

命令语句大致意思是:在 D 盘路径下把 in.mp4 视频文件每隔 25 帧设置一个关键帧,音轨保持原视频参数,其余使用 FFmpeg 提供的default 值,最后保存为 out.mp4 文件到 D 盘。

总结

在深究问题的原因时不可浅尝而止,也不要一味的怀疑是不是代码造成了问题。很多情况下都选择盲目地替换不同的视频组件出实现,而忽略了视频源文件本身的问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值