RQDspVideoDetailViewController.m 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. //
  2. // RQDspVideoDetailViewController.m
  3. // SDJK
  4. //
  5. // Created by RONGQING on 2022/1/19.
  6. //
  7. #import "RQDspVideoDetailViewController.h"
  8. #import <ZFPlayer/ZFAVPlayerManager.h>
  9. #import <ZFPlayer/ZFIJKPlayerManager.h>
  10. #import <ZFPlayer/ZFPlayerControlView.h>
  11. #import <ZFPlayer/ZFPlayerConst.h>
  12. #import "MPTransition.h"
  13. /// 播放器view的tag,列表中UI控件唯一tag值
  14. #define kPlayerViewTag 100
  15. static NSString *kIdentifier = @"kIdentifier";
  16. @interface RQDspVideoDetailViewController ()
  17. /// viewModel
  18. @property (nonatomic, readonly, strong) RQDspVideoDetailViewModel *viewModel;
  19. @property (nonatomic, readwrite, strong) UIButton *backBtn;
  20. @property (nonatomic, readwrite, strong) RQDspVideoDetailControlView *controlView;
  21. @property (nonatomic, readwrite, strong) NSIndexPath *playingIndexPath;
  22. @property (nonatomic, readwrite, strong) ZFPlayerControlView *preControlView;
  23. @property (nonatomic, readwrite, assign) BOOL isInited;
  24. @property (nonatomic, readwrite, assign) BOOL isPassPlayer;
  25. @property (nonatomic, readwrite, strong) MPPlayerController *player;
  26. @property (nonatomic, readwrite, assign) NSInteger index;
  27. @property (nonatomic, readwrite, strong) NSMutableArray *dataSource;
  28. @property (nonatomic, strong) UIView *startView;
  29. @property (nonatomic, strong) UIImage *startImage;
  30. @property (nonatomic, copy) void(^popbackBlock)(void);
  31. @end
  32. @implementation RQDspVideoDetailViewController
  33. @dynamic viewModel;
  34. #pragma mark - SystemMethod
  35. - (void)viewDidLoad {
  36. [super viewDidLoad];
  37. /// 初始化
  38. [self rq_setup];
  39. }
  40. - (void)viewDidLayoutSubviews {
  41. [super viewDidLayoutSubviews];
  42. self.backBtn.frame = CGRectMake(15, CGRectGetMaxY([UIApplication sharedApplication].statusBarFrame), 36, 36);
  43. }
  44. - (void)viewDidAppear:(BOOL)animated {
  45. [super viewDidAppear:animated];
  46. if (!self.isInited) {
  47. self.isInited = YES;
  48. if (self.isPassPlayer) {
  49. UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.playingIndexPath];
  50. UIView *playerView = [cell viewWithTag:10086];
  51. self.player.controlView = self.controlView;
  52. if (playerView) {
  53. [self.player updateNoramlPlayerWithContainerView:playerView];
  54. [self.controlView resetControlView];
  55. VideosItem *videosItem = self.dataSource[self.playingIndexPath.row];
  56. UIViewContentMode imageMode;
  57. if (videosItem.videoWidth >= videosItem.videoHeight) {
  58. imageMode = UIViewContentModeScaleAspectFit;
  59. } else {
  60. imageMode = UIViewContentModeScaleAspectFill;
  61. }
  62. [self.controlView showCoverViewWithUrl:videosItem.coverFileUrl withImageMode:imageMode];
  63. }
  64. }else {
  65. self.player.controlView = self.controlView;
  66. [self playTheVideoAtIndexPath:self.playingIndexPath scrollToTop:NO];
  67. }
  68. }
  69. self.navigationController.delegate = self;
  70. }
  71. #pragma mark - PrivateMethods
  72. /// 初始化
  73. - (void)rq_setup {
  74. @weakify(self)
  75. self.tableView.pagingEnabled = YES;
  76. self.tableView.showsVerticalScrollIndicator = NO;
  77. self.tableView.scrollsToTop = NO;
  78. self.index = self.viewModel.indexPath.row;
  79. [self.view addSubview:self.backBtn];
  80. if (!self.player) {
  81. self.player = [MPPlayerController playrWithContainerView:[UIView new]];
  82. [self requestData];
  83. self.player.playableArray = self.dataSource;
  84. }else {
  85. for(UIView *subView in self.player.currentPlayerManager.view.subviews) {
  86. [subView removeFromSuperview];
  87. }
  88. self.isPassPlayer = YES;
  89. }
  90. self.player.presentationSizeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, CGSize size) {
  91. @strongify(self)
  92. if (size.width >= size.height) {
  93. self.player.currentPlayerManager.scalingMode = ZFPlayerScalingModeAspectFit;
  94. } else {
  95. self.player.currentPlayerManager.scalingMode = ZFPlayerScalingModeAspectFill;
  96. }
  97. };
  98. [self.tableView reloadData];
  99. self.playingIndexPath = [NSIndexPath indexPathForRow:self.index inSection:0];
  100. [self.tableView scrollToRowAtIndexPath:self.playingIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
  101. }
  102. - (void)requestData {
  103. [self.dataSource addObjectsFromArray:RQ_COMMON_MANAGER.dspListArr];
  104. self.player.playableArray = self.dataSource;
  105. }
  106. - (void)backClick:(UIButton *)sender {
  107. [self.navigationController popViewControllerAnimated:YES];
  108. }
  109. /// play the video
  110. - (void)playTheVideoAtIndexPath:(NSIndexPath *)indexPath scrollToTop:(BOOL)scrollToTop {
  111. UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
  112. UIView *contanier = [cell viewWithTag:10086];
  113. [self.player updateNoramlPlayerWithContainerView:contanier];
  114. [self.player playWithPlayable:self.dataSource[indexPath.row]];
  115. [self.controlView resetControlView];
  116. VideosItem *videosItem = self.dataSource[indexPath.row];
  117. UIViewContentMode imageMode;
  118. if (videosItem.videoWidth >= videosItem.videoHeight) {
  119. imageMode = UIViewContentModeScaleAspectFit;
  120. } else {
  121. imageMode = UIViewContentModeScaleAspectFill;
  122. }
  123. [self.controlView showCoverViewWithUrl:videosItem.coverFileUrl withImageMode:imageMode];
  124. self.playingIndexPath = indexPath;
  125. }
  126. - (void)didMoveToParentViewController:(UIViewController *)parent {
  127. if (!parent) {
  128. if (self.isPassPlayer) {
  129. [self.controlView removeFromSuperview];
  130. for (UIView *subView in self.player.currentPlayerManager.view.subviews) {
  131. [subView removeFromSuperview];
  132. }
  133. self.player.controlView = self.preControlView;
  134. if (self.popbackBlock) {
  135. self.popbackBlock();
  136. }
  137. }
  138. }
  139. }
  140. #pragma mark - UIScrollViewDelegate 列表播放必须实现
  141. - (void)cellPlayVideo {
  142. if (self.tableView.visibleCells.count && self.tableView.visibleCells.count == 1) {
  143. UITableViewCell *cell = self.tableView.visibleCells.firstObject;
  144. NSIndexPath *ip = [self.tableView indexPathForCell:cell];
  145. NSComparisonResult result = [ip compare:self.playingIndexPath];
  146. // 判断indexPath是否发生变化
  147. if (ip && result != NSOrderedSame) {
  148. [self.player stop];
  149. [self playTheVideoAtIndexPath:ip scrollToTop:NO];
  150. }
  151. if (ip) {
  152. self.playingIndexPath = ip;
  153. }
  154. }
  155. }
  156. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  157. [self cellPlayVideo];
  158. }
  159. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  160. [self handlePlayerOutofScreen: scrollView];
  161. }
  162. - (void)handlePlayerOutofScreen: (UIScrollView *)scrollView {
  163. // 为了处理快速滑动时,player复用的bug
  164. UIView *cell = [self.tableView cellForRowAtIndexPath:self.playingIndexPath];
  165. if (!cell && self.playingIndexPath) {
  166. [self.player stop];
  167. return;
  168. }
  169. }
  170. #pragma mark - OverrideMethods
  171. - (UIEdgeInsets)contentInset {
  172. return UIEdgeInsetsMake(0, 0, 0, 0);
  173. }
  174. - (UITableViewCell *)tableView:(UITableView *)tableView dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath {
  175. switch (indexPath.section) {
  176. case 0: {
  177. RQDspVideoDetailCell *cell = [RQDspVideoDetailCell cellWithTableView:tableView];
  178. return cell;
  179. }
  180. default:
  181. return [super tableView:tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
  182. }
  183. }
  184. - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath withObject:(id)object {
  185. switch (indexPath.section) {
  186. case 0: {
  187. RQDspVideoDetailCell *dspVideoDetailCell = (RQDspVideoDetailCell *)cell;
  188. [dspVideoDetailCell bindViewModel:object];
  189. break;
  190. }
  191. default: {
  192. [super configureCell:cell atIndexPath:indexPath withObject:object];
  193. break;
  194. }
  195. }
  196. }
  197. #pragma mark - LazyLoad
  198. - (void)setPlayer:(MPPlayerController *)player {
  199. _player = player;
  200. self.preControlView = (ZFPlayerControlView *)player.controlView;
  201. [self.preControlView removeFromSuperview];
  202. }
  203. - (RQDspVideoDetailControlView *)controlView {
  204. if (!_controlView) {
  205. _controlView = [RQDspVideoDetailControlView new];
  206. }
  207. return _controlView;
  208. }
  209. - (UIButton *)backBtn {
  210. if (!_backBtn) {
  211. _backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  212. [_backBtn setImage:[UIImage imageNamed:@"icon_titlebar_whiteback"] forState:UIControlStateNormal];
  213. [_backBtn addTarget:self action:@selector(backClick:) forControlEvents:UIControlEventTouchUpInside];
  214. }
  215. return _backBtn;
  216. }
  217. - (NSMutableArray *)dataSource {
  218. if (!_dataSource) {
  219. _dataSource = @[].mutableCopy;
  220. }
  221. return _dataSource;
  222. }
  223. - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
  224. if (self.startView == nil)
  225. return nil;
  226. if (self.playingIndexPath &&
  227. self.playingIndexPath.row != self.index)
  228. return nil;
  229. return [MPTransition animationWithDuration:0.3 startView:self.startView startImage:self.startImage player:self.player operation:operation completion:^{
  230. }];
  231. }
  232. @end