package com.guangzhou.haochuan.jxtv.activity; import android.app.Activity; import android.app.ActivityManager; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import com.guangzhou.haochuan.jxtv.R; import com.guangzhou.haochuan.jxtv.util.CrashHandler; import com.guangzhou.haochuan.jxtv.util.LocalStore; import com.guangzhou.haochuan.jxtv.util.OttLoginUtil; import java.util.LinkedHashMap; import java.util.List; import java.util.Timer; import java.util.TimerTask; import tv.icntv.been.IcntvPlayerInfo; import tv.icntv.icntvplayersdk.IcntvPlayer; import tv.icntv.icntvplayersdk.iICntvPlayInterface; public class CntvPlayerActivity extends Activity implements iICntvPlayInterface, VideoEndDialog.OnClickListener{ private IcntvPlayer icntvPlayer = null; //cntv播放器实例 private FrameLayout playerContainer; //播放器容器 // 计时器 private Timer timer_pay; private Timer timer_video_time; private TimerTask task_video_timer; private TimerTask task_pay; //延迟执行滑动播放 private Timer delaySeekTimer; private TimerTask delaySeekTimerTask; //UI参数 private TextView videoTitle; //视频标题 private ImageView loadingAnimation; //加载动画 private FrameLayout loadingContainer; //加载动画容器 private TextView payNotice; //提示计费文本 private ImageView playOrPause; //暂停/播放按钮 private SeekBar seekBar; //播放进度条 private TextView currentTime; //当前播放时间 private TextView duration; //视频时长 private RelativeLayout topBar; //顶部栏 private RelativeLayout bottomBar; //顶部栏 //控制参数 private int seekPercent = 1; //视频跳跃百分比; private int delayHiddenBarTime = 3000; //延后隐藏操作条时间 private final String appId = "5aa0b1a82cf0a"; //未来电视视频播放ID private final String fSource = "1018"; //日志数据来源 //上一个页面传过来的参数 private String videoSourceId = ""; //素材ID private String videoTitleValue = ""; //素材标题 private String videoUrl = ""; //素材播放地址 private String isFee = ""; //该素材是否免费 private String examineId = ""; //未来审核ID private String examineStatus = ""; //审核状态。10,通过;20,未通过;40,下架 private String examineType=""; //审核类型 //退出菜单 private boolean showVideoEndDialog = false; String TAG = "CntvPlayerActivity"; @Override public void onConfigurationChanged(Configuration configuration){ super.onConfigurationChanged(configuration); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cntv_player); //Toast.makeText(this,"uid:" + uId,Toast.LENGTH_SHORT).show(); getDataFromIntent(); initComponent(); showBarOnBeginPlay(); //String msg = OttLoginUtil.getInstance().getLoginStateMsg(); String deviceId = OttLoginUtil.getInstance().getDeviceId(); if(deviceId.isEmpty() || deviceId == null){ // Log.i(TAG,",重新初始化ott,msg:" + msg); OttLoginUtil.getInstance().init(this, new OttLoginUtil.OnLoginListener() { @Override public void OnSuccess() { initPlayer(); } @Override public void onFail(String msg) { new AlertDialog.Builder(CntvPlayerActivity.this) .setMessage("抱歉!播放器初始化失败,点击'确定'退出当前播放") .setNegativeButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { playerRelease(); destroyPayTask(); CntvPlayerActivity.this.finish(); System.exit(0); } }).show(); } }); }else{ initPlayer(); } } @Override protected void onResume(){ super.onResume(); if(icntvPlayer != null){ if(!icntvPlayer.isPlaying()){ icntvPlayer.startVideo(); } } } @Override protected void onPause(){ super.onPause(); if(icntvPlayer != null){ if(icntvPlayer.isPlaying()){ icntvPlayer.pauseVideo(); } } } @Override protected void onStop(){ super.onStop(); playerRelease(); destroyPayTask(); killWebProcess(); } private void getDataFromIntent(){ Intent intent = getIntent(); videoSourceId = intent.getStringExtra("sourceId"); videoTitleValue = intent.getStringExtra("title"); videoUrl = intent.getStringExtra("url"); isFee = intent.getStringExtra("isFee"); examineId = intent.getStringExtra("examineId"); examineStatus = intent.getStringExtra("examineStatus"); examineType = intent.getStringExtra("examineType"); } //开场显示上下条,一段时间后隐藏 private void showBarOnBeginPlay(){ showBar(); new Thread(){ public void run(){ Looper.prepare(); new Handler().postDelayed(new Runnable() { @Override public void run() { CntvPlayerActivity.this.runOnUiThread(new Runnable() { @Override public void run() { hiddenBar(); } }); } },delayHiddenBarTime); Looper.loop(); } }.start(); } @Override protected void onDestroy(){ //将全局参数赋值为null videoSourceId = null; videoTitle = null; icntvPlayer = null; playerContainer = null; timer_pay = null; timer_video_time = null; task_video_timer = null; task_pay = null; delaySeekTimer = null; delaySeekTimerTask = null; videoTitle = null; loadingAnimation = null; loadingContainer = null; payNotice = null; playOrPause = null; seekBar = null; currentTime= null; duration = null; topBar = null; bottomBar= null; super.onDestroy(); } private void initComponent(){ videoTitle = findViewById(R.id.title); payNotice = findViewById(R.id.pay_notice); playOrPause = findViewById(R.id.play_pause); loadingAnimation = findViewById(R.id.loading_animation); loadingContainer = findViewById(R.id.loading); seekBar = findViewById(R.id.seek_bar); currentTime = findViewById(R.id.time_current); duration = findViewById(R.id.time_total); topBar = findViewById(R.id.top_bar); bottomBar = findViewById(R.id.bottom_bar); playerContainer = findViewById(R.id.video_view); videoTitle.setText(videoTitleValue); if(!LocalStore.getInstance().getIsVip(this)){ if(isFee.equals("1")){ payNotice.setVisibility(View.INVISIBLE); }else { payNotice.setVisibility(View.VISIBLE); } }else{ payNotice.setVisibility(View.INVISIBLE); } //开启加载动画 initLoadingAnimation(); } private void initLoadingAnimation(){ loadingAnimation.setImageResource(R.drawable.tv_load_animation); AnimationDrawable a = (AnimationDrawable)loadingAnimation.getDrawable(); a.start(); } /* private void setPlayerData(){ new SearchSingleSourceViewModel(this,videoSourceId).addObserver(this); }*/ private void initPlayer(){ try{ IcntvPlayerInfo icntvPlayerInfo = new IcntvPlayerInfo(); //播放器所需传入参数实例 icntvPlayerInfo.setPlayUrl(videoUrl); icntvPlayerInfo.setApp_id(appId); icntvPlayerInfo.setCheckType(examineType); icntvPlayerInfo.setfSource(fSource); icntvPlayerInfo.setProgramID(examineId); icntvPlayerInfo.setDuration(0); //还未实现,等待接口更新 icntvPlayerInfo.setPlayType("0"); Log.d(TAG,"初始化播放器"); if(icntvPlayer != null){ playerRelease(); icntvPlayer = null; } icntvPlayer = new IcntvPlayer(this, playerContainer, icntvPlayerInfo, this); }catch (Exception e){ e.printStackTrace(); } } private void showBar(){ topBar.setVisibility(View.VISIBLE); bottomBar.setVisibility(View.VISIBLE); initUpdatePlayTimeTask(); } private void hiddenBar(){ topBar.setVisibility(View.GONE); bottomBar.setVisibility(View.GONE); destroyUpdatePlayTimeTask(); } private void destroyPayTask(){ if(task_pay != null){ task_pay.cancel(); } } //更新当前播放时间 private void initUpdatePlayTimeTask(){ //启动更新视频进度任务 timer_video_time = new Timer(); task_video_timer = new TimerTask() { @Override public void run() { if(icntvPlayer == null){ return; } new Thread(){ public void run(){ Looper.prepare(); new Handler().post( new Runnable() { @Override public void run() { CntvPlayerActivity.this.runOnUiThread(new Runnable() { @Override public void run() { //更新当前播放时间 String currentPlayTime = convertLongTimeToStr(icntvPlayer.getCurrentPosition()); //获得当前播放时间 currentTime.setText(currentPlayTime); } }); } } ); Looper.loop(); } }.start(); } }; timer_video_time.schedule(task_video_timer,0,1000); } private void destroyUpdatePlayTimeTask(){ if(task_video_timer != null){ task_video_timer.cancel(); } timer_video_time.purge(); } public String convertLongTimeToStr(long time) { int ss = 1000; int mi = ss * 60; int hh = mi * 60; long hour = (time) / hh; long minute = (time - hour * hh) / mi; long second = (time - hour * hh - minute * mi) / ss; String strHour = hour < 10 ? "0" + hour : "" + hour; String strMinute = minute < 10 ? "0" + minute : "" + minute; String strSecond = second < 10 ? "0" + second : "" + second; if (hour > 0) { return strHour + ":" + strMinute + ":" + strSecond; } else { return strMinute + ":" + strSecond; } } public void playerRelease(){ destroyUpdatePlayTimeTask(); if(icntvPlayer == null){ return; } if(icntvPlayer.isPlaying()){ icntvPlayer.stopVideo(); } icntvPlayer.release(); } //重新播放 private void rePlay(){ playerRelease(); initPlayer(); showBarOnBeginPlay(); hasCompletion = false; } //播放/暂停 private void playOrPause(){ if(icntvPlayer == null){ return; } if(icntvPlayer.isPlaying()){ icntvPlayer.pauseVideo(); playOrPause.setImageResource(R.drawable.icon_play); showBar(); }else{ icntvPlayer.startVideo(); playOrPause.setImageResource(R.drawable.icon_pause); hiddenBar(); } } private void showVideoEndDialog(){ try{ VideoEndDialog videoEndDialog = new VideoEndDialog(); videoEndDialog.show(getFragmentManager(),"VideoEndDialog"); showVideoEndDialog = true; }catch (Exception e){ e.printStackTrace(); } } //遥控事件 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: //播放/暂停 playOrPause(); return true; case KeyEvent.KEYCODE_DPAD_LEFT: seekBack(); return true; case KeyEvent.KEYCODE_DPAD_RIGHT: seekForward(); return true; case KeyEvent.KEYCODE_BACK: //到顶跳到相应tab if(!showVideoEndDialog){ showVideoEndDialog(); //Toast.makeText(this,"显示VideoEndDialog",Toast.LENGTH_SHORT).show(); return true; }else{ return false; } case KeyEvent.KEYCODE_DPAD_DOWN: hiddenBar(); return true; } return false; } //当用户连续点击“前进”或者“后退时”,需要延时执行,好一次性滑动到目标位置 private void seekBack(){ if(icntvPlayer == null){ return; } showBar(); int backDistance = icntvPlayer.getDuration()*seekPercent/100; int currentPosition = icntvPlayer.getCurrentPosition(); int seekPosition = currentPosition - backDistance; seekBar.setProgress(seekPosition); playerDelaySeek(); destroyUpdatePlayTimeTask(); } private void seekForward(){ if(icntvPlayer == null){ return; } showBar(); int backDistance = icntvPlayer.getDuration()*seekPercent/100; int currentPosition = icntvPlayer.getCurrentPosition(); int seekPosition = currentPosition + backDistance; seekBar.setProgress(seekPosition); playerDelaySeek(); destroyUpdatePlayTimeTask(); } private void playerDelaySeek(){ delaySeekTimer = new Timer(); if(delaySeekTimerTask != null) { delaySeekTimerTask.cancel(); } delaySeekTimer.purge(); delaySeekTimerTask = new TimerTask() { @Override public void run() { new Thread(){ public void run(){ Looper.prepare(); new Handler().post( new Runnable() { @Override public void run() { CntvPlayerActivity.this.runOnUiThread(new Runnable() { @Override public void run() { if(icntvPlayer == null){ return; } int seekToPosition = seekBar.getProgress(); icntvPlayer.seekTo(seekToPosition); initUpdatePlayTimeTask(); hiddenBar(); } }); } }); Looper.loop(); } }.start(); } }; delaySeekTimer.schedule(delaySeekTimerTask,2000); } //视频事件 @Override public void onPrepared(LinkedHashMap linkedHashMap) { loadingContainer.setVisibility(View.GONE); //设置seekbar最大值 seekBar.setMax(icntvPlayer.getDuration()); seekBar.setProgress(0); //设置视频时长显示 duration.setText(convertLongTimeToStr(icntvPlayer.getDuration())); if(!LocalStore.getInstance().getIsVip(this)){ if(!isFee.equals("1")){ initPayTimeTask(); } } } //监控当前观看时间,弹出计费 private void initPayTimeTask(){ timer_pay = new Timer(); task_pay = new TimerTask() { @Override public void run() { new Thread(){ public void run(){ Looper.prepare(); new Handler().post( new Runnable() { @Override public void run() { //Toast.makeText(CntvPlayerActivity.this,"监控计费时间",Toast.LENGTH_SHORT).show(); if(icntvPlayer.getCurrentPosition()/1000 > 30){ //跳转到计费界面 CntvPlayerActivity.this.runOnUiThread(new Runnable() { @Override public void run() { playerRelease(); //Toast.makeText(CntvPlayerActivity.this,"跳转计费页面",Toast.LENGTH_SHORT).show(); setResult(3); destroyPayTask(); CntvPlayerActivity.this.finish(); System.exit(0); } }); } } }); Looper.loop(); } }.start(); } }; timer_pay.schedule(task_pay,0,1000); } private boolean hasCompletion = false; @Override public void onCompletion() { showVideoEndDialog(); } @Override public void onBufferStart(String s) { loadingContainer.setVisibility(View.VISIBLE); } @Override public void onBufferEnd(String s) { loadingContainer.setVisibility(View.GONE); } @Override public void onError(int i, int i1, String s) { new AlertDialog.Builder(this) .setTitle("错误") .setMessage("播放错误:" + s) .setPositiveButton("确定",new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { CntvPlayerActivity.this.finish(); } }).show(); String cnTvError = ""; switch (i){ case 1001: cnTvError = "未来电视播放错误. " + "错误类型:" + i + "; 错误值:" + i1 + "; 错误消息:" + "CDN视频源调度失败"; break; case 123456: cnTvError = "未来电视播放错误. " + "错误类型:" + i + "; 错误值:" + i1 + "; 错误消息:" + "SDK鉴权失败"; break; } CrashHandler.getInstance().saveCrashInfoToWeb(cnTvError); } @Override public void onTimeout() { new AlertDialog.Builder(this) .setTitle("超时") .setMessage("加载视频超时,点击“确定”返回") .setPositiveButton("确定",new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { playerRelease(); destroyPayTask(); CntvPlayerActivity.this.finish(); System.exit(0); } }).show(); Toast.makeText(this,"视频超时,退出",Toast.LENGTH_SHORT).show(); } /* @Override public void update(Observable o, Object arg) { if(o instanceof SearchSingleSourceViewModel){ SearchSingleSourceViewModel searchSingleSourceViewModel = (SearchSingleSourceViewModel)o; searchSingleSource = searchSingleSourceViewModel.getSearchSingleSource(); if(searchSingleSource == null){ return; } setSearchSingleSource(searchSingleSource); } }*/ /*private void setSearchSingleSource(SearchSingleSource searchSingleSource){ if(searchSingleSource != null){ if(searchSingleSource.code == 0){ icntvPlayerInfo = new IcntvPlayerInfo(); SingleSource singleSource = searchSingleSource.data; if(singleSource.isFee.equals("1")){ isFee = false; payNotice.setVisibility(View.GONE); }else if(singleSource.isFee.equals("2")){ isFee = true; } if(!singleSource.examine.examineStatus.equals("10")){ //未审核通过 CrashHandler .getInstance() .saveCrashInfoToWeb("播放的视频,ID:" + searchSingleSource.data.sourceId +",未通过审核,状态ID;" + singleSource.examine.examineStatus); new AlertDialog.Builder(this) .setMessage("视频未通过审核,或已下架,返回!") .setNegativeButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { CntvPlayerActivity.this.finish(); } }).show(); } *//*Toast.makeText(this,"sourceId:" + singleSource.sourceId +"审核ID:" + singleSource.examine.examineId + "审核状态:"+ singleSource.examine.examineStatus,Toast.LENGTH_LONG).show();*//* try{ icntvPlayerInfo.setPlayUrl(singleSource.videoUrl); icntvPlayerInfo.setApp_id(appId); icntvPlayerInfo.setCheckType(singleSource.examine.examineType); icntvPlayerInfo.setfSource(fSource); icntvPlayerInfo.setProgramID(singleSource.examine.examineId); icntvPlayerInfo.setDuration(singleSource.movieTime); //还未实现,等待接口更新 icntvPlayerInfo.setPlayType("0"); if(icntvPlayer != null){ playerRelease(); icntvPlayer = null; } icntvPlayer = new IcntvPlayer(this, playerContainer, icntvPlayerInfo, this); }catch (Exception e){ e.printStackTrace(); } //videoSourceId = searchSingleSource.data.sourceId; recordWatchHistory(videoSourceId); }else { Toast.makeText(this,"当前视频未通过审核,请退出播放!",Toast.LENGTH_SHORT).show(); } }else{ Toast.makeText(this,"未获得当前视频信息,请退出播放!",Toast.LENGTH_SHORT).show(); } }*/ /* //记录播放记录 private void recordWatchHistory(String sourceId){ if(sourceId.isEmpty()){ return; } new CollectWatchViewModel(sourceId).addObserver(this); }*/ @Override public void onPlayCurrent() { if(hasCompletion){ rePlay(); } } @Override public void onExit() { playerRelease(); destroyPayTask(); // killWebProcess(); this.finish(); System.exit(0); } /* * 因为DjblWebActivity是单独一个线程,如果退出的话,必须还要关闭DjblWebActivity线程才能起作用 * */ private void killWebProcess(){ ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); List runningAppProcessInfos = am.getRunningAppProcesses(); if(!runningAppProcessInfos.get(0).processName.equals("com.guangzhou.haochuan.jxtv")){ am.killBackgroundProcesses("com.guangzhou.haochuan.jxtv"); // API Level至少为8才能使用 this.finish(); System.exit(0); } } @Override public void onDismiss() { showVideoEndDialog = false; } }