热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

androidseekto实现_关于AndroidVideoViewseekTo不准确的问题

本文章为原创,转载时请注明出处Android播放视频实现Android的视频播放器,通常有以下几种方式:1、使用自带的播放器,

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

Android播放视频

实现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、调用VideoView的start()、stop()、psuse()方法来控制视频的播放

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

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

使用VideoView

当用户从后台恢复播放时,需要跳转到之前退出的时间点继续播放。

整个控制逻辑大致上是:

在暂停时保存CurrantPosition进度

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

但是还是遇到了恢复播放时位置不准的问题,而且甚至有重头开始播放的现象。

问题定位

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

VideoView是基于MediaPlayer实现的,但没提供setOnSeekCompleteListener方法

//设置videoview的OnPrepared监听

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer mp) {

//设置MediaPlayer的OnSeekComplete监听

mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {

@Override

public void onSeekComplete(MediaPlayer mp) {

if(isPause){

videoView.start();

isPause = false;

}

}

});

}

});

根本原因

其实seekTo跳转的位置其实并不是参数所带的position,而是离position最近的关键帧。关于视频的关键帧建议大家可以去了解一下相关知识,大致上就是视频播放时需要从一个关键帧的位置开始。

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

解决措施

如何确认是视频源造成的问题,可以采取以下解决措施:

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

2、对视频源文件进行处理,增加其关键帧数量,比如可以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盘。

总结

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

不积跬步无以至千里,从当下开始就得养成好的习惯,一点一滴的积累经验。厚积薄发,技术由点汇聚成面,总结很重要,后面会开始很多的文章产出。



推荐阅读
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • Asp.net Mvc Framework 七 (Filter及其执行顺序) 的应用示例
    本文介绍了在Asp.net Mvc中应用Filter功能进行登录判断、用户权限控制、输出缓存、防盗链、防蜘蛛、本地化设置等操作的示例,并解释了Filter的执行顺序。通过示例代码,详细说明了如何使用Filter来实现这些功能。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
author-avatar
无声胜有剩
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有