ZFDouYinViewController.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //
  2. // ZFDouYinViewController.m
  3. // ZFPlayer_Example
  4. //
  5. // Created by 紫枫 on 2018/6/4.
  6. // Copyright © 2018年 紫枫. All rights reserved.
  7. //
  8. #import "ZFDouYinViewController.h"
  9. #import <ZFPlayer/ZFAVPlayerManager.h>
  10. #import <ZFPlayer/ZFIJKPlayerManager.h>
  11. #import <ZFPlayer/ZFPlayerControlView.h>
  12. #import <ZFPlayer/ZFPlayerConst.h>
  13. #import "ZFTableViewCellLayout.h"
  14. #import "ZFTableData.h"
  15. #import "ZFDouYinCell.h"
  16. #import "ZFDouYinControlView.h"
  17. #import "UINavigationController+FDFullscreenPopGesture.h"
  18. #import <MJRefresh/MJRefresh.h>
  19. #import "ZFCustomControlView.h"
  20. static NSString *kIdentifier = @"kIdentifier";
  21. @interface ZFDouYinViewController () <UITableViewDelegate,UITableViewDataSource,ZFDouYinCellDelegate>
  22. @property (nonatomic, strong) UITableView *tableView;
  23. @property (nonatomic, strong) ZFPlayerController *player;
  24. @property (nonatomic, strong) ZFDouYinControlView *controlView;
  25. @property (nonatomic, strong) NSMutableArray *dataSource;
  26. @property (nonatomic, strong) UIButton *backBtn;
  27. @property (nonatomic, strong) ZFCustomControlView *fullControlView;
  28. @end
  29. @implementation ZFDouYinViewController
  30. - (void)viewDidLoad {
  31. [super viewDidLoad];
  32. self.view.backgroundColor = [UIColor whiteColor];
  33. [self.view addSubview:self.tableView];
  34. [self.view addSubview:self.backBtn];
  35. self.fd_prefersNavigationBarHidden = YES;
  36. [self requestData];
  37. MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  38. self.tableView.mj_header = header;
  39. /// playerManager
  40. ZFAVPlayerManager *playerManager = [[ZFAVPlayerManager alloc] init];
  41. // ZFIJKPlayerManager *playerManager = [[ZFIJKPlayerManager alloc] init];
  42. /// player,tag值必须在cell里设置
  43. self.player = [ZFPlayerController playerWithScrollView:self.tableView playerManager:playerManager containerViewTag:kPlayerViewTag];
  44. self.player.disableGestureTypes = ZFPlayerDisableGestureTypesPan | ZFPlayerDisableGestureTypesPinch;
  45. self.player.controlView = self.controlView;
  46. self.player.allowOrentitaionRotation = NO;
  47. self.player.WWANAutoPlay = YES;
  48. /// 1.0是完全消失时候
  49. self.player.playerDisapperaPercent = 1.0;
  50. @zf_weakify(self)
  51. self.player.playerDidToEnd = ^(id _Nonnull asset) {
  52. @zf_strongify(self)
  53. [self.player.currentPlayerManager replay];
  54. };
  55. self.player.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
  56. @zf_strongify(self)
  57. self.player.controlView.hidden = YES;
  58. };
  59. self.player.orientationDidChanged = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
  60. @zf_strongify(self)
  61. self.player.controlView.hidden = NO;
  62. if (isFullScreen) {
  63. self.player.controlView = self.fullControlView;
  64. } else {
  65. self.player.controlView = self.controlView;
  66. }
  67. };
  68. /// 更新另一个控制层的时间
  69. self.player.playerPlayTimeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) {
  70. @zf_strongify(self)
  71. if ([self.player.controlView isEqual:self.fullControlView]) {
  72. [self.controlView videoPlayer:self.player currentTime:currentTime totalTime:duration];
  73. } else if ([self.player.controlView isEqual:self.controlView]) {
  74. [self.fullControlView videoPlayer:self.player currentTime:currentTime totalTime:duration];
  75. }
  76. };
  77. /// 更新另一个控制层的缓冲时间
  78. self.player.playerBufferTimeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSTimeInterval bufferTime) {
  79. @zf_strongify(self)
  80. if ([self.player.controlView isEqual:self.fullControlView]) {
  81. [self.controlView videoPlayer:self.player bufferTime:bufferTime];
  82. } else if ([self.player.controlView isEqual:self.controlView]) {
  83. [self.fullControlView videoPlayer:self.player bufferTime:bufferTime];
  84. }
  85. };
  86. /// 停止的时候找出最合适的播放
  87. self.player.zf_scrollViewDidEndScrollingCallback = ^(NSIndexPath * _Nonnull indexPath) {
  88. @zf_strongify(self)
  89. if (self.player.playingIndexPath) return;
  90. if (indexPath.row == self.dataSource.count-1) {
  91. /// 加载下一页数据
  92. [self requestData];
  93. [self.tableView reloadData];
  94. }
  95. [self playTheVideoAtIndexPath:indexPath];
  96. };
  97. }
  98. - (void)viewWillLayoutSubviews {
  99. [super viewWillLayoutSubviews];
  100. self.backBtn.frame = CGRectMake(15, CGRectGetMaxY([UIApplication sharedApplication].statusBarFrame), 36, 36);
  101. }
  102. - (void)loadNewData {
  103. [self.dataSource removeAllObjects];
  104. @zf_weakify(self)
  105. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  106. /// 下拉时候一定要停止当前播放,不然有新数据,播放位置会错位。
  107. [self.player stopCurrentPlayingCell];
  108. [self requestData];
  109. [self.tableView reloadData];
  110. /// 找到可以播放的视频并播放
  111. [self.player zf_filterShouldPlayCellWhileScrolled:^(NSIndexPath *indexPath) {
  112. @zf_strongify(self)
  113. [self playTheVideoAtIndexPath:indexPath];
  114. }];
  115. });
  116. }
  117. - (void)requestData {
  118. NSString *path = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];
  119. NSData *data = [NSData dataWithContentsOfFile:path];
  120. NSDictionary *rootDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
  121. NSArray *videoList = [rootDict objectForKey:@"list"];
  122. for (NSDictionary *dataDic in videoList) {
  123. ZFTableData *data = [[ZFTableData alloc] init];
  124. [data setValuesForKeysWithDictionary:dataDic];
  125. [self.dataSource addObject:data];
  126. }
  127. [self.tableView.mj_header endRefreshing];
  128. }
  129. - (void)playTheIndex:(NSInteger)index {
  130. @zf_weakify(self)
  131. /// 指定到某一行播放
  132. NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
  133. [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO];
  134. [self.player zf_filterShouldPlayCellWhileScrolled:^(NSIndexPath *indexPath) {
  135. @zf_strongify(self)
  136. [self playTheVideoAtIndexPath:indexPath];
  137. }];
  138. /// 如果是最后一行,去请求新数据
  139. if (index == self.dataSource.count-1) {
  140. /// 加载下一页数据
  141. [self requestData];
  142. [self.tableView reloadData];
  143. }
  144. }
  145. - (BOOL)shouldAutorotate {
  146. return NO;
  147. }
  148. - (UIStatusBarStyle)preferredStatusBarStyle {
  149. return UIStatusBarStyleLightContent;
  150. }
  151. - (BOOL)prefersStatusBarHidden {
  152. return NO;
  153. }
  154. - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
  155. return UIInterfaceOrientationMaskPortrait;
  156. }
  157. #pragma mark - UIScrollViewDelegate 列表播放必须实现
  158. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  159. [scrollView zf_scrollViewDidEndDecelerating];
  160. }
  161. - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
  162. [scrollView zf_scrollViewDidEndDraggingWillDecelerate:decelerate];
  163. }
  164. - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView {
  165. [scrollView zf_scrollViewDidScrollToTop];
  166. }
  167. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  168. [scrollView zf_scrollViewDidScroll];
  169. }
  170. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  171. [scrollView zf_scrollViewWillBeginDragging];
  172. }
  173. #pragma mark - ZFDouYinCellDelegate
  174. - (void)zf_douyinRotation {
  175. UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown;
  176. if (self.player.isFullScreen) {
  177. orientation = UIInterfaceOrientationPortrait;
  178. } else {
  179. orientation = UIInterfaceOrientationLandscapeRight;
  180. }
  181. [self.player rotateToOrientation:orientation animated:YES completion:nil];
  182. }
  183. #pragma mark - UITableViewDataSource
  184. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  185. return self.dataSource.count;
  186. }
  187. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  188. ZFDouYinCell *cell = [tableView dequeueReusableCellWithIdentifier:kIdentifier];
  189. cell.delegate = self;
  190. cell.data = self.dataSource[indexPath.row];
  191. return cell;
  192. }
  193. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  194. [self playTheVideoAtIndexPath:indexPath];
  195. }
  196. #pragma mark - ZFTableViewCellDelegate
  197. - (void)zf_playTheVideoAtIndexPath:(NSIndexPath *)indexPath {
  198. [self playTheVideoAtIndexPath:indexPath];
  199. }
  200. #pragma mark - private method
  201. - (void)backClick:(UIButton *)sender {
  202. [self.navigationController popViewControllerAnimated:YES];
  203. }
  204. /// play the video
  205. - (void)playTheVideoAtIndexPath:(NSIndexPath *)indexPath {
  206. ZFTableData *data = self.dataSource[indexPath.row];
  207. [self.player playTheIndexPath:indexPath assetURL:[NSURL URLWithString:data.video_url]];
  208. [self.controlView resetControlView];
  209. [self.controlView showCoverViewWithUrl:data.thumbnail_url];
  210. [self.fullControlView showTitle:@"custom landscape controlView" coverURLString:data.thumbnail_url fullScreenMode:ZFFullScreenModeLandscape];
  211. }
  212. #pragma mark - getter
  213. - (UITableView *)tableView {
  214. if (!_tableView) {
  215. _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  216. _tableView.pagingEnabled = YES;
  217. [_tableView registerClass:[ZFDouYinCell class] forCellReuseIdentifier:kIdentifier];
  218. _tableView.backgroundColor = [UIColor lightGrayColor];
  219. _tableView.delegate = self;
  220. _tableView.dataSource = self;
  221. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  222. _tableView.showsVerticalScrollIndicator = NO;
  223. _tableView.scrollsToTop = NO;
  224. if (@available(iOS 11.0, *)) {
  225. _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  226. } else {
  227. self.automaticallyAdjustsScrollViewInsets = NO;
  228. }
  229. _tableView.estimatedRowHeight = 0;
  230. _tableView.estimatedSectionFooterHeight = 0;
  231. _tableView.estimatedSectionHeaderHeight = 0;
  232. _tableView.frame = self.view.bounds;
  233. _tableView.rowHeight = _tableView.frame.size.height;
  234. _tableView.scrollsToTop = NO;
  235. }
  236. return _tableView;
  237. }
  238. - (ZFDouYinControlView *)controlView {
  239. if (!_controlView) {
  240. _controlView = [ZFDouYinControlView new];
  241. }
  242. return _controlView;
  243. }
  244. - (ZFCustomControlView *)fullControlView {
  245. if (!_fullControlView) {
  246. _fullControlView = [[ZFCustomControlView alloc] init];
  247. }
  248. return _fullControlView;
  249. }
  250. - (NSMutableArray *)dataSource {
  251. if (!_dataSource) {
  252. _dataSource = @[].mutableCopy;
  253. }
  254. return _dataSource;
  255. }
  256. - (UIButton *)backBtn {
  257. if (!_backBtn) {
  258. _backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  259. [_backBtn setImage:[UIImage imageNamed:@"icon_titlebar_whiteback"] forState:UIControlStateNormal];
  260. [_backBtn addTarget:self action:@selector(backClick:) forControlEvents:UIControlEventTouchUpInside];
  261. }
  262. return _backBtn;
  263. }
  264. @end