Android MediaPlayer 在 6.0 以上版本使用倍速播放功能说明
Android MediaPlayer 在API 23即6.0版本开始支持倍速播放,下面我们来介绍一下如何使用MediaPlayer进行倍速播放。
一、核心接口
- MediaPlayer.setPlaybackParams(PlaybackParams params) throws IllegalStateException, IllegalArgumentException
1. 接口说明
(1) 使用这个接口可以进行播放速率的设置。
(2) 播放器prepared状态之前调用这个方法不会更改播放器的状态。
(3) prepared状态之后设置速率0等同于调用pause(),当调用start恢复播放以后,将以原来的速率进行播放。
(4) prepared状态之后设置非0的速率等同于调用start()。
(5) 当播放器还未初始化或者已经被释放的时候设置会抛IllegalStateException的异常。
(6) 当参数不支持的时候会抛IllegalArgumentException的异常。
2. 设置时机要求
合法的时机:Initialized, Prepared, Started, Paused, PlaybackCompleted, Error
非法的时机:Idle, Stopped
二、使用示例
本例为悬浮弹窗播放View,在此基础上增加了倍速播放的测试逻辑,经测试,发现此API可用,且效果基本和ijk播放器一样。
- public class FloatingPopupWindow implements SurfaceHolder.Callback {
- // 弹窗宽度
- private static final int POPUP_WINDOW_WIDTH = 567;
- // 弹窗高度
- private static final int POPUP_WINDOW_HEIGHT = 432;
- private Context mContext;
- private PopupWindow mPopupWindow;
- private View mPopContentView;
- private RelativeLayout mFloatingLayout;
- SurfaceView surfaceView;
- SurfaceHolder surfaceHolder;
- MediaPlayer mediaPlayer;
- private boolean IsDouble = false;
- private float lastX;
- private float lastY;
- public FloatingPopupWindow(Context context) {
- mContext = context;
- mPopContentView = LayoutInflater.from(mContext).inflate(R.layout.popup_window_floating, null);
- mPopupWindow = new PopupWindow(mPopContentView, POPUP_WINDOW_WIDTH, POPUP_WINDOW_HEIGHT);
- mFloatingLayout = mPopContentView.findViewById(R.id.floating_layout);
- surfaceView = mPopContentView.findViewById(R.id.surface_view);
- surfaceHolder = surfaceView.getHolder();
- surfaceHolder.addCallback(this);
- mPopContentView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- if (event.getPointerCount() == 1) {
- IsDouble = false;
- }
- if (!IsDouble) {
- lastX = event.getRawX();
- lastY = event.getRawY();
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (event.getPointerCount() > 1) {
- IsDouble = true;
- }
- if (!IsDouble) {
- int deltaX = (int) (event.getRawX() - lastX);
- lastX = event.getRawX();
- int deltaY = (int) (event.getRawY() - lastY);
- lastY = event.getRawY();
- mPopupWindow.update(deltaX + (int) lastX - (POPUP_WINDOW_WIDTH / 2), deltaY + (int) lastY - (POPUP_WINDOW_HEIGHT / 2), -1, -1, true);
- }
- break;
- }
- return true;
- }
- });
- mediaPlayer = new MediaPlayer();
- }
- /**
- * 是否显示
- */
- public boolean isShowing() {
- return mPopupWindow.isShowing();
- }
- public void setPlayPath(String playPath) {
- try {
- mediaPlayer.reset();
- mediaPlayer.setDataSource(playPath);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Surface surface = holder.getSurface();
- mediaPlayer.setSurface(surface);
- mediaPlayer.prepareAsync();
- mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
- @Override
- public void onPrepared(MediaPlayer mp) {
- mp.start();
- // 6.0及以后支持倍速,测试
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mp.setPlaybackParams(new PlaybackParams().setSpeed(0.75f));
- }
- }
- });
- mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
- @Override
- public void onCompletion(MediaPlayer mp) {
- dismiss();
- }
- });
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
- private View mNowView; // 当前容器里面装载的View
- /**
- * 添加新View
- */
- public void addView(View view) {
- mNowView = view;
- if (mFloatingLayout != null) {
- mFloatingLayout.addView(view);
- }
- }
- /**
- * 获取当前正展示的View
- */
- public View getNowView() {
- return mNowView;
- }
- /**
- * 移除所有的子布局
- */
- public void removeAllView() {
- if (mFloatingLayout != null) {
- mFloatingLayout.removeAllViews();
- }
- }
- /**
- * 显示弹出框
- */
- public void show(View view) {
- if (isShowing()) {
- return;
- }
- mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 200);
- }
- /**
- * 隐藏弹出框
- */
- public void dismiss() {
- if (mPopupWindow != null) {
- if (mPopupWindow.isShowing()) {
- mPopupWindow.dismiss();
- }
- }
- }
- }
Android MediaPlayer 在 6.0 以上版本使用倍速播放功能说明的更多相关文章
- [Android自动化] 在 pip-9.0.1 版本情况下安装 uiautomator2 报错的解决办法
1.在命令窗口中使用命令: pip install uiautomator2 时报 pip 版本过低,需要先升级 pip 版本,理论上会按照提示进行升级 pip 操作,但执行升级命令时到最后却还是报错 ...
- AppCompat v21 — Android 5.0之前版本设备的Material Design实现
博客原文地址:http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html,要想打 ...
- Android studio 3.0以上版本无法引入,找不到v4,v7包方案解决
Android studio 3.0以上版本无法引入v4.v7包报红,即找不到v4.v7包,解决方案如下: 步骤: 1,Close Object,点击左上角的关闭工程. 2,点击x,删除项目. 3,重 ...
- Android Studio 3.0.1 版本包下载
Android Studio 3.0.1 发布了,这是对 Android Studio 3.0 的一个小的更新,包括一般错误修复和性能改进 下载地址: Windows 64 位:https://dl. ...
- 如何在Cordova Android 7.0.0 以下版本集成最新插件 极光插件为例
前提 Cordova Android 7.0.0开始改变了项目安卓平台的架构.新建一个空项目分别添加Android 6.4.0 和 Android 7.0.0平台: cordova platform ...
- 对Android 8.0以上版本通知点击无效的一次分析
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/178 对Android 8.0以上版本通知点击无效的一次分 ...
- Android P(9.0) userdebug版本执行adb remount失败
[DESCRIPTION] 在android P版本上如果按照“FAQ18076 android 6.0 M userdebug版本执行adb remount失败”的做法在userdebug ...
- 快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题
快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题 转 https://www.jb51.net/article/144939.htm 今天小编就为大家分享一篇快速解决设置And ...
- Android MediaPlayer 音频倍速播放,调整播放速度
本文链接: Android MediaPlayer 倍速播放,调整播放速度 现在市面上的很多音视频App都有倍速播放的功能,例如把播放速度调整为0.5.1.5.2倍等等. 从Android API 2 ...
随机推荐
- Jenkins工程中SQL语句执行的方法
前言 网上很多jenkins工程中基于shell或批处理方式调用sql文件执行sql命令的方式,大部分都是需要基于sql文件来完成的,因此在sql语句发生变化时需要去jenkins服务端修改对应的sq ...
- MSSQL - 最佳实践 - 使用SSL加密连接
MSSQL - 最佳实践 - 使用SSL加密连接 author: 风移 摘要 在SQL Server安全系列专题月报分享中,往期我们已经陆续分享了:如何使用对称密钥实现SQL Server列加密技术. ...
- 在kubernetes 集群内访问k8s API服务
所有的 kubernetes 集群中账户分为两类,Kubernetes 管理的 serviceaccount(服务账户) 和 useraccount(用户账户).基于角色的访问控制(“RBAC”)使用 ...
- 查看python版本多少位的
正常我们在cmd终端输入python之后,如果有安装python,就会在回车之后出来关于你安装的python版本信息,几版本,多少位的,但是还有一种,像我这样只显示了python版本是3.7.5,并没 ...
- Linux Zookeeper 安装, 带视频
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 面试必备+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 疯狂创客圈 高并发 ...
- 熔断器Hystrix及服务监控Dashboard
服务雪崩效应 当一个请求依赖多个服务的时候: 正常情况下的访问 : 但是,当请求的服务中出现无法访问.异常.超时等问题时(图中的I),那么用户的请求将会被阻塞. 如果多个用户的请求中,都存在无法访问的 ...
- UML简单介绍—类图详解
类图详解 阅读本文前请先阅读:UML简单介绍—类图这么看就懂了 1.泛化关系 一个动物类: /** * 动物类 */ public class Animal { public String name; ...
- jqgrid addRowData报错
今天再写项目的时候, 有一个手动添加行的功能,使用的是jqgrid的addRowData方法添加数据.但是在我们切换标签页的时候,再次添加行,调用这个方法的时候,报错了.错误信息如下 然后经过自己的反 ...
- border-box和CSS3 calc()解决盒模型加边框或边距后尺寸变大的问题
box-sizing box-sizing的CSS属性是用来改变默认的CSS框模型 属性 初始值:content-box 适用于:接受的所有元素的宽度或高度 继承:无 媒体:visual 指定的:as ...
- Vue 中的keep-alive 什么用处?
keep-alive keep-alive是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在v页面渲染完毕后不会被渲染成一个DOM元素 <keep-aliv ...