ZFPlayerControlView2.m 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. //
  2. // ZFPlayerControlView.m
  3. // ZFPlayer
  4. //
  5. // Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. #import "ZFPlayerControlView2.h"
  25. #import <AVKit/AVKit.h>
  26. #import <AVFoundation/AVFoundation.h>
  27. #import "UIView+ZFFrame.h"
  28. #import "ZFSliderView.h"
  29. #import "ZFUtilities.h"
  30. #import "UIImageView+ZFCache.h"
  31. #import <MediaPlayer/MediaPlayer.h>
  32. #import "ZFVolumeBrightnessView.h"
  33. #if __has_include(<ZFPlayer/ZFPlayer.h>)
  34. #import <ZFPlayer/ZFPlayerConst.h>
  35. #else
  36. #import "ZFPlayerConst.h"
  37. #endif
  38. @interface ZFPlayerControlView2 () <ZFSliderViewDelegate>
  39. /// 竖屏控制层的View
  40. @property (nonatomic, strong) ZFPortraitControlView2 *portraitControlView;
  41. /// 横屏控制层的View
  42. @property (nonatomic, strong) ZFLandScapeControlView2 *landScapeControlView;
  43. /// 加载loading
  44. @property (nonatomic, strong) ZFSpeedLoadingView *activity;
  45. /// 快进快退View
  46. @property (nonatomic, strong) UIView *fastView;
  47. /// 快进快退进度progress
  48. @property (nonatomic, strong) ZFSliderView *fastProgressView;
  49. /// 快进快退时间
  50. @property (nonatomic, strong) UILabel *fastTimeLabel;
  51. /// 快进快退ImageView
  52. @property (nonatomic, strong) UIImageView *fastImageView;
  53. /// 加载失败按钮
  54. @property (nonatomic, strong) UIButton *failBtn;
  55. /// 底部播放进度
  56. @property (nonatomic, strong) ZFSliderView *bottomPgrogress;
  57. /// 是否显示了控制层
  58. @property (nonatomic, assign, getter=isShowing) BOOL showing;
  59. /// 是否播放结束
  60. @property (nonatomic, assign, getter=isPlayEnd) BOOL playeEnd;
  61. @property (nonatomic, assign) BOOL controlViewAppeared;
  62. @property (nonatomic, assign) NSTimeInterval sumTime;
  63. @property (nonatomic, strong) dispatch_block_t afterBlock;
  64. @property (nonatomic, strong) ZFSmallFloatControlView *floatControlView;
  65. @property (nonatomic, strong) ZFVolumeBrightnessView *volumeBrightnessView;
  66. @property (nonatomic, strong) UIImageView *bgImgView;
  67. @property (nonatomic, strong) UIView *effectView;
  68. @end
  69. @implementation ZFPlayerControlView2
  70. @synthesize player = _player;
  71. - (instancetype)initWithFrame:(CGRect)frame {
  72. self = [super initWithFrame:frame];
  73. if (self) {
  74. [self addAllSubViews];
  75. self.landScapeControlView.hidden = YES;
  76. self.floatControlView.hidden = YES;
  77. self.seekToPlay = YES;
  78. self.effectViewShow = YES;
  79. self.horizontalPanShowControlView = YES;
  80. self.autoFadeTimeInterval = 0.25;
  81. self.autoHiddenTimeInterval = 2.5;
  82. [[NSNotificationCenter defaultCenter] addObserver:self
  83. selector:@selector(volumeChanged:)
  84. name:@"AVSystemController_SystemVolumeDidChangeNotification"
  85. object:nil];
  86. }
  87. return self;
  88. }
  89. - (void)layoutSubviews {
  90. [super layoutSubviews];
  91. CGFloat min_x = 0;
  92. CGFloat min_y = 0;
  93. CGFloat min_w = 0;
  94. CGFloat min_h = 0;
  95. CGFloat min_view_w = self.zf_width;
  96. CGFloat min_view_h = self.zf_height;
  97. self.portraitControlView.frame = self.bounds;
  98. self.landScapeControlView.frame = self.bounds;
  99. self.floatControlView.frame = self.bounds;
  100. self.coverImageView.frame = self.bounds;
  101. self.bgImgView.frame = self.bounds;
  102. self.effectView.frame = self.bounds;
  103. min_w = 80;
  104. min_h = 80;
  105. self.activity.frame = CGRectMake(min_x, min_y, min_w, min_h);
  106. self.activity.zf_centerX = self.zf_centerX;
  107. self.activity.zf_centerY = self.zf_centerY + 10;
  108. min_w = 150;
  109. min_h = 30;
  110. self.failBtn.frame = CGRectMake(min_x, min_y, min_w, min_h);
  111. self.failBtn.center = self.center;
  112. min_w = 140;
  113. min_h = 80;
  114. self.fastView.frame = CGRectMake(min_x, min_y, min_w, min_h);
  115. self.fastView.center = self.center;
  116. min_w = 32;
  117. min_x = (self.fastView.zf_width - min_w) / 2;
  118. min_y = 5;
  119. min_h = 32;
  120. self.fastImageView.frame = CGRectMake(min_x, min_y, min_w, min_h);
  121. min_x = 0;
  122. min_y = self.fastImageView.zf_bottom + 2;
  123. min_w = self.fastView.zf_width;
  124. min_h = 20;
  125. self.fastTimeLabel.frame = CGRectMake(min_x, min_y, min_w, min_h);
  126. min_x = 12;
  127. min_y = self.fastTimeLabel.zf_bottom + 5;
  128. min_w = self.fastView.zf_width - 2 * min_x;
  129. min_h = 10;
  130. self.fastProgressView.frame = CGRectMake(min_x, min_y, min_w, min_h);
  131. min_x = 0;
  132. min_y = min_view_h - 1;
  133. min_w = min_view_w;
  134. min_h = 1;
  135. self.bottomPgrogress.frame = CGRectMake(min_x, min_y, min_w, min_h);
  136. min_x = 0;
  137. min_y = iPhoneX ? 54 : 30;
  138. min_w = 170;
  139. min_h = 35;
  140. self.volumeBrightnessView.frame = CGRectMake(min_x, min_y, min_w, min_h);
  141. self.volumeBrightnessView.zf_centerX = self.zf_centerX;
  142. }
  143. - (void)dealloc {
  144. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
  145. [self cancelAutoFadeOutControlView];
  146. }
  147. /// 添加所有子控件
  148. - (void)addAllSubViews {
  149. [self addSubview:self.portraitControlView];
  150. [self addSubview:self.landScapeControlView];
  151. [self addSubview:self.floatControlView];
  152. [self addSubview:self.activity];
  153. [self addSubview:self.failBtn];
  154. [self addSubview:self.fastView];
  155. [self.fastView addSubview:self.fastImageView];
  156. [self.fastView addSubview:self.fastTimeLabel];
  157. [self.fastView addSubview:self.fastProgressView];
  158. [self addSubview:self.bottomPgrogress];
  159. [self addSubview:self.volumeBrightnessView];
  160. }
  161. - (void)autoFadeOutControlView {
  162. self.controlViewAppeared = YES;
  163. [self cancelAutoFadeOutControlView];
  164. @zf_weakify(self)
  165. self.afterBlock = dispatch_block_create(0, ^{
  166. @zf_strongify(self)
  167. [self hideControlViewWithAnimated:YES];
  168. });
  169. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.autoHiddenTimeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(),self.afterBlock);
  170. }
  171. /// 取消延时隐藏controlView的方法
  172. - (void)cancelAutoFadeOutControlView {
  173. if (self.afterBlock) {
  174. dispatch_block_cancel(self.afterBlock);
  175. self.afterBlock = nil;
  176. }
  177. }
  178. /// 隐藏控制层
  179. - (void)hideControlViewWithAnimated:(BOOL)animated {
  180. self.controlViewAppeared = NO;
  181. if (self.controlViewAppearedCallback) {
  182. self.controlViewAppearedCallback(NO);
  183. }
  184. [UIView animateWithDuration:animated ? self.autoFadeTimeInterval : 0 animations:^{
  185. if (self.player.isFullScreen) {
  186. [self.landScapeControlView hideControlView];
  187. } else {
  188. if (!self.player.isSmallFloatViewShow) {
  189. [self.portraitControlView hideControlView];
  190. }
  191. }
  192. } completion:^(BOOL finished) {
  193. self.bottomPgrogress.hidden = NO;
  194. }];
  195. }
  196. /// 显示控制层
  197. - (void)showControlViewWithAnimated:(BOOL)animated {
  198. self.controlViewAppeared = YES;
  199. if (self.controlViewAppearedCallback) {
  200. self.controlViewAppearedCallback(YES);
  201. }
  202. [self autoFadeOutControlView];
  203. [UIView animateWithDuration:animated ? self.autoFadeTimeInterval : 0 animations:^{
  204. if (self.player.isFullScreen) {
  205. [self.landScapeControlView showControlView];
  206. } else {
  207. if (!self.player.isSmallFloatViewShow) {
  208. [self.portraitControlView showControlView];
  209. }
  210. }
  211. } completion:^(BOOL finished) {
  212. self.bottomPgrogress.hidden = YES;
  213. }];
  214. }
  215. /// 音量改变的通知
  216. - (void)volumeChanged:(NSNotification *)notification {
  217. NSDictionary *userInfo = notification.userInfo;
  218. NSString *reasonstr = userInfo[@"AVSystemController_AudioVolumeChangeReasonNotificationParameter"];
  219. if ([reasonstr isEqualToString:@"ExplicitVolumeChange"]) {
  220. float volume = [ userInfo[@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
  221. if (self.player.isFullScreen) {
  222. [self.volumeBrightnessView updateProgress:volume withVolumeBrightnessType:ZFVolumeBrightnessTypeVolume];
  223. } else {
  224. [self.volumeBrightnessView addSystemVolumeView];
  225. }
  226. }
  227. }
  228. #pragma mark - Public Method
  229. /// 重置控制层
  230. - (void)resetControlView {
  231. [self.portraitControlView resetControlView];
  232. [self.landScapeControlView resetControlView];
  233. [self cancelAutoFadeOutControlView];
  234. self.bottomPgrogress.value = 0;
  235. self.bottomPgrogress.bufferValue = 0;
  236. self.floatControlView.hidden = YES;
  237. self.failBtn.hidden = YES;
  238. self.volumeBrightnessView.hidden = YES;
  239. self.portraitControlView.hidden = self.player.isFullScreen;
  240. self.landScapeControlView.hidden = !self.player.isFullScreen;
  241. if (self.controlViewAppeared) {
  242. [self showControlViewWithAnimated:NO];
  243. } else {
  244. [self hideControlViewWithAnimated:NO];
  245. }
  246. }
  247. /// 设置标题、封面、全屏模式
  248. - (void)showTitle:(NSString *)title coverURLString:(NSString *)coverUrl fullScreenMode:(ZFFullScreenMode)fullScreenMode {
  249. UIImage *placeholder = [ZFUtilities imageWithColor:[UIColor blackColor] size:self.bgImgView.bounds.size];
  250. [self showTitle:title coverURLString:coverUrl placeholderImage:placeholder fullScreenMode:fullScreenMode];
  251. }
  252. /// 设置标题、封面、默认占位图、全屏模式
  253. - (void)showTitle:(NSString *)title coverURLString:(NSString *)coverUrl placeholderImage:(UIImage *)placeholder fullScreenMode:(ZFFullScreenMode)fullScreenMode {
  254. [self resetControlView];
  255. [self layoutIfNeeded];
  256. [self setNeedsDisplay];
  257. [self.portraitControlView showTitle:title fullScreenMode:fullScreenMode];
  258. [self.landScapeControlView showTitle:title fullScreenMode:fullScreenMode];
  259. /// 这里直接设置播放器视图里的coverImageView
  260. [self.player.currentPlayerManager.view.coverImageView setImageWithURLString:coverUrl placeholder:placeholder];
  261. [self.bgImgView setImageWithURLString:coverUrl placeholder:placeholder];
  262. if (self.prepareShowControlView) {
  263. [self showControlViewWithAnimated:NO];
  264. } else {
  265. [self hideControlViewWithAnimated:NO];
  266. }
  267. }
  268. /// 设置标题、UIImage封面、全屏模式
  269. - (void)showTitle:(NSString *)title coverImage:(UIImage *)image fullScreenMode:(ZFFullScreenMode)fullScreenMode {
  270. [self resetControlView];
  271. [self layoutIfNeeded];
  272. [self setNeedsDisplay];
  273. [self.portraitControlView showTitle:title fullScreenMode:fullScreenMode];
  274. [self.landScapeControlView showTitle:title fullScreenMode:fullScreenMode];
  275. self.coverImageView.image = image;
  276. self.bgImgView.image = image;
  277. if (self.prepareShowControlView) {
  278. [self showControlViewWithAnimated:NO];
  279. } else {
  280. [self hideControlViewWithAnimated:NO];
  281. }
  282. }
  283. #pragma mark - ZFPlayerControlViewDelegate
  284. /// 手势筛选,返回NO不响应该手势
  285. - (BOOL)gestureTriggerCondition:(ZFPlayerGestureControl *)gestureControl gestureType:(ZFPlayerGestureType)gestureType gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer touch:(nonnull UITouch *)touch {
  286. CGPoint point = [touch locationInView:self];
  287. if (self.player.isSmallFloatViewShow && !self.player.isFullScreen && gestureType != ZFPlayerGestureTypeSingleTap) {
  288. return NO;
  289. }
  290. if (self.player.isFullScreen) {
  291. if (!self.customDisablePanMovingDirection) {
  292. /// 不禁用滑动方向
  293. self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionNone;
  294. }
  295. return [self.landScapeControlView shouldResponseGestureWithPoint:point withGestureType:gestureType touch:touch];
  296. } else {
  297. if (!self.customDisablePanMovingDirection) {
  298. if (self.player.scrollView) { /// 列表时候禁止上下滑动(防止和列表滑动冲突)
  299. self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionVertical;
  300. } else { /// 不禁用滑动方向
  301. self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionNone;
  302. }
  303. }
  304. return [self.portraitControlView shouldResponseGestureWithPoint:point withGestureType:gestureType touch:touch];
  305. }
  306. }
  307. /// 单击手势事件
  308. - (void)gestureSingleTapped:(ZFPlayerGestureControl *)gestureControl {
  309. if (!self.player) return;
  310. if(!self.landScapeControlView.changeStateImageView.isHidden){
  311. [self.landScapeControlView hideControlDetailView];
  312. return;
  313. }
  314. if (self.player.isSmallFloatViewShow && !self.player.isFullScreen) {
  315. [self.player enterFullScreen:YES animated:YES];
  316. } else {
  317. if (self.controlViewAppeared) {
  318. [self hideControlViewWithAnimated:YES];
  319. } else {
  320. [self showControlViewWithAnimated:YES];
  321. }
  322. }
  323. }
  324. /// 双击手势事件
  325. - (void)gestureDoubleTapped:(ZFPlayerGestureControl *)gestureControl {
  326. if (self.player.isFullScreen) {
  327. [self.landScapeControlView playOrPause];
  328. } else {
  329. [self.portraitControlView playOrPause];
  330. }
  331. }
  332. /// 开始滑动手势事件
  333. - (void)gestureBeganPan:(ZFPlayerGestureControl *)gestureControl panDirection:(ZFPanDirection)direction panLocation:(ZFPanLocation)location {
  334. if (direction == ZFPanDirectionH) {
  335. self.sumTime = self.player.currentTime;
  336. }
  337. }
  338. /// 滑动中手势事件
  339. - (void)gestureChangedPan:(ZFPlayerGestureControl *)gestureControl panDirection:(ZFPanDirection)direction panLocation:(ZFPanLocation)location withVelocity:(CGPoint)velocity {
  340. if (direction == ZFPanDirectionH) {
  341. // 每次滑动需要叠加时间
  342. self.sumTime += velocity.x / 200;
  343. // 需要限定sumTime的范围
  344. NSTimeInterval totalMovieDuration = self.player.totalTime;
  345. if (totalMovieDuration == 0) return;
  346. if (self.sumTime > totalMovieDuration) self.sumTime = totalMovieDuration;
  347. if (self.sumTime < 0) self.sumTime = 0;
  348. BOOL style = NO;
  349. if (velocity.x > 0) style = YES;
  350. if (velocity.x < 0) style = NO;
  351. if (velocity.x == 0) return;
  352. [self sliderValueChangingValue:self.sumTime/totalMovieDuration isForward:style];
  353. } else if (direction == ZFPanDirectionV) {
  354. if (location == ZFPanLocationLeft) { /// 调节亮度
  355. self.player.brightness -= (velocity.y) / 10000;
  356. [self.volumeBrightnessView updateProgress:self.player.brightness withVolumeBrightnessType:ZFVolumeBrightnessTypeumeBrightness];
  357. } else if (location == ZFPanLocationRight) { /// 调节声音
  358. self.player.volume -= (velocity.y) / 10000;
  359. if (self.player.isFullScreen) {
  360. [self.volumeBrightnessView updateProgress:self.player.volume withVolumeBrightnessType:ZFVolumeBrightnessTypeVolume];
  361. }
  362. }
  363. }
  364. }
  365. /// 滑动结束手势事件
  366. - (void)gestureEndedPan:(ZFPlayerGestureControl *)gestureControl panDirection:(ZFPanDirection)direction panLocation:(ZFPanLocation)location {
  367. @zf_weakify(self)
  368. if (direction == ZFPanDirectionH && self.sumTime >= 0 && self.player.totalTime > 0) {
  369. [self.player seekToTime:self.sumTime completionHandler:^(BOOL finished) {
  370. if (finished) {
  371. @zf_strongify(self)
  372. /// 左右滑动调节播放进度
  373. [self.portraitControlView sliderChangeEnded];
  374. [self.landScapeControlView sliderChangeEnded];
  375. self.bottomPgrogress.isdragging = NO;
  376. if (self.controlViewAppeared) {
  377. [self autoFadeOutControlView];
  378. }
  379. }
  380. }];
  381. if (self.seekToPlay) {
  382. [self.player.currentPlayerManager play];
  383. }
  384. self.sumTime = 0;
  385. }
  386. }
  387. /// 捏合手势事件,这里改变了视频的填充模式
  388. - (void)gesturePinched:(ZFPlayerGestureControl *)gestureControl scale:(float)scale {
  389. if (scale > 1) {
  390. self.player.currentPlayerManager.scalingMode = ZFPlayerScalingModeAspectFill;
  391. } else {
  392. self.player.currentPlayerManager.scalingMode = ZFPlayerScalingModeAspectFit;
  393. }
  394. }
  395. /// 准备播放
  396. - (void)videoPlayer:(ZFPlayerController *)videoPlayer prepareToPlay:(NSURL *)assetURL {
  397. [self hideControlViewWithAnimated:NO];
  398. }
  399. /// 播放状态改变
  400. - (void)videoPlayer:(ZFPlayerController *)videoPlayer playStateChanged:(ZFPlayerPlaybackState)state {
  401. if (state == ZFPlayerPlayStatePlaying) {
  402. [self.portraitControlView playBtnSelectedState:YES];
  403. [self.landScapeControlView playBtnSelectedState:YES];
  404. self.failBtn.hidden = YES;
  405. /// 开始播放时候判断是否显示loading
  406. if (videoPlayer.currentPlayerManager.loadState == ZFPlayerLoadStateStalled && !self.prepareShowLoading) {
  407. [self.activity startAnimating];
  408. } else if ((videoPlayer.currentPlayerManager.loadState == ZFPlayerLoadStateStalled || videoPlayer.currentPlayerManager.loadState == ZFPlayerLoadStatePrepare) && self.prepareShowLoading) {
  409. [self.activity startAnimating];
  410. }
  411. } else if (state == ZFPlayerPlayStatePaused) {
  412. [self.portraitControlView playBtnSelectedState:NO];
  413. [self.landScapeControlView playBtnSelectedState:NO];
  414. /// 暂停的时候隐藏loading
  415. [self.activity stopAnimating];
  416. self.failBtn.hidden = YES;
  417. } else if (state == ZFPlayerPlayStatePlayFailed) {
  418. self.failBtn.hidden = NO;
  419. [self.activity stopAnimating];
  420. }
  421. }
  422. /// 加载状态改变
  423. - (void)videoPlayer:(ZFPlayerController *)videoPlayer loadStateChanged:(ZFPlayerLoadState)state {
  424. if (state == ZFPlayerLoadStatePrepare) {
  425. self.coverImageView.hidden = NO;
  426. [self.portraitControlView playBtnSelectedState:videoPlayer.currentPlayerManager.shouldAutoPlay];
  427. [self.landScapeControlView playBtnSelectedState:videoPlayer.currentPlayerManager.shouldAutoPlay];
  428. } else if (state == ZFPlayerLoadStatePlaythroughOK || state == ZFPlayerLoadStatePlayable) {
  429. self.coverImageView.hidden = YES;
  430. if (self.effectViewShow) {
  431. self.effectView.hidden = NO;
  432. } else {
  433. self.effectView.hidden = YES;
  434. self.player.currentPlayerManager.view.backgroundColor = [UIColor blackColor];
  435. }
  436. }
  437. if (state == ZFPlayerLoadStateStalled && videoPlayer.currentPlayerManager.isPlaying && !self.prepareShowLoading) {
  438. [self.activity startAnimating];
  439. } else if ((state == ZFPlayerLoadStateStalled || state == ZFPlayerLoadStatePrepare) && videoPlayer.currentPlayerManager.isPlaying && self.prepareShowLoading) {
  440. [self.activity startAnimating];
  441. } else {
  442. [self.activity stopAnimating];
  443. }
  444. }
  445. /// 播放进度改变回调
  446. - (void)videoPlayer:(ZFPlayerController *)videoPlayer currentTime:(NSTimeInterval)currentTime totalTime:(NSTimeInterval)totalTime {
  447. [self.portraitControlView videoPlayer:videoPlayer currentTime:currentTime totalTime:totalTime];
  448. [self.landScapeControlView videoPlayer:videoPlayer currentTime:currentTime totalTime:totalTime];
  449. if (!self.bottomPgrogress.isdragging) {
  450. self.bottomPgrogress.value = videoPlayer.progress;
  451. }
  452. }
  453. /// 缓冲改变回调
  454. - (void)videoPlayer:(ZFPlayerController *)videoPlayer bufferTime:(NSTimeInterval)bufferTime {
  455. [self.portraitControlView videoPlayer:videoPlayer bufferTime:bufferTime];
  456. [self.landScapeControlView videoPlayer:videoPlayer bufferTime:bufferTime];
  457. self.bottomPgrogress.bufferValue = videoPlayer.bufferProgress;
  458. }
  459. - (void)videoPlayer:(ZFPlayerController *)videoPlayer presentationSizeChanged:(CGSize)size {
  460. [self.landScapeControlView videoPlayer:videoPlayer presentationSizeChanged:size];
  461. }
  462. /// 视频view即将旋转
  463. - (void)videoPlayer:(ZFPlayerController *)videoPlayer orientationWillChange:(ZFOrientationObserver *)observer {
  464. self.portraitControlView.hidden = observer.isFullScreen;
  465. self.landScapeControlView.hidden = !observer.isFullScreen;
  466. if (videoPlayer.isSmallFloatViewShow) {
  467. self.floatControlView.hidden = observer.isFullScreen;
  468. self.portraitControlView.hidden = YES;
  469. if (observer.isFullScreen) {
  470. self.controlViewAppeared = NO;
  471. [self cancelAutoFadeOutControlView];
  472. }
  473. }
  474. if (self.controlViewAppeared) {
  475. [self showControlViewWithAnimated:NO];
  476. } else {
  477. [self hideControlViewWithAnimated:NO];
  478. }
  479. if (observer.isFullScreen) {
  480. [self.volumeBrightnessView removeSystemVolumeView];
  481. } else {
  482. [self.volumeBrightnessView addSystemVolumeView];
  483. }
  484. [self.landScapeControlView videoPlayer:videoPlayer orientationWillChange:observer];
  485. }
  486. /// 锁定旋转方向
  487. - (void)lockedVideoPlayer:(ZFPlayerController *)videoPlayer lockedScreen:(BOOL)locked {
  488. [self showControlViewWithAnimated:YES];
  489. }
  490. /// 列表滑动时视频view已经显示
  491. - (void)playerDidAppearInScrollView:(ZFPlayerController *)videoPlayer {
  492. if (!self.player.stopWhileNotVisible && !videoPlayer.isFullScreen) {
  493. self.floatControlView.hidden = YES;
  494. self.portraitControlView.hidden = NO;
  495. }
  496. }
  497. /// 列表滑动时视频view已经消失
  498. - (void)playerDidDisappearInScrollView:(ZFPlayerController *)videoPlayer {
  499. if (!self.player.stopWhileNotVisible && !videoPlayer.isFullScreen) {
  500. self.floatControlView.hidden = NO;
  501. self.portraitControlView.hidden = YES;
  502. }
  503. }
  504. - (void)videoPlayer:(ZFPlayerController *)videoPlayer floatViewShow:(BOOL)show {
  505. self.floatControlView.hidden = !show;
  506. self.portraitControlView.hidden = show;
  507. }
  508. #pragma mark - Private Method
  509. - (void)sliderValueChangingValue:(CGFloat)value isForward:(BOOL)forward {
  510. if (self.horizontalPanShowControlView) {
  511. /// 显示控制层
  512. [self showControlViewWithAnimated:NO];
  513. [self cancelAutoFadeOutControlView];
  514. }
  515. self.fastProgressView.value = value;
  516. self.fastView.hidden = NO;
  517. self.fastView.alpha = 1;
  518. if (forward) {
  519. self.fastImageView.image = ZFPlayer_Image(@"ZFPlayer_fast_forward");
  520. } else {
  521. self.fastImageView.image = ZFPlayer_Image(@"ZFPlayer_fast_backward");
  522. }
  523. NSString *draggedTime = [ZFUtilities convertTimeSecond:self.player.totalTime*value];
  524. NSString *totalTime = [ZFUtilities convertTimeSecond:self.player.totalTime];
  525. self.fastTimeLabel.text = [NSString stringWithFormat:@"%@ / %@",draggedTime,totalTime];
  526. /// 更新滑杆
  527. [self.portraitControlView sliderValueChanged:value currentTimeString:draggedTime];
  528. [self.landScapeControlView sliderValueChanged:value currentTimeString:draggedTime];
  529. self.bottomPgrogress.isdragging = YES;
  530. self.bottomPgrogress.value = value;
  531. [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideFastView) object:nil];
  532. [self performSelector:@selector(hideFastView) withObject:nil afterDelay:0.1];
  533. if (self.fastViewAnimated) {
  534. [UIView animateWithDuration:0.4 animations:^{
  535. self.fastView.transform = CGAffineTransformMakeTranslation(forward?8:-8, 0);
  536. }];
  537. }
  538. }
  539. /// 隐藏快进视图
  540. - (void)hideFastView {
  541. [UIView animateWithDuration:0.4 animations:^{
  542. self.fastView.transform = CGAffineTransformIdentity;
  543. self.fastView.alpha = 0;
  544. } completion:^(BOOL finished) {
  545. self.fastView.hidden = YES;
  546. }];
  547. }
  548. /// 加载失败
  549. - (void)failBtnClick:(UIButton *)sender {
  550. [self.player.currentPlayerManager reloadPlayer];
  551. }
  552. #pragma mark - setter
  553. - (void)setPlayer:(ZFPlayerController *)player {
  554. _player = player;
  555. self.landScapeControlView.player = player;
  556. self.portraitControlView.player = player;
  557. /// 解决播放时候黑屏闪一下问题
  558. [player.currentPlayerManager.view insertSubview:self.bgImgView atIndex:0];
  559. [self.bgImgView addSubview:self.effectView];
  560. self.bgImgView.frame = player.currentPlayerManager.view.bounds;
  561. self.bgImgView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  562. self.effectView.frame = self.bgImgView.bounds;
  563. }
  564. - (void)setSeekToPlay:(BOOL)seekToPlay {
  565. _seekToPlay = seekToPlay;
  566. self.portraitControlView.seekToPlay = seekToPlay;
  567. self.landScapeControlView.seekToPlay = seekToPlay;
  568. }
  569. - (void)setEffectViewShow:(BOOL)effectViewShow {
  570. _effectViewShow = effectViewShow;
  571. if (effectViewShow) {
  572. self.bgImgView.hidden = NO;
  573. } else {
  574. self.bgImgView.hidden = YES;
  575. }
  576. }
  577. - (void)setFullScreenMode:(ZFFullScreenMode)fullScreenMode {
  578. _fullScreenMode = fullScreenMode;
  579. self.portraitControlView.fullScreenMode = fullScreenMode;
  580. self.landScapeControlView.fullScreenMode = fullScreenMode;
  581. self.player.orientationObserver.fullScreenMode = fullScreenMode;
  582. }
  583. - (void)setShowCustomStatusBar:(BOOL)showCustomStatusBar {
  584. _showCustomStatusBar = showCustomStatusBar;
  585. self.landScapeControlView.showCustomStatusBar = showCustomStatusBar;
  586. }
  587. #pragma mark - getter
  588. - (UIImageView *)bgImgView {
  589. if (!_bgImgView) {
  590. _bgImgView = [[UIImageView alloc] init];
  591. _bgImgView.userInteractionEnabled = YES;
  592. }
  593. return _bgImgView;
  594. }
  595. - (UIView *)effectView {
  596. if (!_effectView) {
  597. if (@available(iOS 8.0, *)) {
  598. UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
  599. _effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
  600. } else {
  601. UIToolbar *effectView = [[UIToolbar alloc] init];
  602. effectView.barStyle = UIBarStyleBlackTranslucent;
  603. _effectView = effectView;
  604. }
  605. }
  606. return _effectView;
  607. }
  608. - (ZFPortraitControlView2 *)portraitControlView {
  609. if (!_portraitControlView) {
  610. @zf_weakify(self)
  611. _portraitControlView = [[ZFPortraitControlView2 alloc] init];
  612. _portraitControlView.sliderValueChanging = ^(CGFloat value, BOOL forward) {
  613. @zf_strongify(self)
  614. NSString *draggedTime = [ZFUtilities convertTimeSecond:self.player.totalTime*value];
  615. /// 更新滑杆和时间
  616. [self.landScapeControlView sliderValueChanged:value currentTimeString:draggedTime];
  617. self.fastProgressView.value = value;
  618. self.bottomPgrogress.isdragging = YES;
  619. self.bottomPgrogress.value = value;
  620. [self cancelAutoFadeOutControlView];
  621. };
  622. _portraitControlView.sliderValueChanged = ^(CGFloat value) {
  623. @zf_strongify(self)
  624. [self.landScapeControlView sliderChangeEnded];
  625. self.fastProgressView.value = value;
  626. self.bottomPgrogress.isdragging = NO;
  627. self.bottomPgrogress.value = value;
  628. [self autoFadeOutControlView];
  629. };
  630. _portraitControlView.clickBackBlock = ^{
  631. @zf_strongify(self)
  632. if(self.clickBackBlock){
  633. self.clickBackBlock();
  634. }
  635. };
  636. }
  637. return _portraitControlView;
  638. }
  639. - (ZFLandScapeControlView2 *)landScapeControlView {
  640. if (!_landScapeControlView) {
  641. @zf_weakify(self)
  642. _landScapeControlView = [[ZFLandScapeControlView2 alloc] init];
  643. _landScapeControlView.sliderValueChanging = ^(CGFloat value, BOOL forward) {
  644. @zf_strongify(self)
  645. NSString *draggedTime = [ZFUtilities convertTimeSecond:self.player.totalTime*value];
  646. /// 更新滑杆和时间
  647. [self.portraitControlView sliderValueChanged:value currentTimeString:draggedTime];
  648. self.fastProgressView.value = value;
  649. self.bottomPgrogress.isdragging = YES;
  650. self.bottomPgrogress.value = value;
  651. [self cancelAutoFadeOutControlView];
  652. };
  653. _landScapeControlView.sliderValueChanged = ^(CGFloat value) {
  654. @zf_strongify(self)
  655. [self.portraitControlView sliderChangeEnded];
  656. self.fastProgressView.value = value;
  657. self.bottomPgrogress.isdragging = NO;
  658. self.bottomPgrogress.value = value;
  659. [self autoFadeOutControlView];
  660. };
  661. _landScapeControlView.speedBtnClickCallback = ^(CGFloat sp){
  662. @zf_strongify(self)
  663. if(self.speedBtnClickCallback){
  664. self.speedBtnClickCallback(sp);
  665. }
  666. };
  667. _landScapeControlView.pBtnClickCallback = ^(NSInteger index,int second) {
  668. @zf_strongify(self)
  669. if(self.pBtnClickCallback){
  670. self.pBtnClickCallback(index,second);
  671. }
  672. };
  673. _landScapeControlView.nextBtnClickCallback = ^{
  674. @zf_strongify(self)
  675. if(self.nextBtnClickCallback){
  676. self.nextBtnClickCallback();
  677. }
  678. };
  679. }
  680. return _landScapeControlView;
  681. }
  682. - (ZFSpeedLoadingView *)activity {
  683. if (!_activity) {
  684. _activity = [[ZFSpeedLoadingView alloc] init];
  685. }
  686. return _activity;
  687. }
  688. - (UIView *)fastView {
  689. if (!_fastView) {
  690. _fastView = [[UIView alloc] init];
  691. _fastView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
  692. _fastView.layer.cornerRadius = 4;
  693. _fastView.layer.masksToBounds = YES;
  694. _fastView.hidden = YES;
  695. }
  696. return _fastView;
  697. }
  698. - (UIImageView *)fastImageView {
  699. if (!_fastImageView) {
  700. _fastImageView = [[UIImageView alloc] init];
  701. }
  702. return _fastImageView;
  703. }
  704. - (UILabel *)fastTimeLabel {
  705. if (!_fastTimeLabel) {
  706. _fastTimeLabel = [[UILabel alloc] init];
  707. _fastTimeLabel.textColor = [UIColor whiteColor];
  708. _fastTimeLabel.textAlignment = NSTextAlignmentCenter;
  709. _fastTimeLabel.font = [UIFont systemFontOfSize:14.0];
  710. _fastTimeLabel.adjustsFontSizeToFitWidth = YES;
  711. }
  712. return _fastTimeLabel;
  713. }
  714. - (ZFSliderView *)fastProgressView {
  715. if (!_fastProgressView) {
  716. _fastProgressView = [[ZFSliderView alloc] init];
  717. _fastProgressView.maximumTrackTintColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.4];
  718. _fastProgressView.minimumTrackTintColor = [UIColor whiteColor];
  719. _fastProgressView.sliderHeight = 2;
  720. _fastProgressView.isHideSliderBlock = NO;
  721. }
  722. return _fastProgressView;
  723. }
  724. - (UIButton *)failBtn {
  725. if (!_failBtn) {
  726. _failBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  727. [_failBtn setTitle:@"加载失败,点击重试" forState:UIControlStateNormal];
  728. [_failBtn addTarget:self action:@selector(failBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  729. [_failBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  730. _failBtn.titleLabel.font = [UIFont systemFontOfSize:14.0];
  731. _failBtn.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
  732. _failBtn.hidden = YES;
  733. }
  734. return _failBtn;
  735. }
  736. - (ZFSliderView *)bottomPgrogress {
  737. if (!_bottomPgrogress) {
  738. _bottomPgrogress = [[ZFSliderView alloc] init];
  739. _bottomPgrogress.maximumTrackTintColor = [UIColor clearColor];
  740. _bottomPgrogress.minimumTrackTintColor = [UIColor whiteColor];
  741. _bottomPgrogress.bufferTrackTintColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5];
  742. _bottomPgrogress.sliderHeight = 1;
  743. _bottomPgrogress.isHideSliderBlock = NO;
  744. }
  745. return _bottomPgrogress;
  746. }
  747. - (ZFSmallFloatControlView *)floatControlView {
  748. if (!_floatControlView) {
  749. _floatControlView = [[ZFSmallFloatControlView alloc] init];
  750. @zf_weakify(self)
  751. _floatControlView.closeClickCallback = ^{
  752. @zf_strongify(self)
  753. if (self.player.containerType == ZFPlayerContainerTypeCell) {
  754. [self.player stopCurrentPlayingCell];
  755. } else if (self.player.containerType == ZFPlayerContainerTypeView) {
  756. [self.player stopCurrentPlayingView];
  757. }
  758. [self resetControlView];
  759. };
  760. }
  761. return _floatControlView;
  762. }
  763. - (ZFVolumeBrightnessView *)volumeBrightnessView {
  764. if (!_volumeBrightnessView) {
  765. _volumeBrightnessView = [[ZFVolumeBrightnessView alloc] init];
  766. _volumeBrightnessView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
  767. _volumeBrightnessView.hidden = YES;
  768. }
  769. return _volumeBrightnessView;
  770. }
  771. - (void)setBackBtnClickCallback:(void (^)(void))backBtnClickCallback {
  772. _backBtnClickCallback = [backBtnClickCallback copy];
  773. self.landScapeControlView.backBtnClickCallback = _backBtnClickCallback;
  774. }
  775. @end