Android MediaPlayer 在API 23即6.0版本開始支持倍速播放,下面咱們來介紹一下如何使用MediaPlayer進行倍速播放。ide
1、核心接口
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測試
2、使用示例
本例爲懸浮彈窗播放View,在此基礎上增長了倍速播放的測試邏輯,經測試,發現此API可用,且效果基本和ijk播放器同樣。ui
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(); } } } }