package com.joyplus.mediaplayer; import android.content.Context; import android.os.Handler; import android.os.Message; import com.joyplus.mediaplayer.VideoViewInterface.DecodeType; import com.joyplus.mediaplayer.VideoViewInterface.STATE; import com.joyplus.tvhelper.R; import com.joyplus.tvhelper.utils.Log; public class JoyplusMediaPlayerServer { private boolean Debug = true; private String TAG = "JoyplusMediaPlayerServer"; private final static int NO_FIND = -1; //private Context mContext; private JoyplusPlayerConfig[] mPlayerConfigs;//it depend on priority_HW which depend in "JoyplusMediaPlayerConfig.XML" , //private VideoViewInterface mPlayers[];//it depend on priority_HW which depend in "JoyplusMediaPlayerConfig.XML" , private int HWPlayer = 0; //it depend on priority_HW which depend in "JoyplusMediaPlayerConfig.XML" , private int SWPlayer = 0; //it depend on priority_HW which depend in "JoyplusMediaPlayerConfig.XML" , private int[] priorityHWList; //it depend on priority_HW which depend in "JoyplusMediaPlayerConfig.XML" ,reverse order private int[] prioritySWList; //it depend on priority_SW which depend in "JoyplusMediaPlayerConfig.XML" ,reverse order /*MediaPlayer tracker,it use to report*/ private JoyplusMediaPlayerStateTrack mStateTracker; private PlayerState mCurrentState; /*client of JoyplusMediaPlayerServer,bc no C/S,so do it in the same thread*/ public JoyplusMediaPlayerServer(Context context){ // this.mContext = context; mStateTracker = new JoyplusMediaPlayerStateTrack(); mPlayerConfigs = new JoyplusPlayerConfig[JoyplusMediaPlayerManager.TYPE_MAX+1]; //mPlayers = new VideoViewInterface[JoyplusMediaPlayerManager.TYPE_MAX+1]; String[] ConfigStrings = context.getResources().getStringArray(R.array.mediaplayerconfig); if(ConfigStrings==null || "".equals(ConfigStrings))throw new IllegalArgumentException(); for(String config : ConfigStrings){ JoyplusPlayerConfig n = new JoyplusPlayerConfig(config); if(!JoyplusMediaPlayerManager.isTypeAvailable(n.TYPE)){ Log.i(TAG,"JoyplusMediaPlayerServer - ignoring attempt to define type"); continue; } if(mPlayerConfigs[n.TYPE]!=null){ Log.i(TAG,"JoyplusMediaPlayerServer - ignoring attempt to redefine type"); continue; } mPlayerConfigs[n.TYPE] = n; if(!n.EN){ Log.i(TAG,"JoyplusMediaPlayerServer - ignoring EN to define type"); continue; } if(n.DECODE_HW)HWPlayer++; if(n.DECODE_SW)SWPlayer++; } InitprioritySWList(); InitpriorityHWList(); } /*Interface of mediaplayer config*/ public JoyplusPlayerConfig getJoyplusPlayerConfig(int Type) throws Exception{ if(!JoyplusMediaPlayerManager.isTypeAvailable(Type))throw new Exception("unAvailableType"+Type); Log.i(TAG, "getJoyplusPlayerConfig--->" + mPlayerConfigs[Type]); return mPlayerConfigs[Type]; } /*interface of current player,it will be use we init or resume*/ public PlayerState getCurrentType(){ if(mCurrentState == null)mCurrentState = new PlayerState(); return mCurrentState; } /*get next player type,it depend on the priority * when CurrentDecodeType is default decode type,we allow to search the others decode type * eg: CurrentDecodeType is HW. default type is HW. when we search,frist company priorityHWList. * if no lower priority find,now, we allow to search prioritySWList. * CurrentDecodeType is HW. default type is SW. when we search,frist company priorityHWList. * if no lower priority find,now ,we return no find. * First Priority : DecodeType * Second Priority : priority * * Return: PlayerState*/ public PlayerState getNextType(int Type) throws Exception{ if(!JoyplusMediaPlayerManager.isTypeAvailable(Type))throw new Exception("unAvailableType"+Type); DecodeType DefaultDecodeType = JoyplusMediaPlayerManager.getInstance().getDecodeType(); return getNextType(DefaultDecodeType,Type,true); } /*define by Jas@20130730 for get lower priority in list priorityHWList,prioritySWList*/ private PlayerState getNextType(DecodeType type,int currentType,boolean Allow){ PlayerState state = new PlayerState(); if(DecodeType.Decode_HW == type){ state.DecodeType = DecodeType.Decode_HW; state.PlayerType = getNextType(priorityHWList,currentType); }else if(DecodeType.Decode_SW == type){ state.DecodeType = DecodeType.Decode_SW; state.PlayerType = getNextType(prioritySWList,currentType); } if(state.PlayerType <= NO_FIND){ if(Allow){ state = getNextType(type,currentType,false); } } return state; } /*define by Jas@20130730 for get lower priority in list like priorityHWList,prioritySWList*/ private int getNextType(int[] list,int currentType){ if(list == null || list.length<1)return NO_FIND; for(int m : list){ if(currentType <= m)continue; return m; } return NO_FIND; } /*init SW priority ,reverse order*/ private void InitprioritySWList(){ if(SWPlayer<=0)return; prioritySWList = new int[SWPlayer]; int insertionPoint = SWPlayer-1; int currentLowest = 0; int nextLowest = 0; while (insertionPoint > -1) { for (JoyplusPlayerConfig na : mPlayerConfigs) { if (na == null || !na.DECODE_SW || !na.EN) continue; if (na.PRIORITY_SW < currentLowest) continue; if (na.PRIORITY_SW > currentLowest) { if (na.PRIORITY_SW < nextLowest || nextLowest == 0) { nextLowest = na.PRIORITY_SW; } continue; } prioritySWList[insertionPoint--] = na.TYPE; } currentLowest = nextLowest; nextLowest = 0; } if(Debug){ for(int SW :prioritySWList){ Log.d(TAG,"prioritySWList mPlayerConfigs["+SW+"]"+mPlayerConfigs[SW].toString()); } } } /*init HW priority ,reverse order*/ private void InitpriorityHWList(){ if(HWPlayer<=0)return; priorityHWList = new int[HWPlayer]; int insertionPoint = HWPlayer-1; int currentLowest = 0; int nextLowest = 0; while (insertionPoint > -1) { for (JoyplusPlayerConfig na : mPlayerConfigs) { if (na == null || !na.DECODE_HW || !na.EN) continue; if (na.PRIORITY_HW < currentLowest) continue; if (na.PRIORITY_HW > currentLowest) { if (na.PRIORITY_HW < nextLowest || nextLowest == 0) { nextLowest = na.PRIORITY_HW; } continue; } priorityHWList[insertionPoint--] = na.TYPE; } currentLowest = nextLowest; nextLowest = 0; } if(Debug){ for(int HW :priorityHWList){ Log.d(TAG,"priorityHWList mPlayerConfigs["+HW+"]"+mPlayerConfigs[HW].toString()); } } } public class PlayerState{ /*MediaPlayer TYPE * @link{#JoyplusMediaPlayerManager} * see@# JoyplusMediaPlayerManager TYPE_UNKNOW * see@# JoyplusMediaPlayerManager TYPE_MEDIAPLAYER * see@# JoyplusMediaPlayerManager TYPE_VITAMIO * */ public int PlayerType ; /*MediaPlayer DecodeType * @link{# JoyplusPlayer} * see@# JoyplusPlayer DecodeType*/ public DecodeType DecodeType ; /*Save player current state * it will use to restore */ public MediaInfo Info; public PlayerState(){ DecodeType = JoyplusMediaPlayerManager.getInstance().getDecodeType(); if(DecodeType == DecodeType.Decode_HW){ if(priorityHWList != null && priorityHWList.length>0){ PlayerType = priorityHWList[0]; }else if(prioritySWList != null && prioritySWList.length>0){ DecodeType = DecodeType.Decode_SW; PlayerType = prioritySWList[0]; }else{ PlayerType = JoyplusMediaPlayerManager.TYPE_UNKNOW; } }else if(DecodeType == DecodeType.Decode_SW){ if(prioritySWList != null && prioritySWList.length>0){ PlayerType = prioritySWList[0]; }else if(priorityHWList != null && priorityHWList.length>0){ DecodeType = DecodeType.Decode_HW; PlayerType = priorityHWList[0]; }else{ PlayerType = JoyplusMediaPlayerManager.TYPE_UNKNOW; } } if(JoyplusMediaPlayerManager.isTypeAvailable(PlayerType)){ Info = new MediaInfo();//Info will report by MediaPlayer monitor } } public PlayerState(PlayerState state){ if(state != null){ this.PlayerType = state.PlayerType; this.DecodeType = state.DecodeType; this.Info = state.Info.CreateMediaInfo(); } } public String toString(){ StringBuffer sb = new StringBuffer(); sb.append("PlayerState{ PlayerType: ").append(JoyplusMediaPlayerManager.getPlayerTypeName(PlayerType)). append(", DecodeType:").append(JoyplusMediaPlayerManager.getInstance().getDecodeName(DecodeType)). append(", MediaInfo:").append(Info.toString()); return sb.toString(); } } /*Interface of switch player*/ public boolean SwitchPlayer(){ try { if(JoyplusMediaPlayerManager.isTypeAvailable(mCurrentState.PlayerType)){ PlayerState nextPlayer = getNextType(mCurrentState.PlayerType); if(NO_FIND != nextPlayer.PlayerType && JoyplusMediaPlayerManager.isTypeAvailable(nextPlayer.PlayerType)){ mCurrentState = new PlayerState(nextPlayer); return true; } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } InitPlayer(); return false; } public void InitPlayer(){ mCurrentState = new PlayerState(); } /*Interface of Listener*/ public void registerListener(JoyplusMediaPlayerListener listener){ if(listener == null)return; mStateTracker.registerListener(listener); } public void unregisterListener(JoyplusMediaPlayerListener listener){ if(listener == null)return; mStateTracker.unregisterListener(listener); } public void unregisterAllListener(){ mStateTracker.unregisterAllListener(); } /*this handler was use to get info for MediaPlayerMonitor*/ public Handler getMediaPlayerHandler(){ return mMediaPlayerHandler; } private Handler mMediaPlayerHandler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch(msg.what){ case JoyplusPlayerMonitor.MSG_STATEUPDATE: MediaInfo info = ((MediaInfo) msg.obj).CreateMediaInfo(); if(info != null){ //mCurrentState.Info = info; mStateTracker.notifyMediaInfo(info); if(info.getState() == STATE.MEDIA_STATE_UNKNOW ){ //SwitchPlayer(); mStateTracker.notifyMediaError(); }else if(info.getState() == STATE.MEDIA_STATE_FINISH){ mStateTracker.notifyMediaCompletion(); } } break; case JoyplusPlayerMonitor.MSG_NOPROCESSCOMMEND: mStateTracker.NoProcessCommend((String)msg.obj); break; } } }; private void notityNoProcess(String commend){ if(Debug)Log.d(TAG,"notityNoProcess("+commend+")"); Message m = Message.obtain(mMediaPlayerHandler, JoyplusPlayerMonitor.MSG_NOPROCESSCOMMEND,"MSG_NOPROCESSCOMMEND"); m.obj = commend; mMediaPlayerHandler.removeCallbacksAndMessages("MSG_NOPROCESSCOMMEND"); mMediaPlayerHandler.sendMessage(m); } }