package com.wasu.cs.widget.videoview; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.graphics.Rect; import android.media.MediaPlayer; import android.net.Uri; import android.os.Build; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.view.KeyEvent; import android.view.View; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Toast; import com.sohuott.vod.security.ServiceGuardReciver; import com.sohutv.tv.player.partner.SohuTvPlayer; import com.wasu.authsdk.AuthListener; import com.wasu.authsdk.AuthSDK; import com.wasu.authsdk.IAuthInterface; import com.wasu.authsdk.entity.PriceInfo; import com.wasu.authsdk.help.Tools; import com.wasu.base.privateconfig.Config; import com.wasu.common.WError; import com.wasu.comp.pay.DialogPay; import com.wasu.comp.pay.DialogPay.PayStatusListener; import com.wasu.comp.userlogin.DialogLogin; import com.wasu.comp.videoview.AdPlayerView; import com.wasu.comp.videoview.IMediaControl; import com.wasu.comp.videoview.IMediaInterceptListener; import com.wasu.comp.videoview.IMediaListener; import com.wasu.comp.videoview.UrlProperty; import com.wasu.compfactory.WasuCompFactory; import com.wasu.cs.model.DemandList; import com.wasu.cs.model.DemandPlayinfo; import com.wasu.cs.model.DemandProgram; import com.wasu.cs.model.DemandSeries; import com.wasu.cs.model.DetailSeriesSet; import com.wasu.cs.model.IAssetList; import com.wasu.cs.module.AuthMiguModule; import com.wasu.cs.module.FavAndHisModule; import com.wasu.cs.module.ScreenSaverModule; import com.wasu.cs.mvp.presenter.DetailLogic; import com.wasu.cs.ui.ActivityDetail; import com.wasu.cs.ui.DialogBKBM; import com.wasu.cs.widget.mediacontrol.DialogPlanBuy; import com.wasu.cs.widget.mediacontrol.MediaController; import com.wasu.cs.widget.mediacontrol.SeekbarController; import com.wasu.cs.widget.videoview.ext.sohu.SohuIMediaControl; import com.wasu.cs.widget.videoview.ext.sohu.SohuIMediaListener; import com.wasu.decode.DecryptUtil; import com.wasu.module.datafetch.DataFetchListener.ObjectListener; import com.wasu.module.datafetch.DataFetchModule; import com.wasu.module.datafetch.ObjectBase; import com.wasu.module.db.DBManage; import com.wasu.module.log.WLog; import com.wasu.statistics.WasuStatistics; import com.wasu.util.NetUtils; import com.wasu.util.VersionUtils; import org.apache.http.HttpStatus; import org.json.JSONObject; import java.io.IOException; import java.lang.ref.SoftReference; import java.net.HttpURLConnection; import java.net.URL; import java.util.Formatter; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import basic.BuilderTypeManager.BuildType; import basic.db.model.DBProgramHistory; import cn.com.wasu.main.AppUtil; import cn.com.wasu.main.BuildConfig; import cn.com.wasu.main.ChannelFlavor; import cn.com.wasu.main.Common; import cn.com.wasu.main.R; /** * 点播播放器 * * @author zhangrm */ public final class WasuPlayerView extends RelativeLayout implements IMediaControl, IMediaListener, AppUtil.OnNetStateListener { private String ADtip = ",按OK键订会员免广告"; int mExcludeOption = MediaController.NONE_EXCLUDE_OPTION;//默认没有排除项 /** * 当前资产已经改变 */ public static final int MSG_ASSET_CHANGED = 0; private static final String TAG = "WasuPlayerView"; public static final long PLAY_RATE_NORMAL_H = 2500000; public static final long PLAY_RATE_NORMAL_L = 1300000; public static final long PLAY_RATE_BD = 3800000; public static final long PLAY_RATE_4K = 6000000; private static final int MAX_LOOP_CNT = 10; /** * 默认码率1.3m */ public static long DEFAULT_PLAY_RATE = PLAY_RATE_NORMAL_L; /** * 正常播放 */ public static final int PLAY_TYPE_NORMAL = 0; /** * 连播 */ public static final int PLAY_TYPE_LOOP = 1; /** * 连播分页条数 */ private static final int PSIZE = 50; /////////////////////////////////////////////////////////////////////////////////////////// /** * 边看边买 ****/ private Handler mHandler; private Runnable mRunnable; private DialogBKBM mDialogBKBM; //////////////////////////////// // /** // * 登陆弹窗 // */ // public DialogLogin mDialogLogin; // /** // * 包月弹窗 // */ // public DialogPlanBuy mDialogPlanBuy; /** * 支付弹窗 */ public DialogPay mDialogPay; /** * 播放器状态监听器 */ private List mediaListeners; /** * * */ public DetailLogic mDetailLogic; /** * 播放器窗口全屏变化监听 */ public interface OnScreenChangedListener { void onScreenChanged(boolean isFullScreen); } private List scrChgListeners; /** * 连播次序改变监听 */ public interface OnPlayIndexChangedListener { /** * @param index 播放的是第几个资产 * @param position 播放的是当前集合资产的第几集,非集合资产时position为1 * @param total 当前集合资产总集数 */ void onPlayIndexChanged(int index, int position, int total); } private List playIdxChgListener; /////////////////////////////////////////////////////////////////////////////////////////// /** * 资产信息 */ private DemandProgram assetInfo, assetInfoBackup; /** * 获取资产地址 */ private String assetUrl; /** * 播放类型 */ private int playType; /** * 子播放类型 */ private int subPlayType; /** * 联播list */ private IAssetList assetList; /** * 列表index */ private int playIndex; /** * 指定播放的码率 */ private long bitrate; /** * 域名 */ private String domain; /** * 当前的播放信息(从assetInfo里面获取) */ private DemandSeries assetSeries; //to fix memory leak problem , use softreference to param context SoftReference softContext = new SoftReference(this.getContext()); public void setAssetSeries(DemandSeries assetSeries) { this.assetSeries = assetSeries; } public DemandSeries getAssetSeries() { return assetSeries; } /** * 是否是最后一个资产播放完毕 */ private boolean isLastSeriesFinish; public boolean isLastSeriesFinish() { return isLastSeriesFinish; } /////////////////////////////////////////////////////////////////////////////////////////// private static final int STATUS_INIT = 0; private static final int STATUS_PARSE_INTENT = 1; private static final int STATUS_FETCH_ASSET_INFO = 2; private static final int STATUS_QUERY_PRICE = 3; private static final int STATUS_ADJUST_PLAY_BITRATE = 4; private static final int STATUS_QUERY_HISTORY = 5; private static final int STATUS_PLAY_AUTH = 6; private static final int STATUS_DONE = 7; /** * 当前状态 */ private int currentStatus; /** * 下一个流程 */ private static final int PROCESS_NEXT = 0; /** * 上一个流程 */ private static final int PROCESS_PREVIOUS = 1; private Handler processHandler = new Handler() { @Override public void handleMessage(Message msg) { WLog.i(TAG, "currentStatus=" + currentStatus); if (msg.what == PROCESS_NEXT) { switch (currentStatus) { case STATUS_INIT: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); } checkParameters(); break; case STATUS_PARSE_INTENT: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); } if (assetInfo == null) { fetchAssetInfo(); } else { queryPrice(); } break; case STATUS_FETCH_ASSET_INFO: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); } queryPrice(); break; case STATUS_QUERY_PRICE: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); } adjustPlayBitrate(); break; case STATUS_ADJUST_PLAY_BITRATE: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); } queryHistory(); break; case STATUS_QUERY_HISTORY: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); } playAuth(); break; case STATUS_PLAY_AUTH: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); } play(); break; case STATUS_DONE: if (mediaController != null) { mediaController.showBufferView(); mediaController.setReady(false); mediaController.setAssetInfo(assetInfo); mediaController.setAssetUrl(assetUrl); mediaController.setPlayType(playType); mediaController.setPlayIndex(playIndex); mediaController.setAssetList(assetList); } if (playerMask != null) { playerMask.setAssetInfo(assetInfo); } break; } } else if (msg.what == PROCESS_PREVIOUS) { // TODO } } }; int MIGU = 93; private void play2(String url) { if (TextUtils.isEmpty(url)) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "没有获取到播放串,可能该片源已下线"); WLog.e(TAG, "没有获取到播放串,可能该片源已下线"); return; } if (videoView != null) { videoView.updateParams(getUpdateParams()); } if (assetInfo == null) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "资产获取失败"); WLog.e(TAG, "资产获取失败"); return; } try { setVideoPath(url, urlProperty); } catch (Exception e) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "播放地址无效,可能该片源已下线"); WLog.e(TAG, "播放地址无效,可能该片源已下线"); e.printStackTrace(); return; } // 免费资产/已付费资产,上次观看时间如果距离结束10s以上,将历史记录传给播放器,收费资产等待询价结果再决定是否seek,询价免费seek,不免费不seek // 收费资产需seek时间小于预览时间再seek if ((assetInfo.isFree() || (!assetInfo.isFree() && assetHistory.lastPlayTime < assetSeries.getPreviewTime() * 1000)) && assetHistory.lastSeries == assetInfo.getCurPlayIndex() && assetHistory.duration - assetHistory.lastPlayTime > 10000) { seekTo((int) assetHistory.lastPlayTime); isShowSeekMsg = true; } processHandler.sendEmptyMessage(PROCESS_NEXT); } /////////////////////////////////////////////////////////////////////////////////////////// /** * 播放器 */ private AdPlayerView videoView; /** * 当前播放器类型,用于切换播放器 */ private ExtPlayer curPlayer = ExtPlayer.Default; /** * 播控 */ private MediaController mediaController; /** * 搜狐播控 */ private SohuIMediaControl mSohuIMediaControl; public MediaController getMediaController() { return this.mediaController; } /** * 播放器窗口 */ private PlayerWindow playerWindow; /** * 播放器蒙版 */ private PlayerMask playerMask; /** * 解码后实际的播放地址 */ private String mRealUrl; public String getRealUrl() { return mRealUrl; } /** * UrlProperty */ private UrlProperty urlProperty; /** * 是否需要支付 */ private boolean mbNeedPay = false; /** * 当前播放资产原始价格 */ private double mOriginPrice = 0; /** * 锚 */ private View anchorView; /** * 当前宿主activity */ private Activity activity; /** * 当前是否全屏 */ private boolean isFullScreen; /** * 资产播放历史 */ private DBProgramHistory assetHistory; /** * 错误重试次数 */ private int errorRetryCount = 3; /** * 播放器准备好时,是否显示续播的消息 */ private boolean isShowSeekMsg; /** * 当前是否在播放广告 */ private boolean isAdPlaying; /** * 支付弹窗起来的时候的播放位置 */ private int posWhenPay; /** * 是否detach */ private boolean isDetach; /** * 是否支付失败 */ private boolean isPayFail = false; /** * 控制是否全屏,返回的时候不回到小窗 */ private boolean isFullPlay = false; /** * 第三方启动时候指定启动的时间位置 */ private int currentPosition = -1; private Runnable openVideoTask = new Runnable() { @Override public void run() { if (isDetach) { return; } try { if (assetInfo != null && assetInfo.getAssetFrom() < 91) {//华数资产302处理 mRealUrl = DecryptUtil.fetchCdnUrl(softContext.get(), mRealUrl, AuthSDK.getInstance().getValue(IAuthInterface.KEY_TVID), "tv_4_0"); HttpURLConnection connection = (HttpURLConnection) new URL(mRealUrl).openConnection(); if (connection == null) { post(new Runnable() { @Override public void run() { if (isDetach) { return; } postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "无法连接到服务器"); } }); return; } connection.setConnectTimeout(10 * 1000); connection.setReadTimeout(20 * 1000); connection.setUseCaches(false); connection.setInstanceFollowRedirects(false); final int responseCode = connection.getResponseCode(); if (responseCode == HttpStatus.SC_MOVED_TEMPORARILY) { String locationUrl = connection.getHeaderField("Location"); WLog.e(TAG, "location url:" + locationUrl); if (!TextUtils.isEmpty(locationUrl)) { mRealUrl = locationUrl; } } else if (responseCode == HttpStatus.SC_OK) { //do nothing } else { post(new Runnable() { @Override public void run() { if (isDetach) { return; } if (responseCode == -1) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "无法连接到服务器"); } else { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "服务器错误:" + responseCode); } } }); return; } } post(new Runnable() { @Override public void run() { if (isDetach) { return; } //这时候可能已经调用了stopPlayback,mRealUrl有可能为空 if (TextUtils.isEmpty(mRealUrl)) { return; } videoView.setVideoPath(mRealUrl, urlProperty); } }); } catch (IOException e) { post(new Runnable() { @Override public void run() { if (isDetach) { return; } postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取播放地址出错"); } }); e.printStackTrace(); } catch (IllegalArgumentException e){ post(new Runnable() { @Override public void run() { if (isDetach) { return; } postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取播放地址出错"); } }); e.printStackTrace(); } } }; //////////////////////////////////////////////////////////////////////////////////////////// public WasuPlayerView(Context context, String payUrl) { this(context, payUrl, null); } public WasuPlayerView(Context context, DetailLogic detailLogic, String payUrl){ this(context, payUrl, null); mDetailLogic = detailLogic; } public WasuPlayerView(Context context, DetailLogic detailLogic, String payUrl,int excludeOption){ this(context, payUrl, null,excludeOption); mDetailLogic = detailLogic; } public WasuPlayerView(Context context, String payUrl, int excludeOption) { this(context, payUrl, null, excludeOption); } public WasuPlayerView(Context context, String payUrl, ExtPlayer extPlayer) { super(context); RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); this.setLayoutParams(layoutParams); this.setPadding(0, 0, 0, 0); this.setBackgroundColor(Color.BLACK); this.mDialogPay = new WasuCompFactory().createUniPay(context, payUrl); init(extPlayer); } public WasuPlayerView(Context context, String payUrl, ExtPlayer extPlayer,int excludeOption) { super(context); this.mExcludeOption = excludeOption; RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); this.setLayoutParams(layoutParams); this.setPadding(0, 0, 0, 0); this.setBackgroundColor(Color.BLACK); this.mDialogPay = new WasuCompFactory().createUniPay(context, payUrl); init(extPlayer); } public void setFullPlay(boolean isFullPlay) { this.isFullPlay = isFullPlay; } public boolean isFullPlay() { return isFullPlay; } public void setPosition(int currentPosition) { this.currentPosition = currentPosition; } public int getPosition() { return currentPosition; } /** * 切换播放器 * * @param extPlayer */ public void switchPlayer(ExtPlayer extPlayer) { if (extPlayer == null) { return; } if (curPlayer == extPlayer) { return; } if (videoView != null) { curPlayer = extPlayer; IMediaControl mediaControl = null; switch (curPlayer) { case Sohu: SohuTvPlayer sohuTvPlayer = new SohuTvPlayer(softContext.get()); mSohuIMediaControl = new SohuIMediaControl(sohuTvPlayer, new SohuIMediaListener()); mediaControl = mSohuIMediaControl; break; } videoView.switchPlayer(mediaControl); } } @Override public void finalize() throws Throwable { super.finalize(); } /** * 设置锚 * * @param anchor * @param activity */ public void setAnchorView(View anchor, Activity activity) { if (anchor == null || activity == null) { return; } if (this.anchorView != null) { ViewTreeObserver observerTmp = anchorView.getViewTreeObserver(); try { observerTmp.removeGlobalOnLayoutListener(mOnGlobalLayoutListener); observerTmp.removeOnScrollChangedListener(mOnScrollChangedListener); } catch (Exception e) { e.printStackTrace(); } } this.anchorView = anchor; this.activity = activity; final ViewTreeObserver observer = anchorView.getViewTreeObserver(); try { observer.addOnScrollChangedListener(mOnScrollChangedListener); observer.addOnGlobalLayoutListener(mOnGlobalLayoutListener); } catch (Exception e) { e.printStackTrace(); } Activity act = this.activity; if (act != null) { FrameLayout content = (FrameLayout) act.findViewById(android.R.id.content); if (content.getTag() != null) { return; } FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(anchorView.getMeasuredWidth(), anchorView.getMeasuredHeight()); int[] location = new int[2]; anchorView.getLocationInWindow(location); lp.leftMargin = location[0]; lp.topMargin = location[1]; content.addView(this, content.getChildCount(), lp); content.setTag(true); } } /** * 监听anchorView的Scroll变化 */ private OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() { @Override public void onScrollChanged() { updateLayout(); } }; /** * 监听anchorView的layout的变化 */ private OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { updateLayout(); } }; /** * 根据anchorView的layout更新视频显示区域 * * @return */ private boolean updateLayout() { if (getParent() == null) { return false; } if (isFullScreen) { return false; } FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); Rect lastRect = new Rect(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin + lp.height); int[] location = new int[2]; anchorView.getLocationInWindow(location); lp.leftMargin = location[0] + anchorView.getPaddingLeft(); lp.topMargin = location[1] + anchorView.getPaddingTop(); lp.width = anchorView.getMeasuredWidth() - anchorView.getPaddingLeft() - anchorView.getPaddingRight(); lp.height = anchorView.getMeasuredHeight() - anchorView.getPaddingTop() - anchorView.getPaddingBottom(); Rect newRect = new Rect(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin + lp.height); if (newRect.equals(lastRect)) { return false; } setLayoutParams(lp); return false; } /** * 设置显示选项 * * @param displayOption */ public void setDisplayOption(int displayOption) { if (mediaController == null) { return; } mediaController.setDisplayOption(displayOption); } /** * 设置不显示的控件 * * @param option */ public void setExcludeOption(int option) { if (mediaController == null) { return; } mediaController.setExcludeOption(option); } @Override protected void onAttachedToWindow() { isDetach = false; ScreenSaverModule.getInstance().updateUserActionTime(); AppUtil.addOnNetStateListener(this); super.onAttachedToWindow(); } @Override protected void onDetachedFromWindow() { setHasStart(false); isDetach = true; AppUtil.removeOnNetStateListener(this); if (videoView != null) { try { videoView.removeAllViews(); videoView.finalize(); } catch (Throwable throwable) { throwable.printStackTrace(); } } if (mediaListeners != null) { mediaListeners.clear(); } if (mediaController != null) { mediaController.clear(); mediaController.destory(); mediaController.removeAllViews(); } if (mSohuIMediaControl != null) { mSohuIMediaControl = null; } mDialogPay = null; //移除咪咕回调监听 AuthMiguModule.getInstance().removeCallBackLisenter(); if(miguCallBack != null){ miguCallBack = null; } super.onDetachedFromWindow(); } private boolean isPaused = false; /** * 当activity pause的时候调用 */ public void onPause() { } /** * 当activity resume的时候调用 */ public void onResume() { if (playerMask != null) { playerMask.refresh(); } } /** * 切换全屏 * * @return 切换后当前是否全屏状态 */ public boolean toggleFullScreen() { if (this.anchorView == null) { return false; } //2017.1.7 添加 try catch 块,用来修复 乐视压力测试中抓到的 RealativeLayout.LayoutParams can not be casted to FrameLayout.LayoutParams problem try{ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); if (!isFullScreen) { lp.leftMargin = 0; lp.topMargin = 0; lp.width = FrameLayout.LayoutParams.MATCH_PARENT; lp.height = FrameLayout.LayoutParams.MATCH_PARENT; isFullScreen = true; } else { int[] location = new int[2]; anchorView.getLocationInWindow(location); lp.leftMargin = location[0] + anchorView.getPaddingLeft(); lp.topMargin = location[1] + anchorView.getPaddingTop(); lp.width = anchorView.getMeasuredWidth() - anchorView.getPaddingLeft() - anchorView.getPaddingRight(); lp.height = anchorView.getMeasuredHeight() - anchorView.getPaddingTop() - anchorView.getPaddingBottom(); isFullScreen = false; } setLayoutParams(lp); if (isFullScreen) { requestFocus(); } else { anchorView.requestFocus(); } if (mediaController != null) { mediaController.handleFullScreen(isFullScreen); } if (playerMask != null) { playerMask.handleFullScreen(isFullScreen); } if (playerWindow != null) { playerWindow.handleFullScreen(isFullScreen); } for (OnScreenChangedListener l : scrChgListeners) { l.onScreenChanged(isFullScreen); } }catch(Exception e){ WLog.e(TAG,e.toString()); } return isFullScreen; } public void setFullScreen(boolean isFullScreen) { this.isFullScreen = isFullScreen; } public boolean isFullScreen() { return isFullScreen; } public boolean isAdPlaying() { return isAdPlaying; } /** * 忽略下次播放中的片头广告 */ public void ignoreHeadAd() { if (videoView == null) { return; } videoView.ignoreHeadAd(); } /** * 忽略下次播放中的片中广告 */ public void ignoreMidAd() { if (videoView == null) { return; } videoView.ignoreMidAd(); } /** * 忽略下次播放中的片尾广告 */ public void ignoreTailAd() { if (videoView == null) { return; } videoView.ignoreTailAd(); } /** * 忽略下次播放中的全部广告 */ public void ignoreAllAd() { if (videoView == null) { return; } videoView.ignoreHeadAd(); videoView.ignoreMidAd(); videoView.ignoreTailAd(); } public void updateParams(Map params) { if (params == null || videoView == null) { return; } videoView.updateParams(params); } /** * 停止播放,释放资源,并且从界面中移除 */ public void destory() { if (videoView != null) { stopPlayback(); if (videoView.getParent() != null && activity != null) { FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content); content.removeView(this); content.setTag(null); } } } /** * 外部价格变化通知播放器 * * @param ret * @param extra * @param retData */ public void priceChanged(int ret, String extra, Object retData) { if (ret == WError.ERROR_NONE) { PriceInfo price = (PriceInfo) retData; if (urlProperty != null) { urlProperty.setPrice(price.mPrice); } mOriginPrice = price.mOriginalPrice; if (price.mPrice > 0) { mbNeedPay = true; int preTime = Config.MAX_PREVIEW_MINUTES * 60 * 1000; if (assetSeries != null) { preTime = assetSeries.getPreviewTime() * 1000; } if (getCurrentPosition() >= preTime) { // showPayDialog(); loadUnifyPay(); } } else { mbNeedPay = false; } } else { mbNeedPay = false; if (urlProperty != null) { urlProperty.setPrice(0); } mOriginPrice = 0; if (urlProperty != null && !urlProperty.IsFree()) { stopPlayback(); } } if (playerMask != null) { playerMask.refresh(); } } private void init(ExtPlayer extPlayer) { setFocusable(true); setFocusableInTouchMode(true); mediaListeners = new CopyOnWriteArrayList(); scrChgListeners = new CopyOnWriteArrayList(); playIdxChgListener = new CopyOnWriteArrayList(); if (extPlayer == null) { videoView = new AdPlayerView(softContext.get()); } else { curPlayer = extPlayer; switch (curPlayer) { case Default: videoView = new AdPlayerView(softContext.get()); break; case Sohu: SohuTvPlayer sohuTvPlayer = new SohuTvPlayer(softContext.get()); mSohuIMediaControl = new SohuIMediaControl(sohuTvPlayer, new SohuIMediaListener()); videoView = new AdPlayerView(softContext.get(), mSohuIMediaControl); break; } } videoView.setTip(ADtip); videoView.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); addView(videoView); playerMask = new PlayerMask(softContext.get()); playerMask.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); playerMask.setPlayer(this); addView(playerMask); mediaController = new MediaController(softContext.get(), mExcludeOption); mediaController.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); mediaController.setPlayer(this, this); // mediaController.setPlayer(this); addView(mediaController); addObserver(this); addObserver(playerMask); addObserver(mediaController); } public void setPlayerWindow(int resId, LinearLayout.LayoutParams layoutParams) { FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content); content.setClipChildren(false); this.setClipChildren(false); if (playerWindow != null) { removeView(playerWindow); content.invalidate(); this.invalidate(); } playerWindow = new PlayerWindow(softContext.get(), layoutParams); RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); playerWindow.setLayoutParams(layoutParams1); playerWindow.setPalyWinViewBackgroundResource(resId); addView(playerWindow); } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_UP) { return false; } if (!isFullScreen) { return false; } if (mediaController != null && !mediaController.dispatchKeyEvent(event) && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { if (isFullPlay() || BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.DUYA_TECH)) { return false; } else { toggleFullScreen(); } } return true; } /** * 解析传入数据 * * @return */ private void checkParameters() { currentStatus = STATUS_PARSE_INTENT; if (PLAY_TYPE_NORMAL == playType && assetInfo == null && (assetUrl == null || (assetUrl != null && "".equals(assetUrl.trim())))) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "传入数据为空"); WLog.e(TAG, "传入数据为空"); return; } else if (PLAY_TYPE_LOOP == playType && assetList == null && (assetUrl == null || (assetUrl != null && "".equals(assetUrl.trim())))) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "传入数据为空"); WLog.e(TAG, "传入数据为空"); return; } else { processHandler.sendEmptyMessage(PROCESS_NEXT); } } /** * 根据assetUrl获取assetInfo */ private void fetchAssetInfo() { currentStatus = STATUS_FETCH_ASSET_INFO; switch (playType) { case PLAY_TYPE_NORMAL: { ObjectListener objectListener = new ObjectListener() { @Override public void onObjectGet(int retcode, String extraMsg, ObjectBase data) { if (retcode != WError.ERROR_NONE && errorRetryCount > 0) { DataFetchModule.getInstance().fetchObjectGet(assetUrl, DemandProgram.class, this); errorRetryCount--; return; } errorRetryCount = 3; if (retcode != 0 || data == null) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取资产数据失败"); WLog.e(TAG, "获取资产数据失败"); return; } else { assetInfo = (DemandProgram) data; if (assetInfo == null) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取资产数据失败"); WLog.e(TAG, "获取资产数据失败"); return; } if (assetInfo.getAssetType() == DemandProgram.SHOWTYPE_TV_SERIES) { DataFetchModule.getInstance().fetchObjectGet(assetInfo.getOnlineEpisodesUrl(), DetailSeriesSet.class, new ObjectListener() { @Override public void onObjectGet(int i, String s, ObjectBase objectBase) { if (i == WError.ERROR_NONE) { DetailSeriesSet mDetailSeriesSet = (DetailSeriesSet) objectBase; if (mDetailSeriesSet != null) { assetInfo.setDetailSeriesSet(mDetailSeriesSet); } } assetInfo.setDetailUrl(assetUrl); if (assetInfoBackup != null) { assetInfoBackup.copyProperties(assetInfo); for (IMediaListener l : mediaListeners) { l.onInfo(null, MSG_ASSET_CHANGED, 0); } } processHandler.sendEmptyMessage(PROCESS_NEXT); } }); } else { assetInfo.setDetailUrl(assetUrl); if (assetInfoBackup != null) { assetInfoBackup.copyProperties(assetInfo); for (IMediaListener l : mediaListeners) { l.onInfo(null, MSG_ASSET_CHANGED, 0); } } processHandler.sendEmptyMessage(PROCESS_NEXT); } } } }; WLog.i(TAG, "assetUrl=" + assetUrl); DataFetchModule.getInstance().fetchObjectGet(assetUrl, DemandProgram.class, objectListener); } break; case PLAY_TYPE_LOOP: { final ObjectListener demandProgramListener = new ObjectListener() { public void onObjectGet(int retcode, String extraMsg, ObjectBase data) { if (retcode != WError.ERROR_NONE) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取资产数据失败"); WLog.e(TAG, "获取资产数据失败"); return; } else { assetInfo = (DemandProgram) data; if (assetInfo == null) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取资产数据失败"); WLog.e(TAG, "获取资产数据失败"); return; } if (assetInfo.getAssetType() == DemandProgram.SHOWTYPE_TV_SERIES) { subPlayType = PLAY_TYPE_LOOP; DataFetchModule.getInstance().fetchObjectGet(assetInfo.getOnlineEpisodesUrl(), DetailSeriesSet.class, new ObjectListener() { @Override public void onObjectGet(int i, String s, ObjectBase objectBase) { if (i == WError.ERROR_NONE) { DetailSeriesSet mDetailSeriesSet = (DetailSeriesSet) objectBase; if (mDetailSeriesSet != null) { assetInfo.setDetailSeriesSet(mDetailSeriesSet); } } assetInfo.setDetailUrl(assetList.getJsonUrl(playIndex)); processHandler.sendEmptyMessage(PROCESS_NEXT); } }); } else { assetInfo.setDetailUrl(assetList.getJsonUrl(playIndex)); processHandler.sendEmptyMessage(PROCESS_NEXT); } } } }; final ObjectListener demandListListener = new ObjectListener() { @Override public void onObjectGet(int retcode, String extraMsg, ObjectBase data) { if (retcode != WError.ERROR_NONE) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取连播数据失败"); WLog.e(TAG, "获取连播数据失败"); return; } else { DemandList demandList = (DemandList) data; if (demandList == null || demandList.getDatum() == null) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取连播数据失败"); WLog.e(TAG, "获取连播数据失败"); return; } if (assetList == null) { assetList = demandList; String url = assetList.getJsonUrl(playIndex % PSIZE); DataFetchModule.getInstance().fetchObjectGet(url, DemandProgram.class, demandProgramListener); } else { int index = ((DemandList) assetList).getDatum().getAssets().size(); assetList.append(demandList); String url = assetList.getJsonUrl(index); DataFetchModule.getInstance().fetchObjectGet(url, DemandProgram.class, demandProgramListener); } if (mediaController != null && mediaController.getPlayerParams() != null) { mediaController.getPlayerParams().setAssetList(assetList); } } } }; if (assetInfo != null) { if (assetInfo.getAssetType() == DemandProgram.SHOWTYPE_TV_SERIES) { subPlayType = PLAY_TYPE_LOOP; } else { subPlayType = PLAY_TYPE_NORMAL; } processHandler.sendEmptyMessage(PROCESS_NEXT); return; } if (assetList != null) { String url = assetList.getJsonUrl(playIndex); if (TextUtils.isEmpty(url)) { String pageUrl = Uri.parse(assetUrl.replaceAll("&page=[\\d]*", "").replaceAll("&psize=[\\d]*", "")).buildUpon().appendQueryParameter("page", String.valueOf(playIndex / PSIZE + 1)).appendQueryParameter("psize", String.valueOf(PSIZE)).build().toString(); DataFetchModule.getInstance().fetchObjectGet(pageUrl, DemandList.class, demandListListener); } else { DataFetchModule.getInstance().fetchObjectGet(url, DemandProgram.class, demandProgramListener); } } else { String pageUrl = Uri.parse(assetUrl.replaceAll("&page=[\\d]*", "").replaceAll("&psize=[\\d]*", "")).buildUpon().appendQueryParameter("page", String.valueOf(playIndex / PSIZE + 1)).appendQueryParameter("psize", String.valueOf(PSIZE)).build().toString(); DataFetchModule.getInstance().fetchObjectGet(pageUrl, DemandList.class, demandListListener); } } break; } } /** * 询价 */ private void queryPrice() { currentStatus = STATUS_QUERY_PRICE; if (assetInfo == null) { processHandler.sendEmptyMessage(PROCESS_NEXT); return; } urlProperty = new UrlProperty(); if (BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.LETV_MARKET)) { urlProperty.setPreferPlayer(PreferPlayer.IJK); } else { if (TextUtils.equals(Build.MODEL, "B-303")) { WLog.d(TAG, "change player system"); urlProperty.setPreferPlayer(PreferPlayer.SYSTEM); } else { urlProperty.setPreferPlayer(PreferPlayer.DEFAULT); } } urlProperty.setResourceId(assetInfo.getId()); urlProperty.setResourceName(assetInfo.getTitle()); urlProperty.setNodeId(assetInfo.getCatId()); urlProperty.setPpvPath(assetInfo.getPpv()); urlProperty.setIsFree(assetInfo.getIsFree() == 1); final AuthListener queryPriceListener = new AuthListener() { @Override public void result(int ret, String extra, Object retData) { if (ret == WError.ERROR_NONE) { PriceInfo price = (PriceInfo) retData; urlProperty.setPrice(price.mPrice); mOriginPrice = price.mOriginalPrice; if (price.mPrice > 0) { mbNeedPay = true; int preTime = Config.MAX_PREVIEW_MINUTES * 60 * 1000; if (assetSeries != null) { preTime = assetSeries.getPreviewTime() * 1000; } // 预览时间 postOnWasuPlayLimit(IMediaListener.WASU_PLAY_IN_PREVIEW, String.valueOf(preTime)); } else { mbNeedPay = false; postOnWasuPlayLimit(IMediaListener.WASU_PLAY_FREE, "-1"); } } else { WLog.e(TAG, "询价失败: ret=" + ret + ";msg=" + extra); mbNeedPay = false; urlProperty.setPrice(0); mOriginPrice = 0; if (!urlProperty.IsFree()) { postOnWasuError(IMediaListener.WASU_ERROR_QUERY_PRICE, extra); return; } } processHandler.sendEmptyMessage(PROCESS_NEXT); } }; if (TextUtils.isEmpty(urlProperty.getResourceId())) { urlProperty.setIsFree(true); processHandler.sendEmptyMessage(PROCESS_NEXT); } else { Map params = new HashMap(); params.put("resourceId", urlProperty.getResourceId()); params.put("resourceName", urlProperty.getResourceName()); params.put("orderType", 0); AuthSDK.getInstance().queryPrice(params, queryPriceListener); } } /** * 调整默认播放码率 * 一.普通栏目资产 * a.会员登录情况下,查询是否VIP会员(调用是否免广告接口,免广告的为VIP会员): *

* (1)VIP会员:默认播放高清码率(1.3M),如果没有高清,则默认播放码率取低一级;如果高清及高清码率以下都没有,则取高一级码率(比如,只有超清,4K,则默认取超清播放) * (2)普通会员:默认播放清晰码率(0.8M),如果没有清晰,默认取低一级码率;如果清晰以下都没有,则默认顺序取高一级码率 *

* b.会员未登陆情况下: * (1.)单点收费资产(只判断原价price>0)的情况,默认播放高清码率,默认取低一级码率;若高清及以下码率都为空,默认取高一级码率 * (2)免费资产(原价price=0),默认播放0.8M码率 *

* 二、特殊栏目资产(如4K和蓝光等高码率资产,播放相对应码流3.8M/6M) */ private void adjustPlayBitrate() { currentStatus = STATUS_ADJUST_PLAY_BITRATE; if (assetInfo == null) { processHandler.sendEmptyMessage(PROCESS_NEXT); return; } switch (assetInfo.getCatProp()) { case DemandProgram.CAT_PROP_BD: DEFAULT_PLAY_RATE = PLAY_RATE_BD; urlProperty.setBitrate((int) getFitRate()); processHandler.sendEmptyMessage(PROCESS_NEXT); break; case DemandProgram.CAT_PROP_4K: DEFAULT_PLAY_RATE = PLAY_RATE_4K; urlProperty.setBitrate((int) getFitRate()); processHandler.sendEmptyMessage(PROCESS_NEXT); break; default: { String userKey = AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY); if (TextUtils.isEmpty(userKey)) { if (mOriginPrice > 0) { DEFAULT_PLAY_RATE = PLAY_RATE_NORMAL_H; } else if (mOriginPrice == 0) { DEFAULT_PLAY_RATE = PLAY_RATE_NORMAL_L; } else { // } urlProperty.setBitrate((int) getFitRate()); processHandler.sendEmptyMessage(PROCESS_NEXT); } else { AuthSDK.getInstance().verifyUserIsAdFree(new AuthListener() { @Override public void result(int ret, String extra, Object retData) { if (ret == WError.ERROR_NONE) { try { JSONObject root = new JSONObject(new String((byte[]) retData, "utf-8")); boolean isAdFree = root.optInt("isFree") == 1; if (isAdFree) { DEFAULT_PLAY_RATE = PLAY_RATE_NORMAL_H; } } catch (Exception e) { e.printStackTrace(); } } urlProperty.setBitrate((int) getFitRate()); processHandler.sendEmptyMessage(PROCESS_NEXT); } }); } } break; } } /** * 查询播放历史记录 */ private void queryHistory() { currentStatus = STATUS_QUERY_HISTORY; // if (BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.DUYA_TECH)) { // return; // } // getContext().getSharedPreferences(MediaController.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).edit().putLong(MediaController.SHARED_PREFERENCES_KEY_CURRENT_RATE, DEFAULT_PLAY_RATE).commit(); if (assetInfo == null) { assetHistory = new DBProgramHistory(); assetHistory.domain = BuildType.HTTP_DOMAIN; processHandler.sendEmptyMessage(PROCESS_NEXT); return; } try { assetHistory = DBManage.queryBy(DBProgramHistory.class, "programId", assetInfo.getId()); assetHistory.domain = BuildType.HTTP_DOMAIN; } catch (Exception e) { WLog.e(TAG, "查询历史记录出错"); e.printStackTrace(); assetHistory = new DBProgramHistory(); assetHistory.domain = BuildType.HTTP_DOMAIN; } if (subPlayType == PLAY_TYPE_LOOP && assetInfo.getCurPlayIndex() == 0) { assetInfo.setCurPlayIndex(assetHistory.lastSeries); } if (playType == PLAY_TYPE_LOOP && playIdxChgListener != null) { for (OnPlayIndexChangedListener l : playIdxChgListener) { l.onPlayIndexChanged(playIndex, assetInfo.getCurPlayIndex(), assetInfo.getSeriesCount()); } } //电视剧剧集是分页的,默认只取一页30集,如果历史记录超过30集,需要重新获取历史记录的那一页数据 if (assetHistory != null && assetHistory.lastSeries >= 30) { int page = assetHistory.lastSeries / 30 + 1; String url = new StringBuilder(assetInfo.getDetailUrl()).append("&page=").append(page).append("&psize=30").toString(); DataFetchModule.getInstance().fetchObjectGet(url, DemandProgram.class, new ObjectListener() { @Override public void onObjectGet(int retcode, String extraMsg, ObjectBase data) { if (retcode != WError.ERROR_NONE) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "获取对应的剧集出错"); WLog.e(TAG, "获取对应的剧集出错"); return; } assetInfo.addPlaySeriesInfo((DemandProgram) data); processHandler.sendEmptyMessage(PROCESS_NEXT); } }); } else { processHandler.sendEmptyMessage(PROCESS_NEXT); } } /** * 播放鉴权 */ private void playAuth() { currentStatus = STATUS_PLAY_AUTH; if (assetInfo == null) { processHandler.sendEmptyMessage(PROCESS_NEXT); return; } Map params = new HashMap(); params.put("resourceId", assetInfo.getId()); params.put("ip", Tools.getLocalIpAddress()); params.put("offSet", assetHistory.lastPlayTime); params.put("price", assetInfo.getPriceInfo().getPrice()); params.put("resourceName", assetInfo.getTitle()); if (DemandProgram.SHOWTYPE_MOVIE == assetInfo.getAssetType()) { params.put("type", 0); } else if (DemandProgram.SHOWTYPE_TV_SERIES == assetInfo.getAssetType()) { params.put("type", 1); } else { params.put("type", 2); } params.put("categoryId", assetInfo.getCatId()); AuthSDK.getInstance().playVideoCount(params, new AuthListener() { @Override public void result(int arg0, String arg1, Object arg2) { WLog.e(TAG, "video play count:" + arg0 + "," + arg1); } }); /** * 搜狐资产需要搜狐播放器鉴权 * * 1.判断资产是否免费 * 2.如果是免费,不需要鉴权,直接播放 * 3.如果是收费,判断用户是否登录 * 4.用户未登录则引导用户登录 * 5.用户登录成功后询价并鉴权,如果免费影片直接播放,收费影片引导订包,订包成功后播放,否则停止播放 * 6.用户登录失败,停止播放 */ if (assetInfo != null && assetInfo.getAssetFrom() == 91) { if (urlProperty.getPrice() == 0 && mOriginPrice != 99999) { processHandler.sendEmptyMessage(PROCESS_NEXT); } else { String userKey = AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY); SohuTvPlayer sohuTvPlayer = (SohuTvPlayer) videoView.getMediaControl(); sohuTvPlayer.setProviderAppKey(Common.sohuAppKey); sohuTvPlayer.setUid(userKey); sohuTvPlayer.setMobile(""); processHandler.sendEmptyMessage(PROCESS_NEXT); } } else { processHandler.sendEmptyMessage(PROCESS_NEXT); } } /** * 开始播放 */ private void play() { currentStatus = STATUS_DONE; softContext.get().getSharedPreferences(MediaController.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).edit().putLong(MediaController.SHARED_PREFERENCES_KEY_CURRENT_RATE, DEFAULT_PLAY_RATE).commit(); if (assetInfo != null && assetInfo.getAssetFrom() == 93) { getFitPlayUrl();//不能去掉,否则加载过长时会有问题 WLog.i(TAG, "migu program id=" + assetSeries.getOttVodId()); AuthMiguModule.getInstance().getPlayUrl(assetSeries.getOttVodId(), miguCallBack); } else { String url = getFitPlayUrl(); play2(url); } } /** * 咪咕视频流获取回调 */ AuthMiguModule.AuthMiguCallBack miguCallBack = new AuthMiguModule.AuthMiguCallBack() { @Override public void result(String resultcode, String desc, String playUrl) { WLog.i(TAG, "resultcode=" + resultcode + ",desc=" + desc + ",playUrl=" + playUrl); if (resultcode.equals("0")) { play2(playUrl); } else { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, desc); } } }; /** * 根据默认码率和集数获取加密播放串 * * @return */ private String getFitPlayUrl() { if (assetInfo == null || assetInfo.getPlayinfoList().size() == 0) { return null; } int playIndex = assetInfo.getCurPlayIndex(); if (playIndex <= 0) { playIndex = 1; assetInfo.setCurPlayIndex(1); } long fitRate = getFitRate(); DemandPlayinfo playInfo = assetInfo.getPlayinfoList().get(fitRate); if (playInfo == null) {//向下寻找 long minRate = getMinRate(); long closedRate = getClosedFitRate(fitRate, false); int loopcnt = 0; while (closedRate >= minRate && loopcnt < MAX_LOOP_CNT) { playInfo = assetInfo.getPlayinfoList().get(closedRate); if (playInfo != null) { fitRate = closedRate; break; } else { closedRate = getClosedFitRate(closedRate, false); } loopcnt++; } } if (playInfo == null) {//向上寻找 long maxRate = getMaxRate(); long closedRate = getClosedFitRate(fitRate, true); int loopcnt = 0; while (closedRate <= maxRate && loopcnt < MAX_LOOP_CNT) { playInfo = assetInfo.getPlayinfoList().get(closedRate); if (playInfo != null) { fitRate = closedRate; break; } else { closedRate = getClosedFitRate(closedRate, true); } loopcnt++; } } if (playInfo == null) { return null; } DemandSeries seriesInfo = null; List series = playInfo.getSeriesList(); for (DemandSeries o : series) { if (o.getEpisode() == playIndex) { seriesInfo = o; break; } } if (seriesInfo == null) {//向下寻找 long minRate = getMinRate(); long closedRate = getClosedFitRate(fitRate, false); int loopcnt = 0; while (closedRate >= minRate && loopcnt < MAX_LOOP_CNT) { playInfo = assetInfo.getPlayinfoList().get(closedRate); if (playInfo != null) { List l = playInfo.getSeriesList(); for (DemandSeries o : l) { if (o.getEpisode() == playIndex) { seriesInfo = o; break; } } if (seriesInfo != null) { fitRate = closedRate; break; } else { if (closedRate == minRate) { break; } closedRate = getClosedFitRate(closedRate, false); } } else { if (closedRate == minRate) { break; } closedRate = getClosedFitRate(closedRate, false); } loopcnt++; } } if (seriesInfo == null) {//向上寻找 long maxRate = getMaxRate(); long closedRate = getClosedFitRate(fitRate, true); int loopcnt = 0; while (closedRate <= maxRate && loopcnt < MAX_LOOP_CNT) { playInfo = assetInfo.getPlayinfoList().get(closedRate); if (playInfo != null) { List l = playInfo.getSeriesList(); for (DemandSeries o : l) { if (o.getEpisode() == playIndex) { seriesInfo = o; break; } } if (seriesInfo != null) { fitRate = closedRate; break; } else { if (closedRate == maxRate) { break; } closedRate = getClosedFitRate(closedRate, true); } } else { if (closedRate == maxRate) { break; } closedRate = getClosedFitRate(closedRate, true); } loopcnt++; } } if (seriesInfo == null && series.size() != 0) { seriesInfo = series.get(0); if (seriesInfo != null) { assetInfo.setCurPlayIndex(seriesInfo.getEpisode()); } } assetSeries = seriesInfo; if (seriesInfo == null) { return null; } softContext.get().getSharedPreferences(MediaController.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).edit().putLong(MediaController.SHARED_PREFERENCES_KEY_CURRENT_RATE, playInfo.getRate()).commit(); return seriesInfo.getEncryUrl(); } /** * 根据默认码率/用户选择的码率,选择当前最接近的码率 * * @return */ private long getFitRate() { if (assetInfo == null) { return DEFAULT_PLAY_RATE; } if (assetInfo.getPlayinfoList().get(bitrate) != null) { return bitrate; } long defaultRate = softContext.get().getSharedPreferences(MediaController.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).getLong(MediaController.SHARED_PREFERENCES_KEY_CURRENT_RATE, DEFAULT_PLAY_RATE); if (assetInfo.getPlayinfoList().get(defaultRate) != null) { return defaultRate; } long fitRate = defaultRate; long absRate = Long.MAX_VALUE; Set> entrySet = assetInfo.getPlayinfoList().entrySet(); for (Entry entry : entrySet) { long tmpRate = entry.getKey(); if (Math.abs(defaultRate - tmpRate) <= absRate) { fitRate = tmpRate; absRate = Math.abs(defaultRate - tmpRate); } } return fitRate; } /** * 寻找比当前码率最接近的码率,若没有找到,返回原来的码率 * * @param fitRate * @param direction true,向上寻找,false,向下寻找 * @return */ private long getClosedFitRate(long fitRate, boolean direction) { long closedFitRate = fitRate; long absRate = Long.MAX_VALUE; Set> entrySet = assetInfo.getPlayinfoList().entrySet(); for (Entry entry : entrySet) { long tmpRate = entry.getKey(); if (direction) { if (tmpRate <= fitRate) { continue; } } else { if (tmpRate >= fitRate) { continue; } } if (Math.abs(fitRate - tmpRate) <= absRate) { closedFitRate = tmpRate; absRate = Math.abs(fitRate - tmpRate); } } return closedFitRate; } /** * 寻找最大码率 * * @return */ private long getMaxRate() { long ret = -1L; if (assetInfo == null || assetInfo.getPlayinfoList() == null || assetInfo.getPlayinfoList().entrySet() == null) { return ret; } Set> entrySet = assetInfo.getPlayinfoList().entrySet(); for (Entry entry : entrySet) { long tmpRate = entry.getKey(); if (ret == -1L) { ret = tmpRate; continue; } if (ret > tmpRate) { continue; } ret = tmpRate; } return ret; } /** * 寻找最小码率 * * @return */ private long getMinRate() { long ret = -1L; if (assetInfo == null || assetInfo.getPlayinfoList() == null || assetInfo.getPlayinfoList().entrySet() == null) { return ret; } Set> entrySet = assetInfo.getPlayinfoList().entrySet(); for (Entry entry : entrySet) { long tmpRate = entry.getKey(); if (ret == -1L) { ret = tmpRate; continue; } if (ret < tmpRate) { continue; } ret = tmpRate; } return ret; } /** * 保存播放历史记录 */ private void saveHistory(int currDuration, int duration) { //Add By Frewen.Wong 渡鸦科技不保存播放历史 if (BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.DUYA_TECH)) { return; } if (mediaController == null || currDuration == 0 || duration == 0 || duration == -1) { return; } if (assetInfo == null) { return; } try { assetHistory.programId = Integer.parseInt(assetInfo.getId()); assetHistory.programPic = assetInfo.getPicUrl(); assetHistory.programName = assetInfo.getTitle(); assetHistory.domain = domain; assetHistory.showType = assetInfo.getAssetType(); assetHistory.lastPlayTime = currDuration; assetHistory.duration = duration; assetHistory.lastSeries = assetInfo.getCurPlayIndex(); assetHistory.totalSeries = assetInfo.getTotal(); assetHistory.updateSeries = assetInfo.getFirstPlayinfo().getSeriesList().size(); assetHistory.preUpdateSeries = assetHistory.updateSeries; if (TextUtils.isEmpty(assetInfo.getDetailUrl())) {//优先保存单个资产的url assetHistory.detailUrl = assetUrl; } else { assetHistory.detailUrl = assetInfo.getDetailUrl(); } assetHistory.playUrl = getFitPlayUrl(); assetHistory.savehistorytime = System.currentTimeMillis(); FavAndHisModule.getInstance().saveHistory(assetHistory); } catch (Exception e) { WLog.e(TAG, "保存历史记录失败"); e.printStackTrace(); } } /** * 退出播放 * * @param msg */ private void exit(String msg) { if (isFullScreen) { toggleFullScreen(); } if (anchorView != null) { Toast.makeText(softContext.get(), msg, Toast.LENGTH_SHORT).show(); } playerMask.showVideoLoadingPic(); saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); if (mediaController != null) { mediaController.hideCurrentView(); mediaController.clear(); } } private boolean hasStart = false; public boolean isHasStart() { return hasStart; } public void setHasStart(boolean hasStart) { this.hasStart = hasStart; } // //////////////////////////////////IMediaControl////////////////////////////////////////////// public void play(PlayerParams playerParams) { setHasStart(true); this.assetInfo = playerParams.getAssetInfo(); if (this.assetInfo != null) { assetInfoBackup = this.assetInfo; } this.assetUrl = playerParams.getAssetUrl(); this.playType = playerParams.getPlayType(); this.playIndex = playerParams.getPlayIndex(); this.assetList = playerParams.getAssetList(); this.bitrate = playerParams.getBitrate(); this.domain = playerParams.getDomain(); assetSeries = null; if (mediaController != null) { mediaController.hideCurrentView(); mediaController.clear(); mediaController.setPlayerParams(playerParams); } reSetSohuTag(); if (isFullScreen && anchorView != null) { requestFocus(); } isLastSeriesFinish = false; if (playerMask != null) { playerMask.isLastSeriesFinish(isLastSeriesFinish); } currentStatus = STATUS_INIT; processHandler.sendEmptyMessage(PROCESS_NEXT); } @Override public void setVideoPath(String path, UrlProperty property) throws IllegalArgumentException { if (mediaController != null) { mediaController.hideCurrentView(); mediaController.clear(); } if (isFullScreen && anchorView != null) { requestFocus(); } if (mediaController != null) { mediaController.handleFullScreen(isFullScreen); } if (playerMask != null) { playerMask.handleFullScreen(isFullScreen); } if (playerWindow != null) { playerWindow.handleFullScreen(isFullScreen); } if (TextUtils.isEmpty(path)) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "播放地址为空"); WLog.e(TAG, "播放地址为空"); return; } urlProperty = property; try { //区分大小写比较 if (path.regionMatches(true, 0, "http", 0, "http".length()) || path.regionMatches(true, 0, "multisource", 0, "multisource".length()) || path.regionMatches(true, 0, "file", 0, "file".length())) { mRealUrl = path.trim(); } else { mRealUrl = DecryptUtil.decrypt(softContext.get(), 1, path); // 如果是搜狐资产并且存在抢先看 if (assetInfo.getAssetFrom() == 91 && !"".equals(assetInfo.getOttEarly())) { mRealUrl = mRealUrl.replace("}", ""); String isVipT = ",\"isSohuVip\":\"true\"}"; String isVipF = ",\"isSohuVip\":\"false\"}"; if (assetInfo.getTotal() == 1) { // 电影 //搜狐电影暂时没有抢先看 mRealUrl += "}"; WLog.e(TAG, "mRealUrl 电影 " + mRealUrl); // if ("1".equals(assetInfo.getOttIsFree())){ // 是抢先看 // mRealUrl +=isVipT; //// WLog.e(TAG,"mRealUrl 电影T "+mRealUrl); // doLoginOrPay(); // }else { // mRealUrl+=isVipF; //// WLog.e(TAG,"mRealUrl 电影F "+mRealUrl); // } } else { // 多集资产,电视剧等 if ("1".equals(assetSeries.getOttItemFee())) { //电视剧抢先看 mRealUrl += isVipT; // WLog.e(TAG,"mRealUrl 电视剧T "+mRealUrl); // doLoginOrPay(); loadUnifyPay(); } else { mRealUrl += isVipF; // WLog.e(TAG,"mRealUrl 电视剧F "+mRealUrl); } } } } } catch (Exception e) { e.printStackTrace(); } //Log.i(TAG, "setVideoPath: mRealUrl====="+mRealUrl); if (TextUtils.isEmpty(mRealUrl)) { postOnWasuError(IMediaListener.WASU_ERROR_PLAYER, "播放地址解析失败"); WLog.e(TAG, "播放地址解析失败"); return; } openVideo(); } @Override public void setVideoClips(int startTime, int endTime) { videoView.setVideoClips(startTime, endTime); } @Override public void start() { videoView.start(); } @Override public void resume(String url) { try { if (url == null || url.regionMatches(true, 0, "http", 0, "http".length()) || url.regionMatches(true, 0, "multisource", 0, "multisource".length()) || url.regionMatches(true, 0, "file", 0, "file".length())) { mRealUrl = url; } else { if (assetInfo.getAssetFrom() != 91) { mRealUrl = DecryptUtil.decrypt(softContext.get(), 1, url); mRealUrl = DecryptUtil.fetchCdnUrl(softContext.get(), mRealUrl, AuthSDK.getInstance().getValue(IAuthInterface.KEY_TVID), "tv_4_0"); } else { mRealUrl = url; } } } catch (Exception e) { e.printStackTrace(); } if (TextUtils.isEmpty(mRealUrl)) { throw new IllegalArgumentException("url can't decode"); } videoView.resume(mRealUrl); } @Override public void pause() { videoView.pause(); } @Override public void suspend() { isAdPlaying = false; mediaController.setAdPlaying(false); videoView.suspend(); mediaController.setReady(false); } @Override public void seekTo(int msec) { videoView.seekTo(msec); } @Override public void stopPlayback() { isAdPlaying = false; mediaController.setAdPlaying(false); mRealUrl = null; videoView.stopPlayback(); } @Override public void stopPlayback(boolean clearAdStatus) { isAdPlaying = false; mediaController.setAdPlaying(false); mRealUrl = null; videoView.stopPlayback(clearAdStatus); } @Override public int getDuration() { return videoView.getDuration(); } @Override public int getCurrentPosition() { return videoView.getCurrentPosition(); } @Override public int getCurrentADPosition() { return videoView.getCurrentADPosition(); } @Override public int getCurrentADDuration() { return videoView.getCurrentADDuration(); } @Override public boolean isPlaying() { return videoView.isPlaying(); } @Override public boolean isPreparing() { return mediaController.isReady() ? videoView.isPreparing() : false; } @Override public void setPlayType(PlayType type) { videoView.setPlayType(type); } @Override public int getVideoWidth() { return videoView.getVideoWidth(); } @Override public int getVideoHeight() { return videoView.getVideoHeight(); } @Override public boolean isInPlaybackState() { return videoView.isInPlaybackState(); } @Override public View getMediaControl() { return videoView.getMediaControl(); } @Override public void addObserver(IMediaListener listener) { videoView.addObserver(listener); if (mediaListeners == null) { return; } if (!mediaListeners.contains(listener)) { mediaListeners.add(listener); } } @Override public void removeObserver(IMediaListener listener) { videoView.removeObserver(listener); if (mediaListeners == null) { return; } if (mediaListeners.contains(listener)) { mediaListeners.remove(listener); } } @Override public void setInterceptListener(IMediaInterceptListener listener) { } @Override public void postOnStart() { } @Override public void postOnPreparing() { } @Override public void postOnPrepareComplete() { } @Override public void postOnSeeking() { } @Override public void postOnSeekcomplete() { } @Override public void postOnPause() { } @Override public void postOnResume() { } @Override public void postOnStop() { } @Override public void postOnCompletion() { } @Override public void postOnError(int i, int i1) { } @Override public void postOnInfo(int i, int i1) { } public void addOnScreenChangedListener(OnScreenChangedListener l) { if (scrChgListeners == null) { return; } scrChgListeners.add(l); } public void removeOnScreenChangedListener(OnScreenChangedListener l) { if (scrChgListeners == null) { return; } scrChgListeners.remove(l); } public void addOnPlayIndexChangedListener(OnPlayIndexChangedListener l) { if (playIdxChgListener == null) { return; } playIdxChgListener.add(l); } public void removeOnPlayIndexChangedListener(OnPlayIndexChangedListener l) { if (playIdxChgListener == null) { return; } playIdxChgListener.remove(l); } // //////////////////////////////////IMediaControl////////////////////////////////////////////// // //////////////////////////////////IMediaListener//////////////////////////////////// @Override public void onStart(MediaPlayer mp) { StartTimer(); } @Override public void onPreparing(MediaPlayer mp) { } @Override public void onPrepareComplete(MediaPlayer mp) { // 提示用户历史记录时间点 if (isShowSeekMsg && assetHistory.lastSeries == assetInfo.getCurPlayIndex() && assetHistory.duration - assetHistory.lastPlayTime > 10000) { int totalSeconds = (int) ((int) assetHistory.lastPlayTime / 1000.f); int seconds = (int) (totalSeconds % 60.f); int minutes = (int) ((totalSeconds / 60.f) % 60.f); int hours = (int) (totalSeconds / 3600.f); StringBuilder sb = new StringBuilder(); Formatter ft = new Formatter(sb, Locale.getDefault()); String timeStr = ""; sb.setLength(0); if (hours > 0) { timeStr = ft.format("%d:%02d:%02d", hours, minutes, seconds).toString(); } else { timeStr = ft.format("%02d:%02d", minutes, seconds).toString(); } Toast.makeText(softContext.get(), "已从上次退出的时间点" + timeStr + "开始播放", Toast.LENGTH_SHORT).show(); isShowSeekMsg = false; ft.close(); } int position = getPosition(); if(position > 0 && position > getCurrentPosition()) { videoView.seekTo(position); } mediaController.setReady(true); saveHistory(0, getDuration()); } @Override public void onSeeking(MediaPlayer mp) { } @Override public void onSeekComplete(MediaPlayer mp) { } @Override public void onProgress(int position, int duration, int buffingPercent) { ScreenSaverModule.getInstance().updateUserActionTime(); if (mbNeedPay && assetSeries != null && position >= assetSeries.getPreviewTime() * 1000) { if (videoView != null) { posWhenPay = videoView.getCurrentPosition(); } if (assetInfo != null) { loadUnifyPay(); } // if (assetInfo != null && assetInfo.getAssetFrom() == 91 && urlProperty.getPrice() == 99999) { // String userKey = AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY); // if (TextUtils.isEmpty(userKey)) { // // if (mDialogLogin != null && mDialogLogin.isShowing()){ // mDialogLogin.dismiss(); // } // mDialogLogin = new WasuCompFactory().createUniLogin(getContext(), BuildType.loginurl); // mDialogLogin.setLoginStatusListener(new DialogLogin.LoginStatusListener() { // @Override // public void onLogStatus(boolean b) { // if (b) { // Map params = new HashMap(); // params.put("resourceId", urlProperty.getResourceId()); // params.put("resourceName", urlProperty.getResourceName()); // params.put("orderType", 0); // // AuthSDK.getInstance().queryPrice(params, new AuthListener() { // @Override // public void result(int ret, String extra, Object retData) { // if (ret == WError.ERROR_NONE) { // PriceInfo price = (PriceInfo) retData; // urlProperty.setPrice(price.mPrice); // mOriginPrice = price.mOriginalPrice; // // if (price.mPrice > 0) { // mbNeedPay = true; // } else { // mbNeedPay = false; // postOnWasuPlayLimit(IMediaListener.WASU_PLAY_FREE, "-1"); // } // } // /**免费或收费都需要鉴权**/ // SohuTvPlayer sohuTvPlayer = (SohuTvPlayer) videoView.getMediaControl(); // sohuTvPlayer.setProviderAppKey(Common.sohuAppKey); // sohuTvPlayer.setUid(AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY)); // sohuTvPlayer.setMobile(""); // if (urlProperty.getPrice() == 0) { // reSetSohuTag(); // videoView.setVideoPath(mRealUrl, urlProperty); // seekTo(posWhenPay); // } else { // showPayDialog(); // } // } // }); // } else { // postOnWasuError(IMediaListener.WASU_ERROR_AUTH, "用户登录失败"); // if (isFullScreen()) { // toggleFullScreen(); // stopPlayback(); // } // } // } // }); // suspend(); // mDialogLogin.show(); // } else { // suspend(); // showPayDialog(); // } // } else { // showPayDialog(); // } // suspend(); } } /** * 统一的询价 */ private AuthListener authListener = new AuthListener() { @Override public void result(int ret, String extra, Object retData) { if (ret == WError.ERROR_NONE) { PriceInfo price = (PriceInfo) retData; urlProperty.setPrice(price.mPrice); mOriginPrice = price.mOriginalPrice; if (price.mPrice > 0) { mbNeedPay = true; } else { mbNeedPay = false; postOnWasuPlayLimit(IMediaListener.WASU_PLAY_FREE, "-1"); } /** * 飞狐资产需要设定播放器 * */ int payType = WasuPlayerViewPayUtil.getInstance().checkPayType(urlProperty.getPrice(), assetInfo.getAssetFrom()); if (payType == WasuPlayerViewPayUtil.PAYTYPE_PACKAGE_FEIHU) { /** sohu - 免费或收费都需要鉴权**/ SohuTvPlayer sohuTvPlayer = (SohuTvPlayer) videoView.getMediaControl(); sohuTvPlayer.setProviderAppKey(Common.sohuAppKey); sohuTvPlayer.setUid(AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY)); sohuTvPlayer.setMobile(""); } /** * 付费成功直接继续播放 * */ if (urlProperty.getPrice() == 0) { reSetSohuTag(); resume(mRealUrl); } else { loadUnifyPay(); } } else { // 询价有误时 mbNeedPay = true; postOnWasuError(IMediaListener.WASU_ERROR_PAY, null); stopPlayback(); if (isFullScreen) { toggleFullScreen(); } else { if (anchorView != null) { anchorView.requestFocus(); } } return; } } }; /** * 统一的支付回调 */ private PayStatusListener payListener = new PayStatusListener() { @Override public void onPay(int payStatus, int code) { int preTime = Config.MAX_PREVIEW_MINUTES * 60 * 1000; if (assetSeries != null) { preTime = assetSeries.getPreviewTime() * 1000; } if (payStatus == 0) { if (!TextUtils.isEmpty(mRealUrl)) { resume(mRealUrl); } //支付成功后,再次询价确保真正支付成功 try { WasuPlayerViewPayUtil.getInstance().checkPriceFromServere(urlProperty.getResourceId(), urlProperty.getResourceName(), new AuthListener() { @Override public void result(int ret, String extra, Object retData) { if (ret != WError.ERROR_NONE) { mbNeedPay = true; postOnWasuError(IMediaListener.WASU_ERROR_PAY, null); stopPlayback(); //Add By Frewen.Wong 渡鸦科技支付失败直接退出应用 if (BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.DUYA_TECH)) { ((ActivityDetail) activity).exitApp(); return; } if (isFullScreen) { toggleFullScreen(); } else { if (anchorView != null) { anchorView.requestFocus(); } } return; } PriceInfo price = (PriceInfo) retData; urlProperty.setPrice(price.mPrice); mOriginPrice = price.mOriginalPrice; if (price.mPrice > 0) {//支付成功后询价仍然不免费,说明支付失败. mbNeedPay = true; postOnWasuError(IMediaListener.WASU_ERROR_PAY, null); stopPlayback(); //Add By Frewen.Wong 渡鸦科技支付失败直接退出应用 if (BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.DUYA_TECH)) { ((ActivityDetail) activity).exitApp(); return; } if (isFullScreen) { toggleFullScreen(); } else { if (anchorView != null) { anchorView.requestFocus(); } } } else { reSetSohuTag(); mbNeedPay = false; postOnWasuPlayLimit(IMediaListener.WASU_PLAY_FREE, "-1"); } } }); //<<<<<<< HEAD // suspend(); // mDialogLogin.show(); // } else { // suspend(); // showPayDialog(); //======= } catch (IllegalStateException e) { e.printStackTrace(); mbNeedPay = true; postOnWasuError(IMediaListener.WASU_ERROR_PAY, null); stopPlayback(); //>>>>>>> prototype_release } } else { mbNeedPay = true; if (posWhenPay < preTime && !(assetInfo.getAssetFrom() == 91 && "1".equals(assetSeries.getOttItemFee()))) { postOnWasuPlayLimit(IMediaListener.WASU_PLAY_IN_PREVIEW, String.valueOf(preTime)); if (!TextUtils.isEmpty(mRealUrl)) { resume(mRealUrl); } } else { postOnWasuError(IMediaListener.WASU_ERROR_PAY, "支付失败"); isPayFail = true; stopPlayback(); mediaController.hideBufferView(); } if (isFullScreen) { toggleFullScreen(); } else { if (anchorView != null) { anchorView.requestFocus(); } } } } }; /** * 统一的登录回调 */ private DialogLogin.LoginStatusListener loginStatusListener = new DialogLogin.LoginStatusListener() { @Override public void onLogStatus(boolean b) { if (b) { // 登陆成功 // 再次询价检测用户是否是vip WasuPlayerViewPayUtil.getInstance().checkPriceFromServere(urlProperty.getResourceId(), urlProperty.getResourceName(), authListener); } else { Toast.makeText(softContext.get(), "用户登录失败", Toast.LENGTH_SHORT).show(); postOnWasuError(IMediaListener.WASU_ERROR_AUTH, "用户登录失败"); if (isFullScreen()) { toggleFullScreen(); } stopPlayback(); // 强制关闭播放 } } }; /** * 调起统一支付 */ private void loadUnifyPay() { /** * 检测用户是否需要付费(飞狐抢先看 * */ if (assetInfo.getAssetFrom() == 91 && urlProperty.getPrice() == 0) { videoView.setVideoPath(mRealUrl, urlProperty); } else { suspend(); // 停止播放器 int type = WasuPlayerViewPayUtil.getInstance().checkPayType(urlProperty.getPrice(), assetInfo.getAssetFrom()); switch (type) { case WasuPlayerViewPayUtil.PAYTYPE_SINGLE_WASU: WasuPlayerViewPayUtil.getInstance().WasuSinglePay(mDialogPay, urlProperty.getResourceName(), urlProperty.getResourceId(), urlProperty.getPrice(), payListener); break; case WasuPlayerViewPayUtil.PAYTYPE_PACKAGE_WASU: if (WasuPlayerViewPayUtil.getInstance().checkLogin()) { WasuPlayerViewPayUtil.getInstance().BookWasuMonthPackage(mDialogPay, urlProperty.getResourceName(), urlProperty.getResourceId(), urlProperty.getPrice(), payListener); } else { // 用户未登录 WasuPlayerViewPayUtil.getInstance().ShowLoginUI(softContext.get(), BuildType.loginurl, loginStatusListener); } break; case WasuPlayerViewPayUtil.PAYTYPE_PACKAGE_FEIHU: if (WasuPlayerViewPayUtil.getInstance().checkLogin()) { // 用户登录 WasuPlayerViewPayUtil.getInstance().SelectFeiHuPackge(softContext.get(), Common.OtherOrderUrl, assetInfo.getAssetFromLabel(), new DialogPlanBuy.PayStatusListener() { @Override public void onPay(int status, int code) { payListener.onPay(status, code); } }); } else { // 用戶未登录 WasuPlayerViewPayUtil.getInstance().ShowLoginUI(softContext.get(), BuildType.loginurl, loginStatusListener); } break; case WasuPlayerViewPayUtil.PAYTYPE_SINGLE_MIGU: WasuPlayerViewPayUtil.getInstance().MiGuSinglePay(mDialogPay, urlProperty.getResourceName(), urlProperty.getResourceId(), urlProperty.getPrice(), assetSeries.getOttVodId(), payListener); break; } } } // // sohu授权检测 // private void doLoginOrPay() { // String userKey = AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY); // if (TextUtils.isEmpty(userKey)) { // // if (mDialogLogin!= null && mDialogLogin.isShowing()){ // mDialogLogin.dismiss(); // } // mDialogLogin = new WasuCompFactory().createUniLogin(getContext(), BuildType.loginurl); // mDialogLogin.setLoginStatusListener(new DialogLogin.LoginStatusListener() { // @Override // public void onLogStatus(boolean b) { // if (b) { // Map params = new HashMap(); // params.put("resourceId", urlProperty.getResourceId()); // params.put("resourceName", urlProperty.getResourceName()); // params.put("orderType", 0); // // AuthSDK.getInstance().queryPrice(params, new AuthListener() { // @Override // public void result(int ret, String extra, Object retData) { // if (ret == WError.ERROR_NONE) { // PriceInfo price = (PriceInfo) retData; // urlProperty.setPrice(price.mPrice); // mOriginPrice = price.mOriginalPrice; // // if (price.mPrice > 0) { // mbNeedPay = true; // } else { // mbNeedPay = false; // postOnWasuPlayLimit(IMediaListener.WASU_PLAY_FREE, "-1"); // } // } // /**免费或收费都需要鉴权**/ // SohuTvPlayer sohuTvPlayer = (SohuTvPlayer) videoView.getMediaControl(); // sohuTvPlayer.setProviderAppKey(Common.sohuAppKey); // sohuTvPlayer.setUid(AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY)); // sohuTvPlayer.setMobile(""); // if (urlProperty.getPrice() == 0) { // reSetSohuTag(); // videoView.setVideoPath(mRealUrl, urlProperty); // } else { // showPayDialog(); // } // } // }); // } else { // postOnWasuError(IMediaListener.WASU_ERROR_AUTH, "用户登录失败"); // if (isFullScreen()) { // toggleFullScreen(); // } // if (assetInfo.getAssetFrom() == 91 && !"".equals(assetInfo.getOttEarly())) { // 搜狐抢先看资产特别处理 // stopPlayback(); // } // } // } // }); // suspend(); // mDialogLogin.show(); // } else { // if (urlProperty.getPrice() == 0) { // videoView.setVideoPath(mRealUrl, urlProperty); // } else { // showPayDialog(); // } // } // suspend(); // } // /** // * 调起统一支付页面 // */ // public void showPayDialog() { // WLog.i(TAG, "showPayDialog"); // if (mOriginPrice == 99999) { // monthlyPay(); // } else { // closeBKBMDialog(); // showPayDialog(true, urlProperty.getResourceName(), urlProperty.getResourceId(), urlProperty.getPrice(), payListener); // } // } /** * 调起统一支付页面(详情页自处理回调) * * @param isGodBuy 单点:true,订包:false * @param name 影片名称 * @param id 影片id或产品包id * @param price 价格 * @param listener 支付结果状态监听 * // */ public void showPayDialog(boolean isGodBuy, String name, String id, double price, PayStatusListener listener) { DemandProgram asset = assetInfo == null?assetInfoBackup : assetInfo; if (mDialogPay != null && asset != null && assetSeries != null) { if (asset.getAssetFrom() == 93) { // 咪咕资产_咪咕影院点单带渠道号migu_yy WasuPlayerViewPayUtil.getInstance().MiGuSinglePay(mDialogPay, name, id, price, assetSeries.getOttVodId(), listener); } else { if (isGodBuy) { // 单点 WasuPlayerViewPayUtil.getInstance().WasuSinglePay(mDialogPay, name, id, price, listener); } else { // 订包 WasuPlayerViewPayUtil.getInstance().BookWasuMonthPackage(mDialogPay, name, id, price, listener); } } postOnWasuPlayLimit(IMediaListener.WASU_PLAY_IN_PAY, "-1"); } } // /** // * 调起统一支付页面 // * // * @param isGodBuy 单点:true,订包:false // * @param name 影片名称 // * @param id 影片id或产品包id // * @param price 价格 // * @param listener 支付结果状态监听 // */ // public void showPayDialog(boolean isGodBuy, String name, String id, double price, PayStatusListener listener) { // if (urlProperty == null) { // return; // } // // if (mDialogPay != null) { // WLog.e("BigDataStatistics", "调用消费记录"); // WasuStatistics.getInstance().BigDataconsume(assetInfo.getId(), assetInfo.getPrice() + ""); // // if (assetInfo.getAssetFrom() == 93) { // 咪咕资产_咪咕影院点单带渠道号migu_yy // PayInfo pay = new PayInfo(); // pay.setPayType(PayInfo.PAY_TYPE_Miguyy); // pay.setResourceName(name); // pay.setResourceId(id); // pay.setPrice(price); // pay.setThirdIndentID(assetSeries.getOttVodId()); // WLog.e("tag", "assetSeries.getOttVodId() = " + assetSeries.getOttVodId()); // mDialogPay.setPayInfo(pay, listener); // } else { // PayInfo pay = new PayInfo(); // pay.setPayType(isGodBuy ? PayInfo.PAY_TYPE_DEMAND : PayInfo.PAY_TYPE_PLAN); // pay.setResourceName(name); // pay.setResourceId(id); // pay.setPrice(price); // mDialogPay.setPayInfo(pay, listener); // } // // if (!mDialogPay.isShowing()) { // mDialogPay.show(); // } // postOnWasuPlayLimit(IMediaListener.WASU_PLAY_IN_PAY, "-1"); // } // } // /** // * 无参调起登陆和定包 // * */ // public void monthlyPay(){ // String userKey = AuthSDK.getInstance().getValue(AuthSDK.KEY_USERKEY); // if (TextUtils.isEmpty(userKey)) { // // if (mDialogLogin != null && mDialogLogin.isShowing()){ // mDialogLogin.dismiss(); // } // mDialogLogin = new WasuCompFactory().createUniLogin(getContext(), BuildType.loginurl); // mDialogLogin.setLoginStatusListener(new DialogLogin.LoginStatusListener() { // @Override // public void onLogStatus(boolean b) { // if (b) { // Map params = new HashMap(); // params.put("resourceId", urlProperty.getResourceId()); // params.put("resourceName", urlProperty.getResourceName()); // params.put("orderType", 0); // // AuthSDK.getInstance().queryPrice(params, new AuthListener() { // @Override // public void result(int ret, String extra, Object retData) { // if (ret == WError.ERROR_NONE) { // PriceInfo price = (PriceInfo) retData; // urlProperty.setPrice(price.mPrice); // mOriginPrice = price.mOriginalPrice; // // if (price.mPrice > 0) { // mbNeedPay = true; // } else { // mbNeedPay = false; // postOnWasuPlayLimit(IMediaListener.WASU_PLAY_FREE, "-1"); // } // } // // if (urlProperty.getPrice() == 0) { // if (!TextUtils.isEmpty(mRealUrl)) { // reSetSohuTag(); // resume(mRealUrl); // } // } else { // mDialogPlanBuy = new DialogPlanBuy(getContext(), Common.OtherOrderUrl, assetInfo.getAssetFromLabel(), new DialogPlanBuy.PayStatusListener() { // @Override // public void onPay(int status, int code) { // payListener.onPay(status, code); // } // }); // mDialogPlanBuy.show(); // } // } // }); // } else { // Toast.makeText(WasuPlayerView.this.getContext(), "用户登录失败", Toast.LENGTH_SHORT).show(); // } // } // }); // closeBKBMDialog(); // mDialogLogin.show(); // } else { // mDialogPlanBuy = new DialogPlanBuy(getContext(), Common.OtherOrderUrl, assetInfo.getAssetFromLabel(), new DialogPlanBuy.PayStatusListener() { // @Override // public void onPay(int status, int code) { // payListener.onPay(status, code); // } // }); // closeBKBMDialog(); // mDialogPlanBuy.show(); // } // } @Override public void onPause(MediaPlayer mp) { isPaused = true; ScreenSaverModule.getInstance().updateUserActionTime(); } @Override public void onResume(MediaPlayer mp) { ScreenSaverModule.getInstance().updateUserActionTime(); } @Override public void onStop(MediaPlayer mp) { StopTimer(); setHasStart(false); if (isPayFail) { saveHistory(assetSeries != null ? assetSeries.getPreviewTime() * 1000 : Config.MAX_PREVIEW_MINUTES * 60 * 1000, videoView.getDuration());//支付失败历史记录保存为5分钟 } else { saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); } } @Override public void onCompletion(MediaPlayer mp) { setHasStart(false); //渡鸦科技播放完成之后,重新播放该资产 if (BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.DUYA_TECH)) { ((ActivityDetail) activity).play(); return; } if (playType == PLAY_TYPE_NORMAL) { if (assetInfo == null) { StopTimer(); exit("播放完毕"); return; } if (assetInfo.getAssetType() == DemandProgram.SHOWTYPE_MOVIE || assetInfo.getAssetType() == DemandProgram.SHOWTYPE_UNKNOWN) { StopTimer(); exit("播放完毕"); return; } if (assetInfo.getCurPlayIndex() == assetInfo.getLastSeries()) { isLastSeriesFinish = true; if (playerMask != null) { playerMask.isLastSeriesFinish(isLastSeriesFinish); } StopTimer(); exit("播放完毕"); return; } saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); PlayerParams playerParams = new PlayerParams(); assetInfo.setCurPlayIndex(assetInfo.getNextSeries()); playerParams.setAssetInfo(assetInfo); play(playerParams); } else if (playType == PLAY_TYPE_LOOP) { if (subPlayType == PLAY_TYPE_NORMAL) { if (assetList == null) { StopTimer(); exit("播放完毕"); return; } if (playIndex == assetList.getSize() - 1) { StopTimer(); exit("播放完毕"); return; } //获取联播列表长度,判断是否播放到联播列表结尾 if (playIndex == assetList.getSize() - 1) { StopTimer(); exit("播放完毕"); return; } saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); playIndex++; PlayerParams playerParams = new PlayerParams(); playerParams.setAssetList(assetList); playerParams.setAssetUrl(assetUrl); playerParams.setPlayType(PLAY_TYPE_LOOP); playerParams.setPlayIndex(playIndex); play(playerParams); } else if (subPlayType == PLAY_TYPE_LOOP) { if (assetInfo == null || assetInfo.getAssetType() != DemandProgram.SHOWTYPE_TV_SERIES) { StopTimer(); exit("播放完毕"); return; } saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); if (assetInfo.getCurPlayIndex() == assetInfo.getLastSeries()) { if (assetList == null) { StopTimer(); exit("播放完毕"); return; } if (playIndex == assetList.getSize() - 1) { StopTimer(); exit("播放完毕"); return; } playIndex++; PlayerParams playerParams = new PlayerParams(); playerParams.setAssetList(assetList); playerParams.setAssetUrl(assetUrl); playerParams.setPlayType(PLAY_TYPE_LOOP); playerParams.setPlayIndex(playIndex); play(playerParams); } else { PlayerParams playerParams = new PlayerParams(); assetInfo.setCurPlayIndex(assetInfo.getNextSeries()); playerParams.setAssetInfo(assetInfo); playerParams.setAssetList(assetList); playerParams.setAssetUrl(assetUrl); playerParams.setPlayType(PLAY_TYPE_LOOP); playerParams.setPlayIndex(playIndex); play(playerParams); } } else { } } else { } } @Override public void onError(MediaPlayer mp, int what, int extra) { StopTimer(); WLog.e(TAG, "播放器错误:" + what + "," + extra); WasuStatistics.getInstance().playerError(what + "", extra + "", ""); } @Override public void onInfo(MediaPlayer mp, int what, int extra) { } @Override public void onStatusChanged(MediaPlayer mp, int currentStatus) { } @Override public void onAdStatusChanged(int status, int extra) { switch (status) { case IMediaListener.AD_START: saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); isAdPlaying = true; break; case IMediaListener.AD_END: isAdPlaying = false; break; } } /** * @param errorCode WASU_ERROR_AUTH = 设备授权注册失败 * WASU_ERROR_QUERY_PRICE = 资产询价失败 * WASU_ERROR_PAY = 资产支付失败 * WASU_ERROR_PLAYER = 播放器异常 * WASU_ERROR_UPM_TOKEN_EXPIRE = token严重超期 * @param extra */ @Override public void onWasuError(int errorCode, String extra) { if (NetUtils.isNetConnected(softContext.get())) { switch (errorCode) { case IMediaListener.WASU_ERROR_AUTH: WLog.e(TAG, "设备授权注册失败"); break; case IMediaListener.WASU_ERROR_QUERY_PRICE: WLog.e(TAG, "资产询价失败"); break; case IMediaListener.WASU_ERROR_PAY: WLog.e(TAG, "资产支付失败"); break; case IMediaListener.WASU_ERROR_PLAYER: WLog.e(TAG, "播放器异常:" + extra); break; case IMediaListener.WASU_ERROR_UPM_TOKEN_EXPIRE: WLog.e(TAG, "token严重超期"); break; } } else { WLog.e(TAG, "网络出错,请检查您的网络设置"); } } @Override public void onWasuPlayLimit(int status, String extra) { if (status == IMediaListener.WASU_PLAY_IN_PAY) { saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); } else if (status == IMediaListener.WASU_PLAY_IN_PREVIEW) { } else if (status == IMediaListener.WASU_PLAY_FREE) { // 收费影片,已付费继续历史播放 if (!assetInfo.isFree() && assetHistory.lastSeries == assetInfo.getCurPlayIndex() && assetHistory.duration - assetHistory.lastPlayTime > 10000) { if (isHasStart() || isPlaying() || isAdPlaying()) { videoView.seekTo((int) assetHistory.lastPlayTime); } else { /**收费影片重头拉起这个*/ videoView.setVideoPath(mRealUrl, urlProperty); } isShowSeekMsg = true; } } } /***********************************************************************************/ private String getPlayTag() { if (assetInfo == null) { return null; } Set> entrySet = assetInfo.getPlayinfoList().entrySet(); long fitRate = softContext.get().getSharedPreferences(MediaController.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).getLong(MediaController.SHARED_PREFERENCES_KEY_CURRENT_RATE, WasuPlayerView.DEFAULT_PLAY_RATE); for (Entry entry : entrySet) { long rate = entry.getKey(); String tag = entry.getValue().getTag(); if (rate == fitRate) { return tag; } } return null; } private Map getUpdateParams() { Map params = new HashMap(); if (assetInfo != null) { params.put("prol", Common.APP_NAME + "_" + VersionUtils.getVersionName(softContext.get())); params.put("ccid", assetInfo.getCatId()); params.put("cid", assetInfo.getId()); params.put("pay", assetInfo.getFee()); params.put("strrate", getPlayTag()); String duration = ""; try { if (assetSeries != null) duration = Integer.parseInt(assetSeries.getDuration()) / 1000 + ""; } catch (Exception e) { e.printStackTrace(); } params.put("vd", duration); params.put("ccName", assetInfo.getCatName()); params.put("cName", assetInfo.getTitle()); params.put("userid", AuthSDK.getInstance().getValue(AuthSDK.KEY_TVID)); params.put("columnid", assetInfo.getCatId()); params.put("programid", assetInfo.getId()); params.put("featureid", assetInfo.getIsFree() == 1 ? "true" : "false"); } return params; } private void openVideo() { if (TextUtils.isEmpty(mRealUrl) || videoView == null) { return; } new Thread(openVideoTask).start(); } public void hidePayDialog() { if (mDialogPay != null) { posWhenPay = 0; mDialogPay.dismiss(); } // if (mDialogLogin != null && mDialogLogin.isShowing()) { // mDialogLogin.dismiss(); // } // if (mDialogPlanBuy != null && mDialogPlanBuy.isShowing()) { // mDialogPlanBuy.dismiss(); // } } private void postOnWasuError(int status, String extra) { if (mediaListeners == null) { return; } for (IMediaListener l : mediaListeners) { l.onWasuError(status, extra); } } private void postOnWasuPlayLimit(int status, String extra) { if (mediaListeners == null) { return; } for (IMediaListener l : mediaListeners) { l.onWasuPlayLimit(status, extra); } } @Override public void onStateChanged(int state) { if (videoView == null) { return; } if (AppUtil.ETHERNET_CONNECTED == state || AppUtil.WIFI_CONNECTED == state) { if (assetInfo == null || assetInfo.getAssetFrom() < 91) { if (!TextUtils.isEmpty(mRealUrl) && !isCover()) { resume(mRealUrl); if (assetHistory != null) { seekTo((int) assetHistory.lastPlayTime); } } } if (isPaused) { pause();//原来是暂停状态保持暂停 } } else { saveHistory(videoView.getCurrentPosition(), videoView.getDuration()); } } private boolean isCover() { Rect rect = new Rect(); boolean isCover = getGlobalVisibleRect(rect); if (isCover) { if (rect.width() < getMeasuredWidth() || rect.height() < getMeasuredHeight()) { return true; } else { return false; } } else { return true; } } /** * -----------------------------------边看边买---------------------------------------- **/ // 启动计时器timer public void StartTimer() { /** * 计算是否应该打开边看边买计时器 * */ // WLog.e(TAG, "调起StartTimer"); if (AppUtil.bkbmSwitch /**边看边买开关*/ && JudgeAsset() /**判断资产类型*/ && checkIsVip().equals("0") /**vip不播放广告*/ && mHandler == null/**最后判断,防止资产混编联播*/) { mHandler = new Handler(); mRunnable = new Runnable() { @Override public void run() { /** * 时间到了看是否符合跳出边看边买广告规则 * */ if (videoView != null /**预防播放器联播换集时*/) { //边看边买 AppUtil.watchTime += 1; // WLog.i(TAG, "正在计算时间 time = " + AppUtil.watchTime); // WLog.i(TAG, " isplaying = " + isPlaying()); if (shouldBKBM()) { mDialogBKBM = new DialogBKBM(softContext.get(), R.style.BKBMDialog, AppUtil.bkbmTime.get(0).getPos()/**边看边买的pos*/); AppUtil.bkbmTime.remove(0); } mHandler.postDelayed(mRunnable, 1000); } else { // WLog.e(TAG,"Run 被跳过!"); } } }; mHandler.postDelayed(mRunnable, 1000); } else { // WLog.e(TAG, "StartTimer 已存在实例 或者资产类型错误!或者出错!"); } } //边看边买播放计算器 private boolean shouldBKBM() { if (!isFullScreen()/**全屏*/) { return false; } if (!isPlaying() /**正在播放*/) { return false; } if (!(mediaController.getCurrentView() == null || !(mediaController.getCurrentView() instanceof SeekbarController)) /**seekbar 出现时不出现广告*/) { return false; } if (!JudgeAsset() /**再次判断资产类型*/) { return false; } if (isAdPlaying() /**广告播放时不出现*/) { return false; } /** * 计时器 * */ if (AppUtil.bkbmTime != null) { if (AppUtil.bkbmTime.size() > 0) { if (AppUtil.bkbmTime.get(0).getTime() == AppUtil.watchTime) { } else { return false; } } else { AppUtil.bkbmSwitch = false; return false; } }else { return false; } return true; } // 关闭计时器timer public void StopTimer() { if (mHandler != null) { // WLog.e(TAG, "timer 被关闭!"); mHandler.removeCallbacks(mRunnable); mHandler = null; if (mRunnable != null) { mRunnable = null; } closeBKBMDialog(); } } //关闭BKBMdialog public void closeBKBMDialog() { if (mDialogBKBM != null) { if (mDialogBKBM.isShowing()) mDialogBKBM.dismiss(); mDialogBKBM = null; } } // 资产类型计算器 (是否应该播放边看边买广告) private boolean JudgeAsset() { DemandProgram assetinfo; if (assetInfo != null) { assetinfo = assetInfo; // WLog.e(TAG,"JudgeAsset assetInfo = "+assetInfo.getTitle()); } else if (assetInfoBackup != null) { assetinfo = assetInfoBackup; // WLog.e(TAG,"JudgeAsset assetInfoBackup = "+assetInfoBackup.getTitle()); } else { // WLog.e(TAG,"JudgeAsset 资产信息错误"); StopTimer(); return false; } // WLog.e(TAG, "ppv ========== "+assetinfo.getPpv()); if (assetinfo.getAssetFrom() >= 91) {//小于91代表华数自产,91代表搜狐资产,93代表咪咕影院 // WLog.e(TAG,"非华数资产!"); StopTimer(); return false; } for (int i = 0; i < AppUtil.bkbmIgnore.length; i++) { if (assetinfo.getPpv().contains(AppUtil.bkbmIgnore[i])) { // WLog.e(TAG, "该ppv不允许播放广告!"); StopTimer(); return false; } } return true; } // 获取vip信息 private String checkIsVip() { String isvip = AuthSDK.getInstance().getValue("vipState"); return isvip.isEmpty() ? "0" : isvip; } /********************************************************************************************/ public DemandProgram getAssetInfo() { if (assetInfo == null) { return assetInfoBackup; } else { return assetInfo; } } /** * 切断当前的广告 * */ public void skipCurrentAd(){ if (isAdPlaying() && videoView != null){ videoView.skipCurrentAd(); } } public void changeRate(long rate){ if (mediaController != null && videoView != null){ stopPlayback(); ignoreHeadAd(); PlayerParams playerParams = mediaController.getPlayerParams(); playerParams.setBitrate(rate); play(playerParams); } } public long getBitrate() { return bitrate; } public static long getDefaultPlayRate() { return DEFAULT_PLAY_RATE; } /** * 更改搜狐播放器中的Issuspend 确保能够观看 */ private void reSetSohuTag() { if (mSohuIMediaControl != null && assetInfo != null && assetInfo.getAssetFrom() == 91) { //Add By Frewen.Wong 搜狐资产开始播放的时候,检查并启动服务 ServiceGuardReciver.checkAndRestartLocaleServer(softContext.get().getApplicationContext()); mSohuIMediaControl.setIssuspend(false); //Add By Frewen.Wong 搜狐资产开始播放的时候,检查并启动服务 ServiceGuardReciver.checkAndRestartLocaleServer(getContext().getApplicationContext()); } } public AdPlayerView getVideoView() { return videoView; } }