package com.shuyu.gsyvideoplayer.video; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.graphics.Point; import android.os.Build; import android.os.Handler; import android.transition.TransitionManager; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; import com.shuyu.gsyvideoplayer.GSYVideoManager; import com.shuyu.gsyvideoplayer.GSYVideoPlayer; import com.shuyu.gsyvideoplayer.R; import com.shuyu.gsyvideoplayer.SmallVideoTouch; import com.shuyu.gsyvideoplayer.listener.GSYMediaPlayerListener; import com.shuyu.gsyvideoplayer.utils.CommonUtil; import com.shuyu.gsyvideoplayer.utils.OrientationUtils; import java.lang.reflect.Constructor; import java.util.Map; import static com.shuyu.gsyvideoplayer.utils.CommonUtil.getActionBarHeight; import static com.shuyu.gsyvideoplayer.utils.CommonUtil.getStatusBarHeight; import static com.shuyu.gsyvideoplayer.utils.CommonUtil.hideSupportActionBar; import static com.shuyu.gsyvideoplayer.utils.CommonUtil.showSupportActionBar; /** * Created by shuyu on 2016/11/17. */ public abstract class GSYBaseVideoPlayer extends FrameLayout implements GSYMediaPlayerListener { protected static final int FULLSCREEN_ID = 85597; public static final int SMALL_ID = 84778; protected static long CLICK_QUIT_FULLSCREEN_TIME = 0; protected boolean mActionBar = false;//是否需要在利用window实现全屏幕的时候隐藏actionbar protected boolean mStatusBar = false;//是否需要在利用window实现全屏幕的时候隐藏statusbar protected boolean mCache = false;//是否播边边缓冲 private boolean mShowFullAnimation = true;//是否使用全屏动画效果 protected int[] mListItemRect;//当前item框的屏幕位置 protected int[] mListItemSize;//当前item的大小 protected int mCurrentState = -1; //当前的播放状态 protected boolean mRotateViewAuto = true; //是否自动旋转 protected boolean mIfCurrentIsFullscreen = false; protected Context mContext; protected String mOriginUrl; //原来的url protected String mUrl; protected Object[] mObjects; protected ViewGroup mTextureViewContainer; private OrientationUtils mOrientationUtils; private Handler mHandler = new Handler(); protected View mSmallClose; public GSYBaseVideoPlayer(Context context) { super(context); } public GSYBaseVideoPlayer(Context context, AttributeSet attrs) { super(context, attrs); } public GSYBaseVideoPlayer(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private ViewGroup getViewGroup() { return (ViewGroup) (CommonUtil.scanForActivity(getContext())).findViewById(Window.ID_ANDROID_CONTENT); } /** * 移除没用的 */ private void removeVideo(ViewGroup vp, int id) { View old = vp.findViewById(id); if (old != null) { if (old.getParent() != null) { ViewGroup viewGroup = (ViewGroup) old.getParent(); vp.removeView(viewGroup); } } } /** * 保存大小和状态 */ private void saveLocationStatus(Context context, boolean statusBar, boolean actionBar) { getLocationOnScreen(mListItemRect); int statusBarH = getStatusBarHeight(context); int actionBerH = getActionBarHeight((Activity) context); if (statusBar) { mListItemRect[1] = mListItemRect[1] - statusBarH; } if (actionBar) { mListItemRect[1] = mListItemRect[1] - actionBerH; } mListItemSize[0] = getWidth(); mListItemSize[1] = getHeight(); } /** * 全屏 */ private void resolveFullVideoShow(Context context, GSYBaseVideoPlayer gsyVideoPlayer, int h, int w) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) gsyVideoPlayer.getLayoutParams(); lp.setMargins(0, 0, 0, 0); lp.height = ViewGroup.LayoutParams.MATCH_PARENT; lp.width = ViewGroup.LayoutParams.MATCH_PARENT; lp.gravity = Gravity.CENTER; gsyVideoPlayer.setLayoutParams(lp); gsyVideoPlayer.setIfCurrentIsFullscreen(true); mOrientationUtils = new OrientationUtils((Activity) context, gsyVideoPlayer); mOrientationUtils.setEnable(mRotateViewAuto); } /** * 恢复 */ private void resolveNormalVideoShow(View oldF, ViewGroup vp, GSYVideoPlayer gsyVideoPlayer) { if (oldF.getParent() != null) { ViewGroup viewGroup = (ViewGroup) oldF.getParent(); vp.removeView(viewGroup); } mCurrentState = GSYVideoManager.instance().getLastState(); if (gsyVideoPlayer != null) { mCurrentState = gsyVideoPlayer.getCurrentState(); } GSYVideoManager.instance().setListener(GSYVideoManager.instance().lastListener()); GSYVideoManager.instance().setLastListener(null); setStateAndUi(mCurrentState); addTextureView(); CLICK_QUIT_FULLSCREEN_TIME = System.currentTimeMillis(); } /** * 利用window层播放全屏效果 * * @param context * @param actionBar 是否有actionBar,有的话需要隐藏 * @param statusBar 是否有状态bar,有的话需要隐藏 */ public void startWindowFullscreen(final Context context, final boolean actionBar, final boolean statusBar) { hideSupportActionBar(context, actionBar, statusBar); this.mActionBar = actionBar; this.mStatusBar = statusBar; mListItemRect = new int[2]; mListItemSize = new int[2]; final ViewGroup vp = getViewGroup(); removeVideo(vp, FULLSCREEN_ID); if (mTextureViewContainer.getChildCount() > 0) { mTextureViewContainer.removeAllViews(); } saveLocationStatus(context, statusBar, actionBar); try { Constructor constructor = (Constructor) GSYBaseVideoPlayer.this.getClass().getConstructor(Context.class); final GSYBaseVideoPlayer gsyVideoPlayer = constructor.newInstance(getContext()); gsyVideoPlayer.setId(FULLSCREEN_ID); WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); final int w = wm.getDefaultDisplay().getWidth(); final int h = wm.getDefaultDisplay().getHeight(); FrameLayout.LayoutParams lpParent = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); FrameLayout frameLayout = new FrameLayout(context); frameLayout.setBackgroundColor(Color.BLACK); if (mShowFullAnimation && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(getWidth(), getHeight()); lp.setMargins(mListItemRect[0], mListItemRect[1], 0, 0); frameLayout.addView(gsyVideoPlayer, lp); vp.addView(frameLayout, lpParent); mHandler.postDelayed(new Runnable() { @Override public void run() { TransitionManager.beginDelayedTransition(vp); resolveFullVideoShow(context, gsyVideoPlayer, h, w); } }, 300); } else { FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(getWidth(), getHeight()); frameLayout.addView(gsyVideoPlayer, lp); vp.addView(frameLayout, lpParent); resolveFullVideoShow(context, gsyVideoPlayer, h, w); } gsyVideoPlayer.setUp(mUrl, mCache, mObjects); gsyVideoPlayer.setStateAndUi(mCurrentState); gsyVideoPlayer.addTextureView(); gsyVideoPlayer.getFullscreenButton().setImageResource(R.drawable.video_shrink); gsyVideoPlayer.getFullscreenButton().setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { clearFullscreenLayout(); } }); gsyVideoPlayer.getBackButton().setVisibility(VISIBLE); gsyVideoPlayer.getBackButton().setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { clearFullscreenLayout(); } }); GSYVideoManager.instance().setLastListener(this); GSYVideoManager.instance().setListener(gsyVideoPlayer); } catch (Exception e) { e.printStackTrace(); } } /** * 退出window层播放全屏效果 */ public void clearFullscreenLayout() { int delay = mOrientationUtils.backToProtVideo(); mOrientationUtils.setEnable(false); mHandler.postDelayed(new Runnable() { @Override public void run() { backToNormal(); } }, delay); } /** * 回到正常效果 */ private void backToNormal() { showSupportActionBar(mContext, mActionBar, mStatusBar); final ViewGroup vp = getViewGroup(); final View oldF = vp.findViewById(FULLSCREEN_ID); final GSYVideoPlayer gsyVideoPlayer; if (oldF != null) { gsyVideoPlayer = (GSYVideoPlayer) oldF; if (mShowFullAnimation && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { TransitionManager.beginDelayedTransition(vp); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) gsyVideoPlayer.getLayoutParams(); lp.setMargins(mListItemRect[0], mListItemRect[1], 0, 0); lp.width = mListItemSize[0]; lp.height = mListItemSize[1]; //注意配置回来,不然动画效果会不对 lp.gravity = Gravity.NO_GRAVITY; gsyVideoPlayer.setLayoutParams(lp); new Handler().postDelayed(new Runnable() { @Override public void run() { resolveNormalVideoShow(oldF, vp, gsyVideoPlayer); } }, 400); } else { resolveNormalVideoShow(oldF, vp, gsyVideoPlayer); } } else { resolveNormalVideoShow(null, vp, null); } } /** * 显示小窗口 */ public void showSmallVideo(Point size, final boolean actionBar, final boolean statusBar) { final ViewGroup vp = getViewGroup(); removeVideo(vp, SMALL_ID); if (mTextureViewContainer.getChildCount() > 0) { mTextureViewContainer.removeAllViews(); } try { Constructor constructor = (Constructor) GSYBaseVideoPlayer.this.getClass().getConstructor(Context.class); GSYBaseVideoPlayer gsyVideoPlayer = constructor.newInstance(getContext()); gsyVideoPlayer.setId(SMALL_ID); FrameLayout.LayoutParams lpParent = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); FrameLayout frameLayout = new FrameLayout(mContext); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(size.x, size.y); int marginLeft = CommonUtil.getScreenWidth(mContext) - size.x; int marginTop = CommonUtil.getScreenHeight(mContext) - size.y; if (actionBar) { marginTop = marginTop - getActionBarHeight((Activity) mContext); } if (statusBar) { marginTop = marginTop - getStatusBarHeight(mContext); } lp.setMargins(marginLeft, marginTop, 0, 0); frameLayout.addView(gsyVideoPlayer, lp); vp.addView(frameLayout, lpParent); gsyVideoPlayer.setUp(mUrl, mCache, mObjects); gsyVideoPlayer.setStateAndUi(mCurrentState); gsyVideoPlayer.addTextureView(); gsyVideoPlayer.onClickUiToggle(); gsyVideoPlayer.setSmallVideoTextureView(new SmallVideoTouch(gsyVideoPlayer, marginLeft, marginTop)); GSYVideoManager.instance().setLastListener(this); GSYVideoManager.instance().setListener(gsyVideoPlayer); } catch (InstantiationException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 隐藏小窗口 */ public void hideSmallVideo() { final ViewGroup vp = getViewGroup(); GSYVideoPlayer gsyVideoPlayer = (GSYVideoPlayer) vp.findViewById(SMALL_ID); removeVideo(vp, SMALL_ID); mCurrentState = GSYVideoManager.instance().getLastState(); if (gsyVideoPlayer != null) { mCurrentState = gsyVideoPlayer.getCurrentState(); } GSYVideoManager.instance().setListener(GSYVideoManager.instance().lastListener()); GSYVideoManager.instance().setLastListener(null); setStateAndUi(mCurrentState); addTextureView(); CLICK_QUIT_FULLSCREEN_TIME = System.currentTimeMillis(); } /** * 设置播放URL * * @param url * @param cacheWithPlay 是否边播边缓存 * @param objects * @return */ public abstract boolean setUp(String url, boolean cacheWithPlay, Object... objects); /** * 设置播放URL * * @param url * @param cacheWithPlay 是否边播边缓存 * @param mapHeadData * @param objects * @return */ public abstract boolean setUp(String url, boolean cacheWithPlay, Map mapHeadData, Object... objects); /** * 设置播放显示状态 * * @param state */ protected abstract void setStateAndUi(int state); /** * 添加播放的view */ protected abstract void addTextureView(); /** * 小窗口 **/ protected abstract void setSmallVideoTextureView(View.OnTouchListener onTouchListener); protected abstract void onClickUiToggle(); /** * 获取全屏按键 */ public abstract ImageView getFullscreenButton(); /** * 获取返回按键 */ public abstract ImageView getBackButton(); public boolean isRotateViewAuto() { return mRotateViewAuto; } public boolean isIfCurrentIsFullscreen() { return mIfCurrentIsFullscreen; } public void setIfCurrentIsFullscreen(boolean ifCurrentIsFullscreen) { this.mIfCurrentIsFullscreen = ifCurrentIsFullscreen; } /** * 自动旋转 */ public void setRotateViewAuto(boolean rotateViewAuto) { this.mRotateViewAuto = rotateViewAuto; } public boolean ismShowFullAnimation() { return mShowFullAnimation; } /** * 全屏动画 * * @param showFullAnimation 是否使用全屏动画效果 */ public void setShowFullAnimation(boolean showFullAnimation) { this.mShowFullAnimation = showFullAnimation; } }