VideoPlayerController.java 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  1. /*
  2. Copyright 2017 yangchong211(github.com/yangchong211)
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package org.yczbj.ycvideoplayerlib.controller;
  14. import android.annotation.SuppressLint;
  15. import android.content.BroadcastReceiver;
  16. import android.content.Context;
  17. import android.content.Intent;
  18. import android.content.IntentFilter;
  19. import android.net.ConnectivityManager;
  20. import android.net.NetworkInfo;
  21. import android.os.BatteryManager;
  22. import android.os.Build;
  23. import android.os.CountDownTimer;
  24. import android.support.annotation.DrawableRes;
  25. import android.support.annotation.IntRange;
  26. import android.support.annotation.NonNull;
  27. import android.view.LayoutInflater;
  28. import android.view.MotionEvent;
  29. import android.view.View;
  30. import android.widget.FrameLayout;
  31. import android.widget.ImageView;
  32. import android.widget.LinearLayout;
  33. import android.widget.ProgressBar;
  34. import android.widget.SeekBar;
  35. import android.widget.TextView;
  36. import android.widget.Toast;
  37. import org.yczbj.ycvideoplayerlib.dialog.ChangeClarityDialog;
  38. import org.yczbj.ycvideoplayerlib.R;
  39. import org.yczbj.ycvideoplayerlib.dialog.VideoClarity;
  40. import org.yczbj.ycvideoplayerlib.inter.listener.OnPlayerTypeListener;
  41. import org.yczbj.ycvideoplayerlib.receiver.BatterReceiver;
  42. import org.yczbj.ycvideoplayerlib.receiver.NetChangedReceiver;
  43. import org.yczbj.ycvideoplayerlib.utils.VideoLogUtil;
  44. import org.yczbj.ycvideoplayerlib.utils.VideoPlayerUtils;
  45. import org.yczbj.ycvideoplayerlib.constant.ConstantKeys;
  46. import org.yczbj.ycvideoplayerlib.inter.player.InterVideoPlayer;
  47. import org.yczbj.ycvideoplayerlib.inter.listener.OnClarityChangedListener;
  48. import org.yczbj.ycvideoplayerlib.inter.listener.OnCompletedListener;
  49. import org.yczbj.ycvideoplayerlib.inter.listener.OnPlayOrPauseListener;
  50. import org.yczbj.ycvideoplayerlib.inter.listener.OnVideoBackListener;
  51. import org.yczbj.ycvideoplayerlib.inter.listener.OnVideoControlListener;
  52. import org.yczbj.ycvideoplayerlib.view.BaseToast;
  53. import java.text.SimpleDateFormat;
  54. import java.util.ArrayList;
  55. import java.util.Date;
  56. import java.util.List;
  57. import java.util.Locale;
  58. /**
  59. * <pre>
  60. * @author yangchong
  61. * blog : https://github.com/yangchong211
  62. * time : 2017/9/29
  63. * desc : 播放器控制器,主要是处理UI操作逻辑
  64. * revise: 注意:建议先判断状态,再进行设置参数
  65. * </pre>
  66. */
  67. public class VideoPlayerController extends AbsVideoPlayerController implements View.OnClickListener{
  68. private Context mContext;
  69. private ImageView mImage;
  70. private ImageView mCenterStart;
  71. /**
  72. * top顶部视图,包括所有的
  73. */
  74. private LinearLayout mTop;
  75. private ImageView mBack;
  76. private TextView mTitle;
  77. /**
  78. * 正常视频,top顶部视图,包括下载,分享,更多,音频控件
  79. */
  80. private LinearLayout mLlTopOther;
  81. private ImageView mIvDownload;
  82. private ImageView mIvAudio;
  83. private ImageView mIvShare;
  84. private ImageView mIvMenu;
  85. /**
  86. * 横向屏幕视图,top顶部视图,包括音频,tv,电量,时间等控件
  87. */
  88. private LinearLayout mLlHorizontal;
  89. private ImageView mIvHorAudio;
  90. private ImageView mIvHorTv;
  91. private ImageView mBattery;
  92. private TextView mTime;
  93. /**
  94. * 底部视图,包括所有的
  95. */
  96. private LinearLayout mBottom;
  97. private ImageView mRestartPause;
  98. private TextView mPosition;
  99. private TextView mDuration;
  100. private SeekBar mSeek;
  101. private TextView mClarity;
  102. private ImageView mFullScreen;
  103. private TextView mLength;
  104. /**
  105. * 加载loading视图,包括所有的
  106. */
  107. private LinearLayout mLoading;
  108. private ProgressBar pbLoadingRing;
  109. private ProgressBar pbLoadingQq;
  110. private TextView mLoadText;
  111. /**
  112. * 改变播放位置视图,这个是在屏幕上左右滑动切换播放进度的控件
  113. */
  114. private LinearLayout mChangePosition;
  115. private TextView mChangePositionCurrent;
  116. private ProgressBar mChangePositionProgress;
  117. /**
  118. * 改变屏幕亮度视图,这个是在屏幕左边上下滑动改变亮度的控件
  119. */
  120. private LinearLayout mChangeBrightness;
  121. private ProgressBar mChangeBrightnessProgress;
  122. /**
  123. * 改变播放声音视图,这个是在屏幕右边上下滑动改变音量的控件
  124. */
  125. private LinearLayout mChangeVolume;
  126. private ProgressBar mChangeVolumeProgress;
  127. /**
  128. * 异常壮体视图
  129. */
  130. private LinearLayout mError;
  131. private TextView mTvError;
  132. private TextView mRetry;
  133. /**
  134. * 完成播放视图
  135. */
  136. private LinearLayout mCompleted;
  137. private TextView mReplay;
  138. private TextView mShare;
  139. /**
  140. * 锁屏视图,只有在横屏播放的时候才会显示
  141. */
  142. private FrameLayout mFlLock;
  143. private ImageView mIvLock;
  144. /**
  145. * 底部播放进度条
  146. */
  147. private LinearLayout mLine;
  148. private ProgressBar mPbPlayBar;
  149. private boolean topBottomVisible;
  150. /**
  151. * 倒计时器
  152. */
  153. private CountDownTimer mDismissTopBottomCountDownTimer;
  154. private List<VideoClarity> clarities;
  155. private int defaultClarityIndex;
  156. private ChangeClarityDialog mClarityDialog;
  157. /**
  158. * 是否已经注册了电池广播
  159. */
  160. private boolean hasRegisterBatteryReceiver;
  161. /**
  162. * 是否已经注册了网络监听广播,添加这个判断可以避免崩溃
  163. */
  164. private boolean hasRegisterNetReceiver;
  165. /**
  166. * 是否锁屏
  167. */
  168. private boolean mIsLock = false;
  169. /**
  170. * 这个是time时间不操作界面,则自动隐藏顶部和底部视图布局
  171. */
  172. private long time;
  173. /**
  174. * 顶部的布局,下载,切换音频,分享布局是否显示。
  175. * 默认为false,不显示
  176. */
  177. private boolean mIsTopLayoutVisibility = false;
  178. /**
  179. * 设置横屏播放时,tv图标是否显示
  180. * 默认为false,不显示
  181. */
  182. private boolean mIsTvIconVisibility = false;
  183. /**
  184. * 设置横屏播放时,audio图标是否显示
  185. * 默认为false,不显示
  186. */
  187. private boolean mIsAudioIconVisibility = false;
  188. /**
  189. * 网络变化监听广播,在网络变更时进行对应处理
  190. */
  191. private NetChangedReceiver netChangedReceiver;
  192. /**
  193. * 电池状态即电量变化广播接收器
  194. */
  195. private BroadcastReceiver mBatterReceiver;
  196. public VideoPlayerController(Context context) {
  197. super(context);
  198. mContext = context;
  199. init();
  200. }
  201. @Override
  202. protected void onAttachedToWindow() {
  203. super.onAttachedToWindow();
  204. }
  205. /**
  206. * 注意,在view被销毁调用该方法后,手动销毁动画
  207. */
  208. @Override
  209. protected void onDetachedFromWindow() {
  210. super.onDetachedFromWindow();
  211. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  212. if (pbLoadingRing!=null && pbLoadingRing.getVisibility()==View.VISIBLE){
  213. boolean animating = pbLoadingRing.isAnimating();
  214. if (animating){
  215. pbLoadingRing.clearAnimation();
  216. }
  217. }
  218. if (pbLoadingQq!=null && pbLoadingQq.getVisibility()==View.VISIBLE){
  219. boolean ringAnimating = pbLoadingQq.isAnimating();
  220. if (ringAnimating){
  221. pbLoadingQq.clearAnimation();
  222. }
  223. }
  224. } else {
  225. if (pbLoadingRing!=null && pbLoadingRing.getVisibility()==View.VISIBLE){
  226. pbLoadingRing.clearAnimation();
  227. }
  228. if (pbLoadingQq!=null && pbLoadingQq.getVisibility()==View.VISIBLE){
  229. pbLoadingQq.clearAnimation();
  230. }
  231. }
  232. }
  233. /**
  234. * 注册网络监听广播
  235. */
  236. private void registerNetChangedReceiver() {
  237. if (!hasRegisterNetReceiver) {
  238. if (netChangedReceiver == null) {
  239. netChangedReceiver = new NetChangedReceiver();
  240. IntentFilter filter = new IntentFilter();
  241. filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
  242. mContext.registerReceiver(netChangedReceiver, filter);
  243. VideoLogUtil.i("广播监听---------注册网络监听广播");
  244. }
  245. hasRegisterNetReceiver = true;
  246. }
  247. }
  248. /**
  249. * 当播放完成或者意外销毁,都需要解绑注册网络监听广播
  250. */
  251. private void unRegisterNetChangedReceiver() {
  252. if (hasRegisterNetReceiver) {
  253. if (netChangedReceiver != null) {
  254. mContext.unregisterReceiver(netChangedReceiver);
  255. VideoLogUtil.i("广播监听---------解绑注册网络监听广播");
  256. }
  257. hasRegisterNetReceiver = false;
  258. }
  259. }
  260. /**
  261. * 注册电池监听广播
  262. */
  263. private void registerBatterReceiver() {
  264. if (!hasRegisterBatteryReceiver) {
  265. mBatterReceiver = new BatterReceiver();
  266. mContext.registerReceiver(mBatterReceiver, new IntentFilter(
  267. Intent.ACTION_BATTERY_CHANGED));
  268. hasRegisterBatteryReceiver = true;
  269. VideoLogUtil.i("广播监听---------注册电池监听广播");
  270. }
  271. }
  272. /**
  273. * 当播放完成或者意外销毁,都需要解绑注册电池监听广播
  274. */
  275. private void unRegisterBatterReceiver() {
  276. if (hasRegisterBatteryReceiver) {
  277. mContext.unregisterReceiver(mBatterReceiver);
  278. hasRegisterBatteryReceiver = false;
  279. VideoLogUtil.i("广播监听---------解绑电池监听广播");
  280. }
  281. }
  282. /**
  283. * 初始化操作
  284. */
  285. private void init() {
  286. LayoutInflater.from(mContext).inflate(R.layout.custom_video_player, this, true);
  287. initFindViewById();
  288. initListener();
  289. registerNetChangedReceiver();
  290. }
  291. private void initFindViewById() {
  292. mCenterStart = findViewById(R.id.center_start);
  293. mImage = findViewById(R.id.image);
  294. mTop = findViewById(R.id.top);
  295. mBack = findViewById(R.id.back);
  296. mTitle = findViewById(R.id.title);
  297. mLlTopOther = findViewById(R.id.ll_top_other);
  298. mIvDownload = findViewById(R.id.iv_download);
  299. mIvAudio = findViewById(R.id.iv_audio);
  300. mIvShare = findViewById(R.id.iv_share);
  301. mIvMenu = findViewById(R.id.iv_menu);
  302. mLlHorizontal = findViewById(R.id.ll_horizontal);
  303. mIvHorAudio = findViewById(R.id.iv_hor_audio);
  304. mIvHorTv = findViewById(R.id.iv_hor_tv);
  305. mBattery = findViewById(R.id.battery);
  306. mTime = findViewById(R.id.time);
  307. mBottom = findViewById(R.id.bottom);
  308. mRestartPause = findViewById(R.id.restart_or_pause);
  309. mPosition = findViewById(R.id.position);
  310. mDuration = findViewById(R.id.duration);
  311. mSeek = findViewById(R.id.seek);
  312. mFullScreen = findViewById(R.id.full_screen);
  313. mClarity = findViewById(R.id.clarity);
  314. mLength = findViewById(R.id.length);
  315. mLoading = findViewById(R.id.loading);
  316. pbLoadingRing = findViewById(R.id.pb_loading_ring);
  317. pbLoadingQq = findViewById(R.id.pb_loading_qq);
  318. mLoadText = findViewById(R.id.load_text);
  319. mChangePosition = findViewById(R.id.change_position);
  320. mChangePositionCurrent = findViewById(R.id.change_position_current);
  321. mChangePositionProgress = findViewById(R.id.change_position_progress);
  322. mChangeBrightness = findViewById(R.id.change_brightness);
  323. mChangeBrightnessProgress = findViewById(R.id.change_brightness_progress);
  324. mChangeVolume = findViewById(R.id.change_volume);
  325. mChangeVolumeProgress = findViewById(R.id.change_volume_progress);
  326. mError = findViewById(R.id.error);
  327. mTvError = findViewById(R.id.tv_error);
  328. mRetry = findViewById(R.id.retry);
  329. mCompleted = findViewById(R.id.completed);
  330. mReplay = findViewById(R.id.replay);
  331. mShare = findViewById(R.id.share);
  332. mFlLock = findViewById(R.id.fl_lock);
  333. mIvLock = findViewById(R.id.iv_lock);
  334. mLine = findViewById(R.id.line);
  335. mPbPlayBar = findViewById(R.id.pb_play_bar);
  336. setTopVisibility(mIsTopLayoutVisibility);
  337. }
  338. private void initListener() {
  339. mCenterStart.setOnClickListener(this);
  340. mBack.setOnClickListener(this);
  341. mIvDownload.setOnClickListener(this);
  342. mIvShare.setOnClickListener(this);
  343. mIvAudio.setOnClickListener(this);
  344. mIvMenu.setOnClickListener(this);
  345. mIvHorAudio.setOnClickListener(this);
  346. mIvHorTv.setOnClickListener(this);
  347. mRestartPause.setOnClickListener(this);
  348. mFullScreen.setOnClickListener(this);
  349. mClarity.setOnClickListener(this);
  350. mRetry.setOnClickListener(this);
  351. mReplay.setOnClickListener(this);
  352. mShare.setOnClickListener(this);
  353. mFlLock.setOnClickListener(this);
  354. mSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
  355. @Override
  356. public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
  357. }
  358. @Override
  359. public void onStartTrackingTouch(SeekBar seekBar) {
  360. }
  361. @Override
  362. public void onStopTrackingTouch(SeekBar seekBar) {
  363. if (mVideoPlayer.isBufferingPaused() || mVideoPlayer.isPaused()) {
  364. mVideoPlayer.restart();
  365. }
  366. long position = (long) (mVideoPlayer.getDuration() * seekBar.getProgress() / 100f);
  367. mVideoPlayer.seekTo(position);
  368. startDismissTopBottomTimer();
  369. }
  370. });
  371. this.setOnClickListener(this);
  372. }
  373. /**
  374. * 18年3月15日添加
  375. * 设置是否显示视频头部的下载,分享布局控件
  376. * @param isVisibility 是否可见
  377. */
  378. @Override
  379. public void setTopVisibility(boolean isVisibility) {
  380. this.mIsTopLayoutVisibility = isVisibility;
  381. if(isVisibility){
  382. mLlTopOther.setVisibility(VISIBLE);
  383. }else {
  384. mLlTopOther.setVisibility(GONE);
  385. }
  386. }
  387. /**
  388. * 设置横屏播放时,tv和audio图标是否显示
  389. * @param isVisibility1 tv图标是否显示
  390. * @param isVisibility2 audio图标是否显示
  391. */
  392. @Override
  393. public void setTvAndAudioVisibility(boolean isVisibility1, boolean isVisibility2) {
  394. this.mIsTvIconVisibility = isVisibility1;
  395. this.mIsAudioIconVisibility = isVisibility2;
  396. mIvHorTv.setVisibility(mIsTvIconVisibility?VISIBLE:GONE);
  397. mIvHorAudio.setVisibility(mIsAudioIconVisibility?VISIBLE:GONE);
  398. }
  399. /**
  400. * 18年1月12号添加
  401. * 设置加载loading类型
  402. *
  403. * @param type 加载loading的类型
  404. * 目前1,是仿腾讯加载loading
  405. * 2,是转圈加载loading
  406. * 默认是2,后期想让用户自定义loading加载视图,不过暂时没实现
  407. * 更多可以关注我的GitHub:https://github.com/yangchong211
  408. */
  409. @Override
  410. public void setLoadingType(@ConstantKeys.LoadingType int type) {
  411. switch (type){
  412. case ConstantKeys.Loading.LOADING_RING:
  413. pbLoadingRing.setVisibility(VISIBLE);
  414. pbLoadingQq.setVisibility(GONE);
  415. break;
  416. case ConstantKeys.Loading.LOADING_QQ:
  417. pbLoadingRing.setVisibility(GONE);
  418. pbLoadingQq.setVisibility(VISIBLE);
  419. break;
  420. default:
  421. pbLoadingRing.setVisibility(VISIBLE);
  422. pbLoadingQq.setVisibility(GONE);
  423. break;
  424. }
  425. }
  426. /**
  427. * 设置不操作后,多久自动隐藏头部和底部布局
  428. * 添加值范围注释,限定时间为1秒到10秒之间
  429. * @param time 时间
  430. */
  431. @Override
  432. public void setHideTime(@IntRange(from = 1000 , to = 10000) long time) {
  433. this.time = time;
  434. }
  435. /**
  436. * 设置视频标题
  437. * @param title 视频标题
  438. */
  439. @Override
  440. public void setTitle(String title) {
  441. if (title!=null && title.length()>0){
  442. mTitle.setText(title);
  443. }
  444. }
  445. /**
  446. * 获取ImageView的对象
  447. * @return 对象
  448. */
  449. @Override
  450. public ImageView imageView() {
  451. return mImage;
  452. }
  453. /**
  454. * 设置图片
  455. * @param resId 视频底图资源
  456. */
  457. @Override
  458. public void setImage(@DrawableRes int resId) {
  459. mImage.setImageResource(resId);
  460. }
  461. /**
  462. * 设置视频时长
  463. * @param length 时长,long类型
  464. */
  465. @Override
  466. public void setLength(long length) {
  467. if (length>0){
  468. mLength.setVisibility(VISIBLE);
  469. mLength.setText(VideoPlayerUtils.formatTime(length));
  470. } else {
  471. mLength.setVisibility(GONE);
  472. }
  473. }
  474. /**
  475. * 设置视频时长
  476. * @param length 时长,String类型
  477. */
  478. @Override
  479. public void setLength(String length) {
  480. if (length!=null && length.length()>0){
  481. mLength.setVisibility(VISIBLE);
  482. mLength.setText(length);
  483. } else {
  484. mLength.setVisibility(GONE);
  485. }
  486. }
  487. /**
  488. * 设置播放器
  489. * @param videoPlayer 播放器
  490. */
  491. @Override
  492. public void setVideoPlayer(InterVideoPlayer videoPlayer) {
  493. super.setVideoPlayer(videoPlayer);
  494. // 给播放器配置视频链接地址
  495. if (clarities != null && clarities.size() > 1 && clarities.size()>defaultClarityIndex) {
  496. mVideoPlayer.setUp(clarities.get(defaultClarityIndex).getVideoUrl(), null);
  497. }
  498. }
  499. /**
  500. * 设置top到顶部的距离
  501. * @param top top
  502. */
  503. @Override
  504. public void setTopPadding(float top) {
  505. //如果设置0,则模式是10dp
  506. if (top==0){
  507. top = 10.0f;
  508. }
  509. mTop.setPadding(VideoPlayerUtils.dp2px(mContext,10.0f),
  510. VideoPlayerUtils.dp2px(mContext,top),
  511. VideoPlayerUtils.dp2px(mContext,10.0f), 0);
  512. mTop.invalidate();
  513. }
  514. /**
  515. * 获取是否是锁屏模式
  516. * @return true表示锁屏
  517. */
  518. @Override
  519. public boolean getLock() {
  520. return mIsLock;
  521. }
  522. /**
  523. * 如果锁屏,则屏蔽滑动事件
  524. */
  525. @Override
  526. public boolean onTouchEvent(MotionEvent event) {
  527. VideoLogUtil.i("如果锁屏2,则屏蔽返回键");
  528. //如果锁屏了,那就就不需要处理滑动的逻辑
  529. return !getLock() && super.onTouchEvent(event);
  530. }
  531. /**
  532. * 设置视频清晰度
  533. * @param clarities 清晰度
  534. * @param defaultClarityIndex 默认清晰度
  535. */
  536. public void setClarity(final List<VideoClarity> clarities, int defaultClarityIndex) {
  537. if (clarities != null && clarities.size() > 1) {
  538. this.clarities = clarities;
  539. this.defaultClarityIndex = defaultClarityIndex;
  540. List<String> clarityGrades = new ArrayList<>();
  541. for (VideoClarity clarity : clarities) {
  542. clarityGrades.add(clarity.getGrade() + " " + clarity.getP());
  543. }
  544. mClarity.setText(clarities.get(defaultClarityIndex).getGrade());
  545. // 初始化切换清晰度对话框
  546. mClarityDialog = new ChangeClarityDialog(mContext);
  547. mClarityDialog.setClarityGrade(clarityGrades, defaultClarityIndex);
  548. mClarityDialog.setOnClarityCheckedListener(new OnClarityChangedListener() {
  549. @Override
  550. public void onClarityChanged(int clarityIndex) {
  551. // 根据切换后的清晰度索引值,设置对应的视频链接地址,并从当前播放位置接着播放
  552. VideoClarity clarity = clarities.get(clarityIndex);
  553. mClarity.setText(clarity.getGrade());
  554. long currentPosition = mVideoPlayer.getCurrentPosition();
  555. //释放播放器
  556. mVideoPlayer.releasePlayer();
  557. //设置视频Url,以及headers
  558. mVideoPlayer.setUp(clarity.getVideoUrl(), null);
  559. //开始从此位置播放
  560. mVideoPlayer.start(currentPosition);
  561. }
  562. @Override
  563. public void onClarityNotChanged() {
  564. // 清晰度没有变化,对话框消失后,需要重新显示出top、bottom
  565. setTopBottomVisible(true);
  566. }
  567. });
  568. // 给播放器配置视频链接地址
  569. if (mVideoPlayer != null) {
  570. mVideoPlayer.setUp(clarities.get(defaultClarityIndex).getVideoUrl(), null);
  571. }
  572. }
  573. }
  574. /**
  575. * 当播放状态发生改变时
  576. * @param playState 播放状态:
  577. */
  578. @SuppressLint("SetTextI18n")
  579. @Override
  580. public void onPlayStateChanged(int playState) {
  581. switch (playState) {
  582. case ConstantKeys.CurrentState.STATE_IDLE:
  583. break;
  584. //播放准备中
  585. case ConstantKeys.CurrentState.STATE_PREPARING:
  586. startPreparing();
  587. break;
  588. //播放准备就绪
  589. case ConstantKeys.CurrentState.STATE_PREPARED:
  590. startUpdateProgressTimer();
  591. //取消缓冲时更新网络加载速度
  592. cancelUpdateNetSpeedTimer();
  593. break;
  594. //正在播放
  595. case ConstantKeys.CurrentState.STATE_PLAYING:
  596. statePlaying();
  597. break;
  598. //暂停播放
  599. case ConstantKeys.CurrentState.STATE_PAUSED:
  600. statePaused();
  601. break;
  602. //正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复播放)
  603. case ConstantKeys.CurrentState.STATE_BUFFERING_PLAYING:
  604. stateBufferingPlaying();
  605. break;
  606. //暂停缓冲
  607. case ConstantKeys.CurrentState.STATE_BUFFERING_PAUSED:
  608. stateBufferingPaused();
  609. break;
  610. //播放错误
  611. case ConstantKeys.CurrentState.STATE_ERROR:
  612. stateError();
  613. break;
  614. //播放完成
  615. case ConstantKeys.CurrentState.STATE_COMPLETED:
  616. stateCompleted();
  617. break;
  618. default:
  619. break;
  620. }
  621. }
  622. /**
  623. * 播放准备中
  624. */
  625. private void startPreparing() {
  626. mLoading.setVisibility(View.VISIBLE);
  627. mLoadText.setText("正在准备...");
  628. mImage.setVisibility(View.GONE);
  629. mError.setVisibility(View.GONE);
  630. mCompleted.setVisibility(View.GONE);
  631. mCenterStart.setVisibility(View.GONE);
  632. mLength.setVisibility(View.GONE);
  633. mPbPlayBar.setVisibility(GONE);
  634. setTopBottomVisible(false);
  635. //开启缓冲时更新网络加载速度
  636. startUpdateNetSpeedTimer();
  637. startUpdateProgressTimer();
  638. }
  639. /**
  640. * 正在播放
  641. */
  642. private void statePlaying() {
  643. mLoading.setVisibility(View.GONE);
  644. mPbPlayBar.setVisibility(View.VISIBLE);
  645. mRestartPause.setImageResource(R.drawable.ic_player_pause);
  646. mCenterStart.setImageResource(R.drawable.icon_pause_center);
  647. setTopBottomVisible(true);
  648. startDismissTopBottomTimer();
  649. cancelUpdateNetSpeedTimer();
  650. }
  651. /**
  652. * 暂停播放
  653. */
  654. private void statePaused() {
  655. mLoading.setVisibility(View.GONE);
  656. mRestartPause.setImageResource(R.drawable.ic_player_start);
  657. mCenterStart.setImageResource(R.drawable.icon_play_center);
  658. setTopBottomVisible(true);
  659. cancelDismissTopBottomTimer();
  660. cancelUpdateNetSpeedTimer();
  661. }
  662. /**
  663. * 正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复播放)
  664. */
  665. private void stateBufferingPlaying() {
  666. mLoading.setVisibility(View.VISIBLE);
  667. setTopBottomVisible(false);
  668. mRestartPause.setImageResource(R.drawable.ic_player_pause);
  669. mCenterStart.setImageResource(R.drawable.icon_pause_center);
  670. mLoadText.setText("正在准备...");
  671. startDismissTopBottomTimer();
  672. cancelUpdateNetSpeedTimer();
  673. }
  674. /**
  675. * 暂停缓冲
  676. */
  677. private void stateBufferingPaused() {
  678. mLoading.setVisibility(View.VISIBLE);
  679. mRestartPause.setImageResource(R.drawable.ic_player_start);
  680. mCenterStart.setImageResource(R.drawable.icon_play_center);
  681. mLoadText.setText("正在准备...");
  682. setTopBottomVisible(false);
  683. cancelDismissTopBottomTimer();
  684. //开启缓冲时更新网络加载速度
  685. startUpdateNetSpeedTimer();
  686. }
  687. /**
  688. * 播放错误
  689. */
  690. private void stateError() {
  691. setTopBottomVisible(false);
  692. mError.setVisibility(View.VISIBLE);
  693. cancelUpdateProgressTimer();
  694. cancelUpdateNetSpeedTimer();
  695. if (!VideoPlayerUtils.isConnected(mContext)){
  696. mTvError.setText("没有网络,请链接网络");
  697. } else {
  698. mTvError.setText("播放错误,请重试");
  699. }
  700. }
  701. /**
  702. * 播放完成
  703. */
  704. private void stateCompleted() {
  705. cancelUpdateProgressTimer();
  706. cancelUpdateNetSpeedTimer();
  707. setTopBottomVisible(false);
  708. mImage.setVisibility(View.VISIBLE);
  709. mCompleted.setVisibility(View.VISIBLE);
  710. //设置播放完成的监听事件
  711. if(mOnCompletedListener!=null){
  712. mOnCompletedListener.onCompleted();
  713. }
  714. mPbPlayBar.setProgress(100);
  715. //当播放完成就解除广播
  716. unRegisterNetChangedReceiver();
  717. }
  718. /**
  719. * 当播放器的播放模式发生变化时
  720. * @param playMode 播放器的模式:
  721. */
  722. @Override
  723. public void onPlayModeChanged(int playMode) {
  724. switch (playMode) {
  725. //普通模式
  726. case ConstantKeys.PlayMode.MODE_NORMAL:
  727. //隐藏锁屏控件
  728. mFlLock.setVisibility(View.GONE);
  729. mBack.setVisibility(View.VISIBLE);
  730. mFullScreen.setImageResource(R.drawable.ic_player_open);
  731. mFullScreen.setVisibility(View.VISIBLE);
  732. //隐藏清晰度
  733. mClarity.setVisibility(View.GONE);
  734. setTopVisibility(mIsTopLayoutVisibility);
  735. //隐藏横屏的时候展现的布局
  736. setTopVisibility(false);
  737. mLlHorizontal.setVisibility(View.GONE);
  738. unRegisterBatterReceiver();
  739. mIsLock = false;
  740. if (mOnPlayerTypeListener!=null){
  741. mOnPlayerTypeListener.onNormal();
  742. }
  743. //隐藏电量图标
  744. mBattery.setVisibility(GONE);
  745. setTopVisibility(mIsTopLayoutVisibility);
  746. VideoLogUtil.d("播放模式--------普通模式");
  747. break;
  748. //全屏模式
  749. case ConstantKeys.PlayMode.MODE_FULL_SCREEN:
  750. mFlLock.setVisibility(View.VISIBLE);
  751. mBack.setVisibility(View.VISIBLE);
  752. mFullScreen.setVisibility(View.VISIBLE);
  753. mFullScreen.setImageResource(R.drawable.ic_player_close);
  754. if (clarities != null && clarities.size() > 1) {
  755. mClarity.setVisibility(View.VISIBLE);
  756. }
  757. setTopVisibility(false);
  758. mLlHorizontal.setVisibility(View.VISIBLE);
  759. mIvHorTv.setVisibility(mIsTvIconVisibility?VISIBLE:GONE);
  760. mIvHorAudio.setVisibility(mIsAudioIconVisibility?VISIBLE:GONE);
  761. registerBatterReceiver();
  762. if (mOnPlayerTypeListener!=null){
  763. mOnPlayerTypeListener.onFullScreen();
  764. }
  765. VideoLogUtil.d("播放模式--------全屏模式");
  766. break;
  767. //小窗口模式
  768. case ConstantKeys.PlayMode.MODE_TINY_WINDOW:
  769. mFlLock.setVisibility(View.GONE);
  770. mBack.setVisibility(View.VISIBLE);
  771. mClarity.setVisibility(View.GONE);
  772. mLlHorizontal.setVisibility(View.GONE);
  773. setTopVisibility(false);
  774. mIsLock = false;
  775. if (mOnPlayerTypeListener!=null){
  776. mOnPlayerTypeListener.onTinyWindow();
  777. }
  778. VideoLogUtil.d("播放模式--------小窗口模式");
  779. break;
  780. default:
  781. break;
  782. }
  783. }
  784. /**
  785. * 重新设置
  786. */
  787. @Override
  788. public void reset() {
  789. topBottomVisible = false;
  790. cancelUpdateProgressTimer();
  791. cancelDismissTopBottomTimer();
  792. mSeek.setProgress(0);
  793. mSeek.setSecondaryProgress(0);
  794. mPbPlayBar.setProgress(0);
  795. mCenterStart.setVisibility(VISIBLE);
  796. mLength.setVisibility(View.VISIBLE);
  797. mFlLock.setVisibility(View.GONE);
  798. mImage.setVisibility(View.VISIBLE);
  799. mBottom.setVisibility(View.GONE);
  800. mFullScreen.setImageResource(R.drawable.ic_player_open);
  801. mTop.setVisibility(View.VISIBLE);
  802. mBack.setVisibility(View.VISIBLE);
  803. mLoading.setVisibility(View.GONE);
  804. mError.setVisibility(View.GONE);
  805. mCompleted.setVisibility(View.GONE);
  806. }
  807. /**
  808. * 注意:跟重置有区别
  809. * 控制器意外销毁,比如手动退出,意外崩溃等等
  810. */
  811. @Override
  812. public void destroy() {
  813. //当播放完成就解除广播
  814. unRegisterNetChangedReceiver();
  815. unRegisterBatterReceiver();
  816. //结束timer
  817. cancelUpdateProgressTimer();
  818. cancelUpdateNetSpeedTimer();
  819. }
  820. /**
  821. * 尽量不要在onClick中直接处理控件的隐藏、显示及各种UI逻辑。
  822. * UI相关的逻辑都尽量到{@link #onPlayStateChanged}和{@link #onPlayModeChanged}中处理.
  823. */
  824. @Override
  825. public void onClick(View v) {
  826. if (v == mCenterStart) {
  827. //开始播放
  828. startVideo();
  829. } else if (v == mBack) {
  830. //退出,执行返回逻辑
  831. //如果是全屏,则先退出全屏
  832. if (mVideoPlayer.isFullScreen()) {
  833. mVideoPlayer.exitFullScreen();
  834. } else if (mVideoPlayer.isTinyWindow()) {
  835. //如果是小窗口,则退出小窗口
  836. mVideoPlayer.exitTinyWindow();
  837. }else {
  838. //如果两种情况都不是,执行逻辑交给使用者自己实现
  839. if(mBackListener!=null){
  840. mBackListener.onBackClick();
  841. }else {
  842. VideoLogUtil.d("返回键逻辑,如果是全屏,则先退出全屏;如果是小窗口,则退出小窗口;如果两种情况都不是,执行逻辑交给使用者自己实现");
  843. }
  844. }
  845. } else if (v == mRestartPause) {
  846. if(VideoPlayerUtils.isConnected(mContext)){
  847. //重新播放或者暂停
  848. if (mVideoPlayer.isPlaying() || mVideoPlayer.isBufferingPlaying()) {
  849. mVideoPlayer.pause();
  850. if(mOnPlayOrPauseListener!=null){
  851. mOnPlayOrPauseListener.onPlayOrPauseClick(true);
  852. }
  853. } else if (mVideoPlayer.isPaused() || mVideoPlayer.isBufferingPaused()) {
  854. mVideoPlayer.restart();
  855. if(mOnPlayOrPauseListener!=null){
  856. mOnPlayOrPauseListener.onPlayOrPauseClick(false);
  857. }
  858. }
  859. }else {
  860. BaseToast.showRoundRectToast("请检测是否有网络");
  861. }
  862. } else if (v == mFullScreen) {
  863. //全屏模式,重置锁屏,设置为未选中状态
  864. if (mVideoPlayer.isNormal() || mVideoPlayer.isTinyWindow()) {
  865. mFlLock.setVisibility(VISIBLE);
  866. mIsLock = false;
  867. mIvLock.setImageResource(R.drawable.player_unlock_btn);
  868. mVideoPlayer.enterFullScreen();
  869. } else if (mVideoPlayer.isFullScreen()) {
  870. mFlLock.setVisibility(GONE);
  871. mVideoPlayer.exitFullScreen();
  872. }
  873. } else if (v == mClarity) {
  874. //设置清晰度
  875. //隐藏top、bottom
  876. setTopBottomVisible(false);
  877. //显示清晰度对话框
  878. mClarityDialog.show();
  879. } else if (v == mRetry) {
  880. //点击重试
  881. if(VideoPlayerUtils.isConnected(mContext)){
  882. startPreparing();
  883. //开始从此位置播放
  884. mVideoPlayer.restart();
  885. }else {
  886. BaseToast.showRoundRectToast("请检测是否有网络");
  887. }
  888. } else if (v == mReplay) {
  889. //重新播放
  890. if(VideoPlayerUtils.isConnected(mContext)){
  891. mRetry.performClick();
  892. }else {
  893. BaseToast.showRoundRectToast("请检测是否有网络");
  894. }
  895. } else if (v == mShare) {
  896. //分享
  897. if(mVideoControlListener==null){
  898. VideoLogUtil.d("请在初始化的时候设置分享监听事件");
  899. return;
  900. }
  901. //点击下载
  902. mVideoControlListener.onVideoControlClick(ConstantKeys.VideoControl.SHARE);
  903. } else if(v == mFlLock){
  904. //点击锁屏按钮,则进入锁屏模式
  905. setLock(mIsLock);
  906. } else if(v == mIvDownload){
  907. if(mVideoControlListener==null){
  908. VideoLogUtil.d("请在初始化的时候设置下载监听事件");
  909. return;
  910. }
  911. //点击下载
  912. mVideoControlListener.onVideoControlClick(ConstantKeys.VideoControl.DOWNLOAD);
  913. } else if(v == mIvAudio){
  914. if(mVideoControlListener==null){
  915. VideoLogUtil.d("请在初始化的时候设置切换监听事件");
  916. return;
  917. }
  918. //点击切换音频
  919. mVideoControlListener.onVideoControlClick(ConstantKeys.VideoControl.AUDIO);
  920. }else if(v == mIvShare){
  921. if(mVideoControlListener==null){
  922. VideoLogUtil.d("请在初始化的时候设置分享监听事件");
  923. return;
  924. }
  925. //点击分享
  926. mVideoControlListener.onVideoControlClick(ConstantKeys.VideoControl.SHARE);
  927. }else if(v == mIvMenu){
  928. if(mVideoControlListener==null){
  929. VideoLogUtil.d("请在初始化的时候设置分享监听事件");
  930. return;
  931. }
  932. //点击菜单
  933. mVideoControlListener.onVideoControlClick(ConstantKeys.VideoControl.MENU);
  934. }else if(v == mIvHorAudio){
  935. if(mVideoControlListener==null){
  936. VideoLogUtil.d("请在初始化的时候设置横向音频监听事件");
  937. return;
  938. }
  939. //点击横向音频
  940. mVideoControlListener.onVideoControlClick(ConstantKeys.VideoControl.HOR_AUDIO);
  941. }else if(v == mIvHorTv){
  942. if(mVideoControlListener==null){
  943. VideoLogUtil.d("请在初始化的时候设置横向Tv监听事件");
  944. return;
  945. }
  946. //点击横向TV
  947. mVideoControlListener.onVideoControlClick(ConstantKeys.VideoControl.TV);
  948. } else if (v == this) {
  949. if (mVideoPlayer.isPlaying() || mVideoPlayer.isPaused()
  950. || mVideoPlayer.isBufferingPlaying() || mVideoPlayer.isBufferingPaused()) {
  951. setTopBottomVisible(!topBottomVisible);
  952. }
  953. }
  954. }
  955. /**
  956. * 开始播放
  957. */
  958. public void startVideo() {
  959. //开始播放
  960. if (mVideoPlayer.isIdle()) {
  961. mVideoPlayer.start();
  962. }else if (mVideoPlayer.isPlaying() || mVideoPlayer.isBufferingPlaying()) {
  963. mVideoPlayer.pause();
  964. } else if (mVideoPlayer.isPaused() || mVideoPlayer.isBufferingPaused()) {
  965. mVideoPlayer.restart();
  966. }
  967. }
  968. /**
  969. * 当电量发生变化的时候,在此方法中国你更新不同的电量状态的UI
  970. *
  971. * @param batterState 电量状态
  972. */
  973. @Override
  974. public void onBatterStateChanged(@ConstantKeys.BatterMode int batterState) {
  975. switch (batterState){
  976. case ConstantKeys.BatterMode.BATTERY_10:
  977. mBattery.setImageResource(R.drawable.battery_10);
  978. break;
  979. case ConstantKeys.BatterMode.BATTERY_20:
  980. mBattery.setImageResource(R.drawable.battery_20);
  981. break;
  982. case ConstantKeys.BatterMode.BATTERY_50:
  983. mBattery.setImageResource(R.drawable.battery_50);
  984. break;
  985. case ConstantKeys.BatterMode.BATTERY_80:
  986. mBattery.setImageResource(R.drawable.battery_80);
  987. break;
  988. case ConstantKeys.BatterMode.BATTERY_100:
  989. mBattery.setImageResource(R.drawable.battery_100);
  990. break;
  991. case ConstantKeys.BatterMode.BATTERY_FULL:
  992. mBattery.setImageResource(R.drawable.battery_full);
  993. break;
  994. case ConstantKeys.BatterMode.BATTERY_CHARGING:
  995. mBattery.setImageResource(R.drawable.battery_charging);
  996. break;
  997. default:
  998. break;
  999. }
  1000. }
  1001. /**
  1002. * 设置top、bottom的显示和隐藏
  1003. * @param visible true显示,false隐藏.
  1004. */
  1005. private void setTopBottomVisible(boolean visible) {
  1006. mTop.setVisibility(visible ? View.VISIBLE : View.GONE);
  1007. mBottom.setVisibility(visible ? View.VISIBLE : View.GONE);
  1008. mLine.setVisibility(visible ? View.GONE : View.VISIBLE);
  1009. mCenterStart.setVisibility(visible ? View.VISIBLE : View.GONE);
  1010. topBottomVisible = visible;
  1011. if (visible) {
  1012. if (!mVideoPlayer.isPaused() && !mVideoPlayer.isBufferingPaused()) {
  1013. startDismissTopBottomTimer();
  1014. }
  1015. } else {
  1016. cancelDismissTopBottomTimer();
  1017. }
  1018. }
  1019. /**
  1020. * 开启top、bottom自动消失的timer
  1021. * 比如,视频常用功能,当用户5秒不操作后,自动隐藏头部和顶部
  1022. */
  1023. private void startDismissTopBottomTimer() {
  1024. if(time==0){
  1025. time = 8000;
  1026. }
  1027. cancelDismissTopBottomTimer();
  1028. if (mDismissTopBottomCountDownTimer == null) {
  1029. //CountDownTimer定时器
  1030. mDismissTopBottomCountDownTimer = new CountDownTimer(time, time) {
  1031. @Override
  1032. public void onTick(long millisUntilFinished) {
  1033. }
  1034. @Override
  1035. public void onFinish() {
  1036. setTopBottomVisible(false);
  1037. }
  1038. };
  1039. }
  1040. mDismissTopBottomCountDownTimer.start();
  1041. }
  1042. /**
  1043. * 取消top、bottom自动消失的timer
  1044. */
  1045. private void cancelDismissTopBottomTimer() {
  1046. if (mDismissTopBottomCountDownTimer != null) {
  1047. mDismissTopBottomCountDownTimer.cancel();
  1048. }
  1049. }
  1050. /**
  1051. * 设置锁屏模式,默认是未锁屏的
  1052. * 当为true时,则锁屏;否则为未锁屏
  1053. * @param isLock 是否锁屏
  1054. */
  1055. private void setLock(boolean isLock){
  1056. if(isLock){
  1057. mIsLock = false;
  1058. mIvLock.setImageResource(R.drawable.player_unlock_btn);
  1059. }else {
  1060. mIsLock = true;
  1061. mIvLock.setImageResource(R.drawable.player_locked_btn);
  1062. }
  1063. /*
  1064. * 设置锁屏时的布局
  1065. * 1.横屏全屏时显示,其他不展示;
  1066. * 2.锁屏时隐藏控制面板除锁屏按钮外其他所有控件
  1067. * 3.当从全屏切换到正常或者小窗口时,则默认不锁屏
  1068. */
  1069. setTopBottomVisible(!mIsLock);
  1070. }
  1071. /**
  1072. * 更新进度,包括更新网络加载速度
  1073. */
  1074. @SuppressLint("SetTextI18n")
  1075. @Override
  1076. protected void updateNetSpeedProgress() {
  1077. //获取网络加载速度
  1078. long tcpSpeed = mVideoPlayer.getTcpSpeed();
  1079. VideoLogUtil.i("获取网络加载速度++++++++"+tcpSpeed);
  1080. if (tcpSpeed>0){
  1081. int speed = (int) (tcpSpeed/1024);
  1082. //显示网速
  1083. mLoading.setVisibility(View.VISIBLE);
  1084. mLoadText.setText("网速"+speed+"kb");
  1085. }
  1086. }
  1087. /**
  1088. * 更新播放进度
  1089. */
  1090. @Override
  1091. protected void updateProgress() {
  1092. //获取当前播放的位置,毫秒
  1093. long position = mVideoPlayer.getCurrentPosition();
  1094. //获取办法给总时长,毫秒
  1095. long duration = mVideoPlayer.getDuration();
  1096. //获取视频缓冲百分比
  1097. int bufferPercentage = mVideoPlayer.getBufferPercentage();
  1098. mSeek.setSecondaryProgress(bufferPercentage);
  1099. int progress = (int) (100f * position / duration);
  1100. mSeek.setProgress(progress);
  1101. mPbPlayBar.setProgress(progress);
  1102. mPosition.setText(VideoPlayerUtils.formatTime(position));
  1103. mDuration.setText(VideoPlayerUtils.formatTime(duration));
  1104. // 更新时间
  1105. mTime.setText(new SimpleDateFormat("HH:mm", Locale.CHINA).format(new Date()));
  1106. long tcpSpeed = mVideoPlayer.getTcpSpeed();
  1107. VideoLogUtil.i("获取网络加载速度---------"+tcpSpeed);
  1108. }
  1109. /**
  1110. * 显示视频播放位置
  1111. * @param duration 视频总时长ms
  1112. * @param newPositionProgress 新的位置进度,取值0到100。
  1113. */
  1114. @Override
  1115. protected void showChangePosition(long duration, int newPositionProgress) {
  1116. mChangePosition.setVisibility(View.VISIBLE);
  1117. long newPosition = (long) (duration * newPositionProgress / 100f);
  1118. mChangePositionCurrent.setText(VideoPlayerUtils.formatTime(newPosition));
  1119. mChangePositionProgress.setProgress(newPositionProgress);
  1120. mSeek.setProgress(newPositionProgress);
  1121. mPbPlayBar.setProgress(newPositionProgress);
  1122. mPosition.setText(VideoPlayerUtils.formatTime(newPosition));
  1123. }
  1124. /**
  1125. * 隐藏视频播放位置
  1126. */
  1127. @Override
  1128. protected void hideChangePosition() {
  1129. //隐藏
  1130. mChangePosition.setVisibility(View.GONE);
  1131. }
  1132. /**
  1133. * 展示视频播放音量
  1134. * @param newVolumeProgress 新的音量进度,取值1到100。
  1135. */
  1136. @Override
  1137. protected void showChangeVolume(int newVolumeProgress) {
  1138. mChangeVolume.setVisibility(View.VISIBLE);
  1139. mChangeVolumeProgress.setProgress(newVolumeProgress);
  1140. }
  1141. /**
  1142. * 隐藏视频播放音量
  1143. */
  1144. @Override
  1145. protected void hideChangeVolume() {
  1146. mChangeVolume.setVisibility(View.GONE);
  1147. }
  1148. /**
  1149. * 展示视频播放亮度
  1150. * @param newBrightnessProgress 新的亮度进度,取值1到100。
  1151. */
  1152. @Override
  1153. protected void showChangeBrightness(int newBrightnessProgress) {
  1154. mChangeBrightness.setVisibility(View.VISIBLE);
  1155. mChangeBrightnessProgress.setProgress(newBrightnessProgress);
  1156. }
  1157. /**
  1158. * 隐藏视频播放亮度
  1159. */
  1160. @Override
  1161. protected void hideChangeBrightness() {
  1162. mChangeBrightness.setVisibility(View.GONE);
  1163. }
  1164. /**
  1165. * 当视频退出全屏或者退出小窗口后,再次点击返回键
  1166. * 让用户自己处理返回键事件的逻辑
  1167. * 欢迎同行交流:https://github.com/yangchong211
  1168. * 如果你觉得项目可以,欢迎star
  1169. */
  1170. private OnVideoBackListener mBackListener;
  1171. public void setOnVideoBackListener(OnVideoBackListener listener) {
  1172. this.mBackListener = listener;
  1173. }
  1174. /**
  1175. * 设置视频分享,下载,音视频转化点击事件
  1176. */
  1177. private OnVideoControlListener mVideoControlListener;
  1178. public void setOnVideoControlListener(OnVideoControlListener listener){
  1179. this.mVideoControlListener = listener;
  1180. }
  1181. /**
  1182. * 播放暂停监听事件
  1183. */
  1184. private OnPlayOrPauseListener mOnPlayOrPauseListener;
  1185. public void setOnPlayOrPauseListener(OnPlayOrPauseListener listener){
  1186. this.mOnPlayOrPauseListener = listener;
  1187. }
  1188. /**
  1189. * 监听视频播放完成事件
  1190. */
  1191. private OnCompletedListener mOnCompletedListener;
  1192. public void setOnCompletedListener(OnCompletedListener listener){
  1193. this.mOnCompletedListener = listener;
  1194. }
  1195. /**
  1196. * 视频播放模式监听
  1197. */
  1198. private OnPlayerTypeListener mOnPlayerTypeListener;
  1199. public void setOnPlayerTypeListener(OnPlayerTypeListener listener){
  1200. this.mOnPlayerTypeListener = listener;
  1201. }
  1202. }