暫無描述

ZFPlayerControlView.m 43KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  1. //
  2. // ZFPlayerControlView.m
  3. //
  4. // Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. #import "ZFPlayerControlView.h"
  24. #import <AVFoundation/AVFoundation.h>
  25. #import <MediaPlayer/MediaPlayer.h>
  26. #import "UIView+CustomControlView.h"
  27. #import "MMMaterialDesignSpinner.h"
  28. #pragma clang diagnostic push
  29. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  30. static const CGFloat ZFPlayerAnimationTimeInterval = 7.0f;
  31. static const CGFloat ZFPlayerControlBarAutoFadeOutTimeInterval = 0.35f;
  32. @interface ZFPlayerControlView () <UIGestureRecognizerDelegate>
  33. /** 标题 */
  34. @property (nonatomic, strong) UILabel *titleLabel;
  35. /** 开始播放按钮 */
  36. @property (nonatomic, strong) UIButton *startBtn;
  37. /** 当前播放时长label */
  38. @property (nonatomic, strong) UILabel *currentTimeLabel;
  39. /** 视频总时长label */
  40. @property (nonatomic, strong) UILabel *totalTimeLabel;
  41. /** 缓冲进度条 */
  42. @property (nonatomic, strong) UIProgressView *progressView;
  43. /** 滑杆 */
  44. @property (nonatomic, strong) ASValueTrackingSlider *videoSlider;
  45. /** 全屏按钮 */
  46. @property (nonatomic, strong) UIButton *fullScreenBtn;
  47. /** 锁定屏幕方向按钮 */
  48. @property (nonatomic, strong) UIButton *lockBtn;
  49. /** 系统菊花 */
  50. @property (nonatomic, strong) MMMaterialDesignSpinner *activity;
  51. /** 返回按钮*/
  52. @property (nonatomic, strong) UIButton *backBtn;
  53. /** 关闭按钮*/
  54. @property (nonatomic, strong) UIButton *closeBtn;
  55. /** 重播按钮 */
  56. @property (nonatomic, strong) UIButton *repeatBtn;
  57. /** bottomView*/
  58. @property (nonatomic, strong) UIImageView *bottomImageView;
  59. /** topView */
  60. @property (nonatomic, strong) UIImageView *topImageView;
  61. /** 缓存按钮 */
  62. @property (nonatomic, strong) UIButton *downLoadBtn;
  63. /** 切换分辨率按钮 */
  64. @property (nonatomic, strong) UIButton *resolutionBtn;
  65. /** 分辨率的View */
  66. @property (nonatomic, strong) UIView *resolutionView;
  67. /** 播放按钮 */
  68. @property (nonatomic, strong) UIButton *playeBtn;
  69. /** 加载失败按钮 */
  70. @property (nonatomic, strong) UIButton *failBtn;
  71. /** 快进快退View*/
  72. @property (nonatomic, strong) UIView *fastView;
  73. /** 快进快退进度progress*/
  74. @property (nonatomic, strong) UIProgressView *fastProgressView;
  75. /** 快进快退时间*/
  76. @property (nonatomic, strong) UILabel *fastTimeLabel;
  77. /** 快进快退ImageView*/
  78. @property (nonatomic, strong) UIImageView *fastImageView;
  79. /** 当前选中的分辨率btn按钮 */
  80. @property (nonatomic, weak ) UIButton *resoultionCurrentBtn;
  81. /** 占位图 */
  82. @property (nonatomic, strong) UIImageView *placeholderImageView;
  83. /** 控制层消失时候在底部显示的播放进度progress */
  84. @property (nonatomic, strong) UIProgressView *bottomProgressView;
  85. /** 分辨率的名称 */
  86. @property (nonatomic, strong) NSArray *resolutionArray;
  87. /** 显示控制层 */
  88. @property (nonatomic, assign, getter=isShowing) BOOL showing;
  89. /** 小屏播放 */
  90. @property (nonatomic, assign, getter=isShrink ) BOOL shrink;
  91. /** 在cell上播放 */
  92. @property (nonatomic, assign, getter=isCellVideo)BOOL cellVideo;
  93. /** 是否拖拽slider控制播放进度 */
  94. @property (nonatomic, assign, getter=isDragged) BOOL dragged;
  95. /** 是否播放结束 */
  96. @property (nonatomic, assign, getter=isPlayEnd) BOOL playeEnd;
  97. /** 是否全屏播放 */
  98. @property (nonatomic, assign,getter=isFullScreen)BOOL fullScreen;
  99. @end
  100. @implementation ZFPlayerControlView
  101. - (instancetype)init {
  102. self = [super init];
  103. if (self) {
  104. [self addSubview:self.placeholderImageView];
  105. [self addSubview:self.topImageView];
  106. [self addSubview:self.bottomImageView];
  107. [self.bottomImageView addSubview:self.startBtn];
  108. [self.bottomImageView addSubview:self.currentTimeLabel];
  109. [self.bottomImageView addSubview:self.progressView];
  110. [self.bottomImageView addSubview:self.videoSlider];
  111. [self.bottomImageView addSubview:self.fullScreenBtn];
  112. [self.bottomImageView addSubview:self.totalTimeLabel];
  113. [self.topImageView addSubview:self.downLoadBtn];
  114. [self addSubview:self.lockBtn];
  115. [self.topImageView addSubview:self.backBtn];
  116. [self addSubview:self.activity];
  117. [self addSubview:self.repeatBtn];
  118. [self addSubview:self.playeBtn];
  119. [self addSubview:self.failBtn];
  120. [self addSubview:self.fastView];
  121. [self.fastView addSubview:self.fastImageView];
  122. [self.fastView addSubview:self.fastTimeLabel];
  123. [self.fastView addSubview:self.fastProgressView];
  124. [self.topImageView addSubview:self.resolutionBtn];
  125. [self.topImageView addSubview:self.titleLabel];
  126. [self addSubview:self.closeBtn];
  127. [self addSubview:self.bottomProgressView];
  128. // 添加子控件的约束
  129. [self makeSubViewsConstraints];
  130. self.downLoadBtn.hidden = YES;
  131. self.resolutionBtn.hidden = YES;
  132. // 初始化时重置controlView
  133. [self zf_playerResetControlView];
  134. // app退到后台
  135. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationWillResignActiveNotification object:nil];
  136. // app进入前台
  137. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterPlayground) name:UIApplicationDidBecomeActiveNotification object:nil];
  138. [self listeningRotating];
  139. }
  140. return self;
  141. }
  142. - (void)dealloc {
  143. [[NSNotificationCenter defaultCenter] removeObserver:self];
  144. [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
  145. }
  146. - (void)makeSubViewsConstraints {
  147. [self.placeholderImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  148. make.edges.mas_equalTo(UIEdgeInsetsZero);
  149. }];
  150. [self.closeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  151. make.trailing.equalTo(self.mas_trailing).offset(7);
  152. make.top.equalTo(self.mas_top).offset(-7);
  153. make.width.height.mas_equalTo(20);
  154. }];
  155. [self.topImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  156. make.leading.trailing.equalTo(self);
  157. make.top.equalTo(self.mas_top).offset(0);
  158. make.height.mas_equalTo(50);
  159. }];
  160. [self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  161. make.leading.equalTo(self.topImageView.mas_leading).offset(10);
  162. make.top.equalTo(self.topImageView.mas_top).offset(3);
  163. make.width.height.mas_equalTo(40);
  164. }];
  165. [self.downLoadBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  166. make.width.mas_equalTo(40);
  167. make.height.mas_equalTo(49);
  168. make.trailing.equalTo(self.topImageView.mas_trailing).offset(-10);
  169. make.centerY.equalTo(self.backBtn.mas_centerY);
  170. }];
  171. [self.resolutionBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  172. make.width.mas_equalTo(40);
  173. make.height.mas_equalTo(25);
  174. make.trailing.equalTo(self.downLoadBtn.mas_leading).offset(-10);
  175. make.centerY.equalTo(self.backBtn.mas_centerY);
  176. }];
  177. [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  178. make.leading.equalTo(self.backBtn.mas_trailing).offset(5);
  179. make.centerY.equalTo(self.backBtn.mas_centerY);
  180. make.trailing.equalTo(self.resolutionBtn.mas_leading).offset(-10);
  181. }];
  182. [self.bottomImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  183. make.leading.trailing.bottom.mas_equalTo(0);
  184. make.height.mas_equalTo(50);
  185. }];
  186. [self.startBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  187. make.leading.equalTo(self.bottomImageView.mas_leading).offset(5);
  188. make.bottom.equalTo(self.bottomImageView.mas_bottom).offset(-5);
  189. make.width.height.mas_equalTo(30);
  190. }];
  191. [self.currentTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  192. make.leading.equalTo(self.startBtn.mas_trailing).offset(-3);
  193. make.centerY.equalTo(self.startBtn.mas_centerY);
  194. make.width.mas_equalTo(43);
  195. }];
  196. [self.fullScreenBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  197. make.width.height.mas_equalTo(30);
  198. make.trailing.equalTo(self.bottomImageView.mas_trailing).offset(-5);
  199. make.centerY.equalTo(self.startBtn.mas_centerY);
  200. }];
  201. [self.totalTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  202. make.trailing.equalTo(self.fullScreenBtn.mas_leading).offset(3);
  203. make.centerY.equalTo(self.startBtn.mas_centerY);
  204. make.width.mas_equalTo(43);
  205. }];
  206. [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) {
  207. make.leading.equalTo(self.currentTimeLabel.mas_trailing).offset(4);
  208. make.trailing.equalTo(self.totalTimeLabel.mas_leading).offset(-4);
  209. make.centerY.equalTo(self.startBtn.mas_centerY);
  210. }];
  211. [self.videoSlider mas_makeConstraints:^(MASConstraintMaker *make) {
  212. make.leading.equalTo(self.currentTimeLabel.mas_trailing).offset(4);
  213. make.trailing.equalTo(self.totalTimeLabel.mas_leading).offset(-4);
  214. make.centerY.equalTo(self.currentTimeLabel.mas_centerY).offset(-1);
  215. make.height.mas_equalTo(30);
  216. }];
  217. [self.lockBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  218. make.leading.equalTo(self.mas_leading).offset(15);
  219. make.centerY.equalTo(self.mas_centerY);
  220. make.width.height.mas_equalTo(32);
  221. }];
  222. [self.repeatBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  223. make.center.equalTo(self);
  224. }];
  225. [self.playeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  226. make.width.height.mas_equalTo(50);
  227. make.center.equalTo(self);
  228. }];
  229. [self.activity mas_makeConstraints:^(MASConstraintMaker *make) {
  230. make.center.equalTo(self);
  231. make.width.with.height.mas_equalTo(45);
  232. }];
  233. [self.failBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  234. make.center.equalTo(self);
  235. make.width.mas_equalTo(130);
  236. make.height.mas_equalTo(33);
  237. }];
  238. [self.fastView mas_makeConstraints:^(MASConstraintMaker *make) {
  239. make.width.mas_equalTo(125);
  240. make.height.mas_equalTo(80);
  241. make.center.equalTo(self);
  242. }];
  243. [self.fastImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  244. make.width.mas_offset(32);
  245. make.height.mas_offset(32);
  246. make.top.mas_equalTo(5);
  247. make.centerX.mas_equalTo(self.fastView.mas_centerX);
  248. }];
  249. [self.fastTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  250. make.leading.with.trailing.mas_equalTo(0);
  251. make.top.mas_equalTo(self.fastImageView.mas_bottom).offset(2);
  252. }];
  253. [self.fastProgressView mas_makeConstraints:^(MASConstraintMaker *make) {
  254. make.leading.mas_equalTo(12);
  255. make.trailing.mas_equalTo(-12);
  256. make.top.mas_equalTo(self.fastTimeLabel.mas_bottom).offset(10);
  257. }];
  258. [self.bottomProgressView mas_makeConstraints:^(MASConstraintMaker *make) {
  259. make.leading.trailing.mas_offset(0);
  260. make.bottom.mas_offset(0);
  261. }];
  262. }
  263. - (void)layoutSubviews {
  264. [super layoutSubviews];
  265. UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
  266. if (currentOrientation == UIDeviceOrientationPortrait) {
  267. [self setOrientationPortraitConstraint];
  268. } else {
  269. [self setOrientationLandscapeConstraint];
  270. }
  271. }
  272. #pragma mark - Action
  273. /**
  274. * 点击切换分别率按钮
  275. */
  276. - (void)changeResolution:(UIButton *)sender {
  277. sender.selected = YES;
  278. if (sender.isSelected) {
  279. sender.backgroundColor = RGBA(86, 143, 232, 1);
  280. } else {
  281. sender.backgroundColor = [UIColor clearColor];
  282. }
  283. self.resoultionCurrentBtn.selected = NO;
  284. self.resoultionCurrentBtn.backgroundColor = [UIColor clearColor];
  285. self.resoultionCurrentBtn = sender;
  286. // 隐藏分辨率View
  287. self.resolutionView.hidden = YES;
  288. // 分辨率Btn改为normal状态
  289. self.resolutionBtn.selected = NO;
  290. // topImageView上的按钮的文字
  291. [self.resolutionBtn setTitle:sender.titleLabel.text forState:UIControlStateNormal];
  292. if ([self.delegate respondsToSelector:@selector(zf_controlView:resolutionAction:)]) {
  293. [self.delegate zf_controlView:self resolutionAction:sender];
  294. }
  295. }
  296. /**
  297. * UISlider TapAction
  298. */
  299. - (void)tapSliderAction:(UITapGestureRecognizer *)tap {
  300. if ([tap.view isKindOfClass:[UISlider class]]) {
  301. UISlider *slider = (UISlider *)tap.view;
  302. CGPoint point = [tap locationInView:slider];
  303. CGFloat length = slider.frame.size.width;
  304. // 视频跳转的value
  305. CGFloat tapValue = point.x / length;
  306. if ([self.delegate respondsToSelector:@selector(zf_controlView:progressSliderTap:)]) {
  307. [self.delegate zf_controlView:self progressSliderTap:tapValue];
  308. }
  309. }
  310. }
  311. // 不做处理,只是为了滑动slider其他地方不响应其他手势
  312. - (void)panRecognizer:(UIPanGestureRecognizer *)sender {}
  313. - (void)backBtnClick:(UIButton *)sender {
  314. // 状态条的方向旋转的方向,来判断当前屏幕的方向
  315. UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
  316. // 在cell上并且是竖屏时候响应关闭事件
  317. if (self.isCellVideo && orientation == UIInterfaceOrientationPortrait) {
  318. if ([self.delegate respondsToSelector:@selector(zf_controlView:closeAction:)]) {
  319. [self.delegate zf_controlView:self closeAction:sender];
  320. }
  321. } else {
  322. if ([self.delegate respondsToSelector:@selector(zf_controlView:backAction:)]) {
  323. [self.delegate zf_controlView:self backAction:sender];
  324. }
  325. }
  326. }
  327. - (void)lockScrrenBtnClick:(UIButton *)sender {
  328. sender.selected = !sender.selected;
  329. self.showing = NO;
  330. [self zf_playerShowControlView];
  331. if ([self.delegate respondsToSelector:@selector(zf_controlView:lockScreenAction:)]) {
  332. [self.delegate zf_controlView:self lockScreenAction:sender];
  333. }
  334. }
  335. - (void)playBtnClick:(UIButton *)sender {
  336. sender.selected = !sender.selected;
  337. if ([self.delegate respondsToSelector:@selector(zf_controlView:playAction:)]) {
  338. [self.delegate zf_controlView:self playAction:sender];
  339. }
  340. }
  341. - (void)closeBtnClick:(UIButton *)sender {
  342. if ([self.delegate respondsToSelector:@selector(zf_controlView:closeAction:)]) {
  343. [self.delegate zf_controlView:self closeAction:sender];
  344. }
  345. }
  346. - (void)fullScreenBtnClick:(UIButton *)sender {
  347. sender.selected = !sender.selected;
  348. if ([self.delegate respondsToSelector:@selector(zf_controlView:fullScreenAction:)]) {
  349. [self.delegate zf_controlView:self fullScreenAction:sender];
  350. }
  351. }
  352. - (void)repeatBtnClick:(UIButton *)sender {
  353. // 重置控制层View
  354. [self zf_playerResetControlView];
  355. [self zf_playerShowControlView];
  356. if ([self.delegate respondsToSelector:@selector(zf_controlView:repeatPlayAction:)]) {
  357. [self.delegate zf_controlView:self repeatPlayAction:sender];
  358. }
  359. }
  360. - (void)downloadBtnClick:(UIButton *)sender {
  361. if ([self.delegate respondsToSelector:@selector(zf_controlView:downloadVideoAction:)]) {
  362. [self.delegate zf_controlView:self downloadVideoAction:sender];
  363. }
  364. }
  365. - (void)resolutionBtnClick:(UIButton *)sender {
  366. sender.selected = !sender.selected;
  367. // 显示隐藏分辨率View
  368. self.resolutionView.hidden = !sender.isSelected;
  369. }
  370. - (void)centerPlayBtnClick:(UIButton *)sender {
  371. if ([self.delegate respondsToSelector:@selector(zf_controlView:cneterPlayAction:)]) {
  372. [self.delegate zf_controlView:self cneterPlayAction:sender];
  373. }
  374. }
  375. - (void)failBtnClick:(UIButton *)sender {
  376. self.failBtn.hidden = YES;
  377. if ([self.delegate respondsToSelector:@selector(zf_controlView:failAction:)]) {
  378. [self.delegate zf_controlView:self failAction:sender];
  379. }
  380. }
  381. - (void)progressSliderTouchBegan:(ASValueTrackingSlider *)sender {
  382. [self zf_playerCancelAutoFadeOutControlView];
  383. self.videoSlider.popUpView.hidden = YES;
  384. if ([self.delegate respondsToSelector:@selector(zf_controlView:progressSliderTouchBegan:)]) {
  385. [self.delegate zf_controlView:self progressSliderTouchBegan:sender];
  386. }
  387. }
  388. - (void)progressSliderValueChanged:(ASValueTrackingSlider *)sender {
  389. if ([self.delegate respondsToSelector:@selector(zf_controlView:progressSliderValueChanged:)]) {
  390. [self.delegate zf_controlView:self progressSliderValueChanged:sender];
  391. }
  392. }
  393. - (void)progressSliderTouchEnded:(ASValueTrackingSlider *)sender {
  394. self.showing = YES;
  395. if ([self.delegate respondsToSelector:@selector(zf_controlView:progressSliderTouchEnded:)]) {
  396. [self.delegate zf_controlView:self progressSliderTouchEnded:sender];
  397. }
  398. }
  399. /**
  400. * 应用退到后台
  401. */
  402. - (void)appDidEnterBackground {
  403. [self zf_playerCancelAutoFadeOutControlView];
  404. }
  405. /**
  406. * 应用进入前台
  407. */
  408. - (void)appDidEnterPlayground {
  409. if (!self.isShrink) { [self zf_playerShowControlView]; }
  410. }
  411. - (void)playerPlayDidEnd {
  412. self.backgroundColor = RGBA(0, 0, 0, .6);
  413. self.repeatBtn.hidden = NO;
  414. // 初始化显示controlView为YES
  415. self.showing = NO;
  416. // 延迟隐藏controlView
  417. [self zf_playerShowControlView];
  418. }
  419. /**
  420. * 屏幕方向发生变化会调用这里
  421. */
  422. - (void)onDeviceOrientationChange {
  423. if (ZFPlayerShared.isLockScreen) { return; }
  424. self.lockBtn.hidden = !self.isFullScreen;
  425. self.fullScreenBtn.selected = self.isFullScreen;
  426. UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
  427. if (orientation == UIDeviceOrientationFaceUp || orientation == UIDeviceOrientationFaceDown || orientation == UIDeviceOrientationUnknown || orientation == UIDeviceOrientationPortraitUpsideDown) { return; }
  428. if (!self.isShrink && !self.isPlayEnd && !self.showing) {
  429. // 显示、隐藏控制层
  430. [self zf_playerShowOrHideControlView];
  431. }
  432. }
  433. - (void)setOrientationLandscapeConstraint {
  434. if (self.isCellVideo) {
  435. self.shrink = NO;
  436. }
  437. self.fullScreen = YES;
  438. self.lockBtn.hidden = !self.isFullScreen;
  439. self.fullScreenBtn.selected = self.isFullScreen;
  440. [self.backBtn setImage:ZFPlayerImage(@"ZFPlayer_back_full") forState:UIControlStateNormal];
  441. [self.backBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
  442. make.top.equalTo(self.topImageView.mas_top).offset(23);
  443. make.leading.equalTo(self.topImageView.mas_leading).offset(10);
  444. make.width.height.mas_equalTo(40);
  445. }];
  446. }
  447. /**
  448. * 设置竖屏的约束
  449. */
  450. - (void)setOrientationPortraitConstraint {
  451. self.fullScreen = NO;
  452. self.lockBtn.hidden = !self.isFullScreen;
  453. self.fullScreenBtn.selected = self.isFullScreen;
  454. [self.backBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
  455. make.top.equalTo(self.topImageView.mas_top).offset(3);
  456. make.leading.equalTo(self.topImageView.mas_leading).offset(10);
  457. make.width.height.mas_equalTo(40);
  458. }];
  459. if (self.isCellVideo) {
  460. [self.backBtn setImage:ZFPlayerImage(@"ZFPlayer_close") forState:UIControlStateNormal];
  461. }
  462. }
  463. #pragma mark - Private Method
  464. - (void)showControlView {
  465. self.showing = YES;
  466. if (self.lockBtn.isSelected) {
  467. self.topImageView.alpha = 0;
  468. self.bottomImageView.alpha = 0;
  469. } else {
  470. self.topImageView.alpha = 1;
  471. self.bottomImageView.alpha = 1;
  472. }
  473. self.backgroundColor = RGBA(0, 0, 0, 0.3);
  474. self.lockBtn.alpha = 1;
  475. if (self.isCellVideo) {
  476. self.shrink = NO;
  477. }
  478. self.bottomProgressView.alpha = 0;
  479. ZFPlayerShared.isStatusBarHidden = NO;
  480. }
  481. - (void)hideControlView {
  482. self.showing = NO;
  483. self.backgroundColor = RGBA(0, 0, 0, 0);
  484. self.topImageView.alpha = self.playeEnd;
  485. self.bottomImageView.alpha = 0;
  486. self.lockBtn.alpha = 0;
  487. self.bottomProgressView.alpha = 1;
  488. // 隐藏resolutionView
  489. self.resolutionBtn.selected = YES;
  490. [self resolutionBtnClick:self.resolutionBtn];
  491. if (self.isFullScreen && !self.playeEnd && !self.isShrink) {
  492. ZFPlayerShared.isStatusBarHidden = YES;
  493. }
  494. }
  495. /**
  496. * 监听设备旋转通知
  497. */
  498. - (void)listeningRotating {
  499. [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
  500. [[NSNotificationCenter defaultCenter] addObserver:self
  501. selector:@selector(onDeviceOrientationChange)
  502. name:UIDeviceOrientationDidChangeNotification
  503. object:nil];
  504. }
  505. - (void)autoFadeOutControlView {
  506. [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(zf_playerHideControlView) object:nil];
  507. [self performSelector:@selector(zf_playerHideControlView) withObject:nil afterDelay:ZFPlayerAnimationTimeInterval];
  508. }
  509. /**
  510. slider滑块的bounds
  511. */
  512. - (CGRect)thumbRect {
  513. return [self.videoSlider thumbRectForBounds:self.videoSlider.bounds
  514. trackRect:[self.videoSlider trackRectForBounds:self.videoSlider.bounds]
  515. value:self.videoSlider.value];
  516. }
  517. #pragma mark - setter
  518. - (void)setShrink:(BOOL)shrink {
  519. _shrink = shrink;
  520. self.closeBtn.hidden = !shrink;
  521. self.bottomProgressView.hidden = shrink;
  522. }
  523. - (void)setFullScreen:(BOOL)fullScreen {
  524. _fullScreen = fullScreen;
  525. ZFPlayerShared.isLandscape = fullScreen;
  526. }
  527. #pragma mark - getter
  528. - (UILabel *)titleLabel {
  529. if (!_titleLabel) {
  530. _titleLabel = [[UILabel alloc] init];
  531. _titleLabel.textColor = [UIColor whiteColor];
  532. _titleLabel.font = [UIFont systemFontOfSize:15.0];
  533. }
  534. return _titleLabel;
  535. }
  536. - (UIButton *)backBtn {
  537. if (!_backBtn) {
  538. _backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  539. [_backBtn setImage:ZFPlayerImage(@"ZFPlayer_back_full") forState:UIControlStateNormal];
  540. [_backBtn addTarget:self action:@selector(backBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  541. }
  542. return _backBtn;
  543. }
  544. - (UIImageView *)topImageView {
  545. if (!_topImageView) {
  546. _topImageView = [[UIImageView alloc] init];
  547. _topImageView.userInteractionEnabled = YES;
  548. _topImageView.alpha = 0;
  549. _topImageView.image = ZFPlayerImage(@"ZFPlayer_top_shadow");
  550. }
  551. return _topImageView;
  552. }
  553. - (UIImageView *)bottomImageView {
  554. if (!_bottomImageView) {
  555. _bottomImageView = [[UIImageView alloc] init];
  556. _bottomImageView.userInteractionEnabled = YES;
  557. _bottomImageView.alpha = 0;
  558. _bottomImageView.image = ZFPlayerImage(@"ZFPlayer_bottom_shadow");
  559. }
  560. return _bottomImageView;
  561. }
  562. - (UIButton *)lockBtn {
  563. if (!_lockBtn) {
  564. _lockBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  565. [_lockBtn setImage:ZFPlayerImage(@"ZFPlayer_unlock-nor") forState:UIControlStateNormal];
  566. [_lockBtn setImage:ZFPlayerImage(@"ZFPlayer_lock-nor") forState:UIControlStateSelected];
  567. [_lockBtn addTarget:self action:@selector(lockScrrenBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  568. }
  569. return _lockBtn;
  570. }
  571. - (UIButton *)startBtn {
  572. if (!_startBtn) {
  573. _startBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  574. [_startBtn setImage:ZFPlayerImage(@"ZFPlayer_play") forState:UIControlStateNormal];
  575. [_startBtn setImage:ZFPlayerImage(@"ZFPlayer_pause") forState:UIControlStateSelected];
  576. [_startBtn addTarget:self action:@selector(playBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  577. }
  578. return _startBtn;
  579. }
  580. - (UIButton *)closeBtn {
  581. if (!_closeBtn) {
  582. _closeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  583. [_closeBtn setImage:ZFPlayerImage(@"ZFPlayer_close") forState:UIControlStateNormal];
  584. [_closeBtn addTarget:self action:@selector(closeBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  585. _closeBtn.hidden = YES;
  586. }
  587. return _closeBtn;
  588. }
  589. - (UILabel *)currentTimeLabel {
  590. if (!_currentTimeLabel) {
  591. _currentTimeLabel = [[UILabel alloc] init];
  592. _currentTimeLabel.textColor = [UIColor whiteColor];
  593. _currentTimeLabel.font = [UIFont systemFontOfSize:12.0f];
  594. _currentTimeLabel.textAlignment = NSTextAlignmentCenter;
  595. }
  596. return _currentTimeLabel;
  597. }
  598. - (UIProgressView *)progressView {
  599. if (!_progressView) {
  600. _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
  601. _progressView.progressTintColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5];
  602. _progressView.trackTintColor = [UIColor clearColor];
  603. }
  604. return _progressView;
  605. }
  606. - (ASValueTrackingSlider *)videoSlider {
  607. if (!_videoSlider) {
  608. _videoSlider = [[ASValueTrackingSlider alloc] init];
  609. _videoSlider.popUpViewCornerRadius = 0.0;
  610. _videoSlider.popUpViewColor = RGBA(19, 19, 9, 1);
  611. _videoSlider.popUpViewArrowLength = 8;
  612. [_videoSlider setThumbImage:ZFPlayerImage(@"ZFPlayer_slider") forState:UIControlStateNormal];
  613. _videoSlider.maximumValue = 1;
  614. _videoSlider.minimumTrackTintColor = [UIColor whiteColor];
  615. _videoSlider.maximumTrackTintColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.5];
  616. // slider开始滑动事件
  617. [_videoSlider addTarget:self action:@selector(progressSliderTouchBegan:) forControlEvents:UIControlEventTouchDown];
  618. // slider滑动中事件
  619. [_videoSlider addTarget:self action:@selector(progressSliderValueChanged:) forControlEvents:UIControlEventValueChanged];
  620. // slider结束滑动事件
  621. [_videoSlider addTarget:self action:@selector(progressSliderTouchEnded:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchCancel | UIControlEventTouchUpOutside];
  622. UITapGestureRecognizer *sliderTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapSliderAction:)];
  623. [_videoSlider addGestureRecognizer:sliderTap];
  624. UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panRecognizer:)];
  625. panRecognizer.delegate = self;
  626. [panRecognizer setMaximumNumberOfTouches:1];
  627. [panRecognizer setDelaysTouchesBegan:YES];
  628. [panRecognizer setDelaysTouchesEnded:YES];
  629. [panRecognizer setCancelsTouchesInView:YES];
  630. [_videoSlider addGestureRecognizer:panRecognizer];
  631. }
  632. return _videoSlider;
  633. }
  634. - (UILabel *)totalTimeLabel {
  635. if (!_totalTimeLabel) {
  636. _totalTimeLabel = [[UILabel alloc] init];
  637. _totalTimeLabel.textColor = [UIColor whiteColor];
  638. _totalTimeLabel.font = [UIFont systemFontOfSize:12.0f];
  639. _totalTimeLabel.textAlignment = NSTextAlignmentCenter;
  640. }
  641. return _totalTimeLabel;
  642. }
  643. - (UIButton *)fullScreenBtn {
  644. if (!_fullScreenBtn) {
  645. _fullScreenBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  646. [_fullScreenBtn setImage:ZFPlayerImage(@"ZFPlayer_fullscreen") forState:UIControlStateNormal];
  647. [_fullScreenBtn setImage:ZFPlayerImage(@"ZFPlayer_shrinkscreen") forState:UIControlStateSelected];
  648. [_fullScreenBtn addTarget:self action:@selector(fullScreenBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  649. }
  650. return _fullScreenBtn;
  651. }
  652. - (MMMaterialDesignSpinner *)activity {
  653. if (!_activity) {
  654. _activity = [[MMMaterialDesignSpinner alloc] init];
  655. _activity.lineWidth = 1;
  656. _activity.duration = 1;
  657. _activity.tintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
  658. }
  659. return _activity;
  660. }
  661. - (UIButton *)repeatBtn {
  662. if (!_repeatBtn) {
  663. _repeatBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  664. [_repeatBtn setImage:ZFPlayerImage(@"ZFPlayer_repeat_video") forState:UIControlStateNormal];
  665. [_repeatBtn addTarget:self action:@selector(repeatBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  666. }
  667. return _repeatBtn;
  668. }
  669. - (UIButton *)downLoadBtn {
  670. if (!_downLoadBtn) {
  671. _downLoadBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  672. [_downLoadBtn setImage:ZFPlayerImage(@"ZFPlayer_download") forState:UIControlStateNormal];
  673. [_downLoadBtn setImage:ZFPlayerImage(@"ZFPlayer_not_download") forState:UIControlStateDisabled];
  674. [_downLoadBtn addTarget:self action:@selector(downloadBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  675. }
  676. return _downLoadBtn;
  677. }
  678. - (UIButton *)resolutionBtn {
  679. if (!_resolutionBtn) {
  680. _resolutionBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  681. _resolutionBtn.titleLabel.font = [UIFont systemFontOfSize:12];
  682. _resolutionBtn.backgroundColor = RGBA(0, 0, 0, 0.7);
  683. [_resolutionBtn addTarget:self action:@selector(resolutionBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  684. }
  685. return _resolutionBtn;
  686. }
  687. - (UIButton *)playeBtn {
  688. if (!_playeBtn) {
  689. _playeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  690. [_playeBtn setImage:ZFPlayerImage(@"ZFPlayer_play_btn") forState:UIControlStateNormal];
  691. [_playeBtn addTarget:self action:@selector(centerPlayBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  692. }
  693. return _playeBtn;
  694. }
  695. - (UIButton *)failBtn {
  696. if (!_failBtn) {
  697. _failBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  698. [_failBtn setTitle:@"加载失败,点击重试" forState:UIControlStateNormal];
  699. [_failBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  700. _failBtn.titleLabel.font = [UIFont systemFontOfSize:14.0];
  701. _failBtn.backgroundColor = RGBA(0, 0, 0, 0.7);
  702. [_failBtn addTarget:self action:@selector(failBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  703. }
  704. return _failBtn;
  705. }
  706. - (UIView *)fastView {
  707. if (!_fastView) {
  708. _fastView = [[UIView alloc] init];
  709. _fastView.backgroundColor = RGBA(0, 0, 0, 0.8);
  710. _fastView.layer.cornerRadius = 4;
  711. _fastView.layer.masksToBounds = YES;
  712. }
  713. return _fastView;
  714. }
  715. - (UIImageView *)fastImageView {
  716. if (!_fastImageView) {
  717. _fastImageView = [[UIImageView alloc] init];
  718. }
  719. return _fastImageView;
  720. }
  721. - (UILabel *)fastTimeLabel {
  722. if (!_fastTimeLabel) {
  723. _fastTimeLabel = [[UILabel alloc] init];
  724. _fastTimeLabel.textColor = [UIColor whiteColor];
  725. _fastTimeLabel.textAlignment = NSTextAlignmentCenter;
  726. _fastTimeLabel.font = [UIFont systemFontOfSize:14.0];
  727. }
  728. return _fastTimeLabel;
  729. }
  730. - (UIProgressView *)fastProgressView {
  731. if (!_fastProgressView) {
  732. _fastProgressView = [[UIProgressView alloc] init];
  733. _fastProgressView.progressTintColor = [UIColor whiteColor];
  734. _fastProgressView.trackTintColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.4];
  735. }
  736. return _fastProgressView;
  737. }
  738. - (UIImageView *)placeholderImageView {
  739. if (!_placeholderImageView) {
  740. _placeholderImageView = [[UIImageView alloc] init];
  741. _placeholderImageView.userInteractionEnabled = YES;
  742. }
  743. return _placeholderImageView;
  744. }
  745. - (UIProgressView *)bottomProgressView {
  746. if (!_bottomProgressView) {
  747. _bottomProgressView = [[UIProgressView alloc] init];
  748. _bottomProgressView.progressTintColor = [UIColor whiteColor];
  749. _bottomProgressView.trackTintColor = [UIColor clearColor];
  750. }
  751. return _bottomProgressView;
  752. }
  753. #pragma mark - UIGestureRecognizerDelegate
  754. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
  755. CGRect rect = [self thumbRect];
  756. CGPoint point = [touch locationInView:self.videoSlider];
  757. if ([touch.view isKindOfClass:[UISlider class]]) { // 如果在滑块上点击就不响应pan手势
  758. if (point.x <= rect.origin.x + rect.size.width && point.x >= rect.origin.x) { return NO; }
  759. }
  760. return YES;
  761. }
  762. #pragma mark - Public method
  763. /** 重置ControlView */
  764. - (void)zf_playerResetControlView {
  765. [self.activity stopAnimating];
  766. self.videoSlider.value = 0;
  767. self.bottomProgressView.progress = 0;
  768. self.progressView.progress = 0;
  769. self.currentTimeLabel.text = @"00:00";
  770. self.totalTimeLabel.text = @"00:00";
  771. self.fastView.hidden = YES;
  772. self.repeatBtn.hidden = YES;
  773. self.playeBtn.hidden = YES;
  774. self.resolutionView.hidden = YES;
  775. self.failBtn.hidden = YES;
  776. self.backgroundColor = [UIColor clearColor];
  777. self.downLoadBtn.enabled = YES;
  778. self.shrink = NO;
  779. self.showing = NO;
  780. self.playeEnd = NO;
  781. self.lockBtn.hidden = !self.isFullScreen;
  782. self.failBtn.hidden = YES;
  783. self.placeholderImageView.alpha = 1;
  784. [self hideControlView];
  785. }
  786. - (void)zf_playerResetControlViewForResolution {
  787. self.fastView.hidden = YES;
  788. self.repeatBtn.hidden = YES;
  789. self.resolutionView.hidden = YES;
  790. self.playeBtn.hidden = YES;
  791. self.downLoadBtn.enabled = YES;
  792. self.failBtn.hidden = YES;
  793. self.backgroundColor = [UIColor clearColor];
  794. self.shrink = NO;
  795. self.showing = NO;
  796. self.playeEnd = NO;
  797. }
  798. /**
  799. * 取消延时隐藏controlView的方法
  800. */
  801. - (void)zf_playerCancelAutoFadeOutControlView {
  802. [NSObject cancelPreviousPerformRequestsWithTarget:self];
  803. }
  804. /** 设置播放模型 */
  805. - (void)zf_playerModel:(ZFPlayerModel *)playerModel {
  806. if (playerModel.title) { self.titleLabel.text = playerModel.title; }
  807. // 设置网络占位图片
  808. if (playerModel.placeholderImageURLString) {
  809. [self.placeholderImageView setImageWithURLString:playerModel.placeholderImageURLString placeholder:ZFPlayerImage(@"ZFPlayer_loading_bgView")];
  810. } else {
  811. self.placeholderImageView.image = playerModel.placeholderImage;
  812. }
  813. if (playerModel.resolutionDic) {
  814. [self zf_playerResolutionArray:[playerModel.resolutionDic allKeys]];
  815. }
  816. }
  817. /** 正在播放(隐藏placeholderImageView) */
  818. - (void)zf_playerItemPlaying {
  819. [UIView animateWithDuration:1.0 animations:^{
  820. self.placeholderImageView.alpha = 0;
  821. }];
  822. }
  823. - (void)zf_playerShowOrHideControlView {
  824. if (self.isShowing) {
  825. [self zf_playerHideControlView];
  826. } else {
  827. [self zf_playerShowControlView];
  828. }
  829. }
  830. /**
  831. * 显示控制层
  832. */
  833. - (void)zf_playerShowControlView {
  834. if ([self.delegate respondsToSelector:@selector(zf_controlViewWillShow:isFullscreen:)]) {
  835. [self.delegate zf_controlViewWillShow:self isFullscreen:self.isFullScreen];
  836. }
  837. [self zf_playerCancelAutoFadeOutControlView];
  838. [UIView animateWithDuration:ZFPlayerControlBarAutoFadeOutTimeInterval animations:^{
  839. [self showControlView];
  840. } completion:^(BOOL finished) {
  841. self.showing = YES;
  842. [self autoFadeOutControlView];
  843. }];
  844. }
  845. /**
  846. * 隐藏控制层
  847. */
  848. - (void)zf_playerHideControlView {
  849. if ([self.delegate respondsToSelector:@selector(zf_controlViewWillHidden:isFullscreen:)]) {
  850. [self.delegate zf_controlViewWillHidden:self isFullscreen:self.isFullScreen];
  851. }
  852. [self zf_playerCancelAutoFadeOutControlView];
  853. [UIView animateWithDuration:ZFPlayerControlBarAutoFadeOutTimeInterval animations:^{
  854. [self hideControlView];
  855. } completion:^(BOOL finished) {
  856. self.showing = NO;
  857. }];
  858. }
  859. /** 小屏播放 */
  860. - (void)zf_playerBottomShrinkPlay {
  861. self.shrink = YES;
  862. [self hideControlView];
  863. }
  864. /** 在cell播放 */
  865. - (void)zf_playerCellPlay {
  866. self.cellVideo = YES;
  867. self.shrink = NO;
  868. [self.backBtn setImage:ZFPlayerImage(@"ZFPlayer_close") forState:UIControlStateNormal];
  869. }
  870. - (void)zf_playerCurrentTime:(NSInteger)currentTime totalTime:(NSInteger)totalTime sliderValue:(CGFloat)value {
  871. // 当前时长进度progress
  872. NSInteger proMin = currentTime / 60;//当前秒
  873. NSInteger proSec = currentTime % 60;//当前分钟
  874. // duration 总时长
  875. NSInteger durMin = totalTime / 60;//总秒
  876. NSInteger durSec = totalTime % 60;//总分钟
  877. if (!self.isDragged) {
  878. // 更新slider
  879. self.videoSlider.value = value;
  880. self.bottomProgressView.progress = value;
  881. // 更新当前播放时间
  882. self.currentTimeLabel.text = [NSString stringWithFormat:@"%02zd:%02zd", proMin, proSec];
  883. }
  884. // 更新总时间
  885. self.totalTimeLabel.text = [NSString stringWithFormat:@"%02zd:%02zd", durMin, durSec];
  886. }
  887. - (void)zf_playerDraggedTime:(NSInteger)draggedTime totalTime:(NSInteger)totalTime isForward:(BOOL)forawrd hasPreview:(BOOL)preview {
  888. // 快进快退时候停止菊花
  889. [self.activity stopAnimating];
  890. // 拖拽的时长
  891. NSInteger proMin = draggedTime / 60;//当前秒
  892. NSInteger proSec = draggedTime % 60;//当前分钟
  893. //duration 总时长
  894. NSInteger durMin = totalTime / 60;//总秒
  895. NSInteger durSec = totalTime % 60;//总分钟
  896. NSString *currentTimeStr = [NSString stringWithFormat:@"%02zd:%02zd", proMin, proSec];
  897. NSString *totalTimeStr = [NSString stringWithFormat:@"%02zd:%02zd", durMin, durSec];
  898. CGFloat draggedValue = (CGFloat)draggedTime/(CGFloat)totalTime;
  899. NSString *timeStr = [NSString stringWithFormat:@"%@ / %@", currentTimeStr, totalTimeStr];
  900. // 显示、隐藏预览窗
  901. self.videoSlider.popUpView.hidden = !preview;
  902. // 更新slider的值
  903. self.videoSlider.value = draggedValue;
  904. // 更新bottomProgressView的值
  905. self.bottomProgressView.progress = draggedValue;
  906. // 更新当前时间
  907. self.currentTimeLabel.text = currentTimeStr;
  908. // 正在拖动控制播放进度
  909. self.dragged = YES;
  910. if (forawrd) {
  911. self.fastImageView.image = ZFPlayerImage(@"ZFPlayer_fast_forward");
  912. } else {
  913. self.fastImageView.image = ZFPlayerImage(@"ZFPlayer_fast_backward");
  914. }
  915. self.fastView.hidden = preview;
  916. self.fastTimeLabel.text = timeStr;
  917. self.fastProgressView.progress = draggedValue;
  918. }
  919. - (void)zf_playerDraggedEnd {
  920. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  921. self.fastView.hidden = YES;
  922. });
  923. self.dragged = NO;
  924. // 结束滑动时候把开始播放按钮改为播放状态
  925. self.startBtn.selected = YES;
  926. // 滑动结束延时隐藏controlView
  927. [self autoFadeOutControlView];
  928. }
  929. - (void)zf_playerDraggedTime:(NSInteger)draggedTime sliderImage:(UIImage *)image; {
  930. // 拖拽的时长
  931. NSInteger proMin = draggedTime / 60;//当前秒
  932. NSInteger proSec = draggedTime % 60;//当前分钟
  933. NSString *currentTimeStr = [NSString stringWithFormat:@"%02zd:%02zd", proMin, proSec];
  934. [self.videoSlider setImage:image];
  935. [self.videoSlider setText:currentTimeStr];
  936. self.fastView.hidden = YES;
  937. }
  938. /** progress显示缓冲进度 */
  939. - (void)zf_playerSetProgress:(CGFloat)progress {
  940. [self.progressView setProgress:progress animated:NO];
  941. }
  942. /** 视频加载失败 */
  943. - (void)zf_playerItemStatusFailed:(NSError *)error {
  944. self.failBtn.hidden = NO;
  945. }
  946. /** 加载的菊花 */
  947. - (void)zf_playerActivity:(BOOL)animated {
  948. if (animated) {
  949. [self.activity startAnimating];
  950. self.fastView.hidden = YES;
  951. } else {
  952. [self.activity stopAnimating];
  953. }
  954. }
  955. /** 播放完了 */
  956. - (void)zf_playerPlayEnd {
  957. self.repeatBtn.hidden = NO;
  958. self.playeEnd = YES;
  959. self.showing = NO;
  960. // 隐藏controlView
  961. [self hideControlView];
  962. self.backgroundColor = RGBA(0, 0, 0, .3);
  963. ZFPlayerShared.isStatusBarHidden = NO;
  964. self.bottomProgressView.alpha = 0;
  965. }
  966. /**
  967. 是否有下载功能
  968. */
  969. - (void)zf_playerHasDownloadFunction:(BOOL)sender {
  970. self.downLoadBtn.hidden = !sender;
  971. }
  972. /**
  973. 是否有切换分辨率功能
  974. */
  975. - (void)zf_playerResolutionArray:(NSArray *)resolutionArray {
  976. self.resolutionBtn.hidden = NO;
  977. _resolutionArray = resolutionArray;
  978. [_resolutionBtn setTitle:resolutionArray.firstObject forState:UIControlStateNormal];
  979. // 添加分辨率按钮和分辨率下拉列表
  980. self.resolutionView = [[UIView alloc] init];
  981. self.resolutionView.hidden = YES;
  982. self.resolutionView.backgroundColor = RGBA(0, 0, 0, 0.7);
  983. [self addSubview:self.resolutionView];
  984. [self.resolutionView mas_makeConstraints:^(MASConstraintMaker *make) {
  985. make.width.mas_equalTo(40);
  986. make.height.mas_equalTo(25*resolutionArray.count);
  987. make.leading.equalTo(self.resolutionBtn.mas_leading).offset(0);
  988. make.top.equalTo(self.resolutionBtn.mas_bottom).offset(0);
  989. }];
  990. // 分辨率View上边的Btn
  991. for (NSInteger i = 0 ; i < resolutionArray.count; i++) {
  992. UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  993. btn.layer.borderColor = [UIColor whiteColor].CGColor;
  994. btn.layer.borderWidth = 0.5;
  995. btn.tag = 200+i;
  996. btn.frame = CGRectMake(0, 25*i, 40, 25);
  997. btn.titleLabel.font = [UIFont systemFontOfSize:12];
  998. [btn setTitle:resolutionArray[i] forState:UIControlStateNormal];
  999. if (i == 0) {
  1000. self.resoultionCurrentBtn = btn;
  1001. btn.selected = YES;
  1002. btn.backgroundColor = RGBA(86, 143, 232, 1);
  1003. }
  1004. [self.resolutionView addSubview:btn];
  1005. [btn addTarget:self action:@selector(changeResolution:) forControlEvents:UIControlEventTouchUpInside];
  1006. }
  1007. }
  1008. /** 播放按钮状态 */
  1009. - (void)zf_playerPlayBtnState:(BOOL)state {
  1010. self.startBtn.selected = state;
  1011. }
  1012. /** 锁定屏幕方向按钮状态 */
  1013. - (void)zf_playerLockBtnState:(BOOL)state {
  1014. self.lockBtn.selected = state;
  1015. }
  1016. /** 下载按钮状态 */
  1017. - (void)zf_playerDownloadBtnState:(BOOL)state {
  1018. self.downLoadBtn.enabled = state;
  1019. }
  1020. #pragma clang diagnostic pop
  1021. @end