Hibit_iOS/HiBit/Project/Player/Manager/GKDYPlayerManager.m
2024-06-11 10:51:38 +08:00

505 lines
18 KiB
Objective-C
Executable File

//
// GKDYPlayerManager.m
// GKDYVideo
//
// Created by QuintGao on 2023/3/17.
// Copyright © 2023 QuintGao. All rights reserved.
//
#import "GKDYPlayerManager.h"
#import <AFNetworking/AFNetworking.h>
#import <ZFPlayer/ZFPlayer.h>
#import <ZFPlayer/ZFAVPlayerManager.h>
#import "GKDYVideoCell.h"
#import "GKRotationManager.h"
#import "GKDYVideoPortraitCell.h"
#import "GKDYVideoLandscapeCell.h"
#import "GKDYVideoFullscreenView.h"
@interface GKDYPlayerManager()<GKVideoScrollViewDataSource, GKDYVideoScrollViewDelegate, GKDYVideoPortraitCellDelegate>
@property (nonatomic, strong) ZFPlayerController *player;
@property (nonatomic, strong) GKRotationManager *rotationManager;
@property (nonatomic, assign) BOOL isSeeking;
@property (nonatomic, strong) GKDYVideoFullscreenView *fullscreenView;
@end
@implementation GKDYPlayerManager
- (instancetype)init {
if (self = [super init]) {
[self initPlayer];
}
return self;
}
- (void)dealloc {
NSLog(@"GKDYPlayerManager dealloc");
[self stop];
}
- (void)initPlayer {
// 初始化播放器
ZFAVPlayerManager *manager = [[ZFAVPlayerManager alloc] init];
ZFPlayerController *player = [[ZFPlayerController alloc] init];
player.shouldAutoPlay = YES;
player.currentPlayerManager = manager;
player.disableGestureTypes = ZFPlayerDisableGestureTypesPan | ZFPlayerDisableGestureTypesPinch;
player.allowOrentitaionRotation = NO; // 禁止自动旋转
self.player = player;
@weakify(self);
// 播放结束回调
player.playerDidToEnd = ^(id<ZFPlayerMediaPlayback> _Nonnull asset) {
@strongify(self);
[self.scrollView scrollToNextPage];
};
// 播放失败回调
player.playerPlayFailed = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, id _Nonnull error) {
@strongify(self);
self.portraitView.resumeButton.hidden = NO;
};
// 加载状态
player.playerLoadStateChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, ZFPlayerLoadState loadState) {
@strongify(self);
if ((loadState == ZFPlayerLoadStatePrepare || loadState == ZFPlayerLoadStateStalled) && self.player.currentPlayerManager.isPlaying) {
[self.portraitView.slider showLoading];
}else {
[self.portraitView.slider hideLoading];
// [self.player.currentPlayerManager play];
}
};
// 播放时间
player.playerPlayTimeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) {
@strongify(self);
[self.portraitView.slider updateCurrentTime:currentTime totalTime:duration];
};
// 方向即将改变
player.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
@strongify(self);
self.player.controlView.hidden = YES;
if (player.isFullScreen) {
[self.landscapeView startTimer];
}else {
[self.landscapeView destoryTimer];
}
};
// 方向已经改变
player.orientationDidChanged = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
@strongify(self);
if (isFullScreen) {
self.landscapeView.hidden = NO;
self.player.controlView = self.landscapeView;
}else {
self.portraitView.hidden = NO;
self.player.controlView = self.portraitView;
}
};
self.rotationManager = [GKRotationManager rotationManager];
self.rotationManager.contentView = self.player.currentPlayerManager.view;
self.landscapeView.rotationManager = self.rotationManager;
// 即将旋转时调用
self.rotationManager.orientationWillChange = ^(BOOL isFullscreen) {
@strongify(self);
self.player.controlView.hidden = YES;
if (isFullscreen) {
[self.landscapeView startTimer];
}else {
self.player.currentPlayerManager.view.backgroundColor = UIColor.clearColor;
self.portraitView.hidden = NO;
[self.landscapeView destoryTimer];
if (self.landscapeScrollView) {
UIView *superview = self.landscapeScrollView.superview;
[superview addSubview:self.rotationManager.contentView];
[self.landscapeScrollView removeFromSuperview];
self.landscapeScrollView = nil;
self.landscapeCell = nil;
}
}
};
// 旋转结束时调用
self.rotationManager.orientationDidChanged = ^(BOOL isFullscreen) {
@strongify(self);
if (isFullscreen) {
// self.portraitView.hidden = YES;
self.landscapeView.hidden = NO;
[self.landscapeView hideContainerView:NO];
if (!self.landscapeScrollView) {
[self initLandscapeScrollView];
UIView *superview = self.rotationManager.contentView.superview;
self.landscapeScrollView.frame = superview.bounds;
[superview addSubview:self.landscapeScrollView];
self.landscapeScrollView.defaultIndex = self.scrollView.currentIndex;
[self.landscapeScrollView reloadData];
}
self.player.controlView = self.landscapeView;
[self.currentCell resetView];
[self.landscapeCell hideTopView];
}else {
self.portraitView.hidden = NO;
self.landscapeView.hidden = YES;
self.player.controlView = self.portraitView;
if (self.player.containerView != self.currentCell.coverImgView) {
self.player.containerView = self.currentCell.coverImgView;
}
self.player.currentPlayerManager.view.backgroundColor = UIColor.blackColor;
}
};
player.presentationSizeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, CGSize size) {
@strongify(self);
self.videoSize = size;
};
}
- (void)initLandscapeScrollView {
self.landscapeScrollView = [[GKDYVideoScrollView alloc] init];
self.landscapeScrollView.backgroundColor = UIColor.blackColor;
self.landscapeScrollView.dataSource = self;
self.landscapeScrollView.delegate = self;
[self.landscapeScrollView registerClass:GKDYVideoLandscapeCell.class forCellReuseIdentifier:@"GKDYVideoLandscapeCell"];
}
- (BOOL)isPlaying {
return self.player.currentPlayerManager.isPlaying;
}
- (void)requestPlayUrlWithModel:(GKDYVideoModel *)model completion:(nullable void (^)(void))completion {
if (model.videoInfo.video_url.length > 0) return;
// if (model.task) {
// [model.task cancel];
// model.task = nil;
// }
//
// AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//
// NSString *url = [NSString stringWithFormat:@"https://haokan.baidu.com/v?vid=%@&_format=json&", model.video_id];
//
// model.task = [manager GET:url parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// if ([responseObject[@"errno"] integerValue] == 0) {
// NSDictionary *videoMeta = responseObject[@"data"][@"apiData"][@"curVideoMeta"];
// model.play_url = videoMeta[@"playurl"];
// model.comment = videoMeta[@"comment"];
// model.like = videoMeta[@"fmlike_num"];
//
// __block NSInteger index = 0;
// __block BOOL exist = NO;
// [self.dataSources enumerateObjectsUsingBlock:^(GKDYVideoModel *obj, NSUInteger idx, BOOL * _Nonnull stop) {
// if ([obj.video_id isEqualToString:model.video_id]) {
// index = idx;
// exist = YES;
// *stop = YES;
// }
// }];
// [self.dataSources replaceObjectAtIndex:index withObject:model];
// model.task = nil;
// !completion ?: completion();
// }
// } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
// model.task = nil;
// NSLog(@"播放地址请求失败");
// }];
}
- (void)playVideoWithCell:(GKDYVideoCell *)cell index:(NSInteger)index {
if (self.dataSources.count - index < 2) {
if ([self.delegate respondsToSelector:@selector(scrollViewShouldLoadMore)]) {
[self.delegate scrollViewShouldLoadMore];
}
}
GKDYVideoModel *model = self.dataSources[index];
self.landscapeView.model = model;
if ([cell isKindOfClass:GKDYVideoPortraitCell.class]) {
self.currentCell = (GKDYVideoPortraitCell *)cell;
self.portraitView = self.currentCell.portraitView;
self.rotationManager.containerView = cell.coverImgView;
if (self.rotationManager.isFullscreen) return;
}else {
self.landscapeCell = (GKDYVideoLandscapeCell *)cell;
[self.landscapeCell autoHide];
[self.scrollView scrollToPageWithIndex:index];
}
// 设置播放内容视图
if (self.player.containerView != cell.coverImgView) {
self.player.containerView = cell.coverImgView;
}
// 设置播放器控制层视图
if ([cell isKindOfClass:GKDYVideoPortraitCell.class]) {
GKDYVideoPortraitCell *portraitCell = (GKDYVideoPortraitCell *)cell;
if (self.player.controlView != portraitCell.portraitView) {
self.player.controlView = portraitCell.portraitView;
self.portraitView = portraitCell.portraitView;
}
}
// 设置封面图片
id<ZFPlayerMediaPlayback> manager = self.player.currentPlayerManager;
[manager.view.coverImageView sd_setImageWithURL:[NSURL URLWithString:model.image_url]];
if (model.videoInfo.video_url.length > 0) {
// 播放内容一致,不做处理
if ([self.player.assetURL.absoluteString isEqualToString:model.videoInfo.video_url]) return;
// 设置播放地址
self.player.assetURL = [NSURL URLWithString:model.videoInfo.video_url];
self.portraitView.resumeButton.hidden = YES;
if (self.isAppeared) {
[self.player.currentPlayerManager play];
}
}else {
@weakify(self);
[self requestPlayUrlWithModel:model completion:^{
@strongify(self);
// 播放内容一致,不做处理
if ([self.player.assetURL.absoluteString isEqualToString:model.videoInfo.video_url]) return;
// 设置播放地址
self.player.assetURL = [NSURL URLWithString:model.videoInfo.video_url];
self.portraitView.resumeButton.hidden = YES;
if (self.isAppeared) {
[self.player.currentPlayerManager play];
}
}];
}
}
- (void)stopPlayWithCell:(GKDYVideoCell *)cell index:(NSInteger)index {
GKDYVideoModel *model = self.dataSources[index];
if (![self.player.assetURL.absoluteString isEqualToString:model.videoInfo.video_url]) return;
[self.player stop];
if ([self.player.controlView isKindOfClass:GKDYVideoPortraitView.class]) {
[self.player.controlView removeFromSuperview];
self.player.controlView = nil;
}
[cell resetView];
}
- (void)rotate {
[self.rotationManager rotate];
}
- (void)play {
if (self.isPlaying) return;
[self.player.currentPlayerManager play];
// [self.currentCell.portraitView handleSingleTapped];
}
- (void)pause {
if (!self.isPlaying) return;
[self.player.currentPlayerManager pause];
}
- (void)stop {
[self.player.currentPlayerManager stop];
self.player = nil;
}
#pragma mark - Private
- (void)likeVideoWithModel:(GKDYVideoModel *)model {
if (model == nil) {
model = self.currentCell.model;
}
model.is_collect = YES;
[self.scrollView reloadData];
}
#pragma mark - GKVideoScrollViewDataSource
- (NSInteger)numberOfRowsInScrollView:(GKVideoScrollView *)scrollView {
return self.dataSources.count;
}
- (GKVideoViewCell *)scrollView:(GKVideoScrollView *)scrollView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
GKDYVideoModel *model = self.dataSources[indexPath.row];
if (scrollView == self.scrollView) {
GKDYVideoPortraitCell *cell = [scrollView dequeueReusableCellWithIdentifier:@"GKDYVideoPortraitCell" forIndexPath:indexPath];
cell.delegate = self;
cell.manager = self;
cell.portraitView.slider.player = self.player;
[cell loadData:model];
return cell;
}else {
GKDYVideoLandscapeCell *cell = [scrollView dequeueReusableCellWithIdentifier:@"GKDYVideoLandscapeCell" forIndexPath:indexPath];
[cell loadData:model];
@weakify(self);
cell.backClickBlock = ^{
@strongify(self);
[self rotate];
};
[cell showTopView];
return cell;
}
}
#pragma mark - GKDYVideoScrollViewDelegate
- (void)scrollView:(GKVideoScrollView *)scrollView didEndScrollingCell:(GKVideoViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[self playVideoWithCell:(GKDYVideoCell *)cell index:indexPath.row];
if ([self.delegate respondsToSelector:@selector(cellSwitchWithModel:)]) {
[self.delegate cellSwitchWithModel:self.dataSources[indexPath.row]];
}
}
- (void)scrollView:(GKVideoScrollView *)scrollView didEndDisplayingCell:(GKVideoViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[self stopPlayWithCell:(GKDYVideoCell *)cell index:indexPath.row];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.scrollView) {
if (self.scrollView.currentIndex == 0 && scrollView.contentOffset.y < 0) {
self.scrollView.contentOffset = CGPointZero;
}
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.portraitView willBeginDragging];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
[self.portraitView didEndDragging];
}
- (void)scrollView:(GKDYVideoScrollView *)scrollView didPanWithDistance:(CGFloat)distance isEnd:(BOOL)isEnd {
if ([self.delegate respondsToSelector:@selector(scrollViewDidPanDistance:isEnd:)]) {
[self.delegate scrollViewDidPanDistance:distance isEnd:isEnd];
}
}
#pragma mark - GKDYVideoPortraitCellDelegate
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickFavorite:(GKDYVideoModel *)model {
[self.scrollView reloadData];
if ([self.delegate respondsToSelector:@selector(celldidClickFavorite:cell:)]) {
[self.delegate celldidClickFavorite:model cell:cell];
}
}
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickEpiscode:(GKDYVideoModel *)model {
if ([self.delegate respondsToSelector:@selector(celldidClickEpiscode:cell:)]) {
[self.delegate celldidClickEpiscode:model cell:cell];
}
}
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickShare:(GKDYVideoModel *)model {
if ([self.delegate respondsToSelector:@selector(celldidClickShare:cell:)]) {
[self.delegate celldidClickShare:model cell:cell];
}
}
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickDanmu:(GKDYVideoModel *)model {
}
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickFullscreen:(GKDYVideoModel *)model {
[self rotate];
}
- (void)videoCell:(GKDYVideoPortraitCell *)cell zoomBegan:(GKDYVideoModel *)model {
self.player.controlView.hidden = YES;
if ([self.delegate respondsToSelector:@selector(cellZoomBegan:)]) {
[self.delegate cellZoomBegan:model];
}
}
- (void)videoCell:(GKDYVideoPortraitCell *)cell zoomEnded:(GKDYVideoModel *)model isFullscreen:(BOOL)isFullscreen {
if (isFullscreen) {
self.fullscreenView.hidden = NO;
if (self.player.controlView != self.fullscreenView) {
self.player.controlView = self.fullscreenView;
self.player.disableGestureTypes = ZFPlayerDisableGestureTypesPinch;
}
}else {
self.currentCell.portraitView.hidden = NO;
if (self.player.controlView != self.currentCell.portraitView) {
self.player.controlView = self.currentCell.portraitView;
self.player.disableGestureTypes = ZFPlayerDisableGestureTypesPan | ZFPlayerDisableGestureTypesPinch;
}
}
if ([self.delegate respondsToSelector:@selector(cellZoomEnded:isFullscreen:)]) {
[self.delegate cellZoomEnded:model isFullscreen:isFullscreen];
}
}
#pragma mark - Lazy
- (GKDYVideoScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [[GKDYVideoScrollView alloc] init];
_scrollView.dataSource = self;
_scrollView.delegate = self;
_scrollView.backgroundColor = UIColor.blackColor;
[_scrollView registerClass:GKDYVideoPortraitCell.class forCellReuseIdentifier:@"GKDYVideoPortraitCell"];
[_scrollView addPanGesture];
}
return _scrollView;
}
- (GKDYVideoLandscapeView *)landscapeView {
if (!_landscapeView) {
_landscapeView = [[GKDYVideoLandscapeView alloc] initWithFrame:UIScreen.mainScreen.bounds];
@weakify(self);
_landscapeView.likeBlock = ^(GKDYVideoModel * _Nonnull model) {
@strongify(self);
[self likeVideoWithModel:model];
};
_landscapeView.singleTapBlock = ^{
@strongify(self);
if (self.landscapeCell.isShowTop) {
[self.landscapeCell hideTopView];
[self.landscapeView hideContainerView:NO];
}else {
[self.landscapeView autoHide];
}
};
}
return _landscapeView;
}
- (GKDYVideoFullscreenView *)fullscreenView {
if (!_fullscreenView) {
_fullscreenView = [[GKDYVideoFullscreenView alloc] init];
@weakify(self);
_fullscreenView.closeFullscreenBlock = ^{
@strongify(self);
[self.currentCell closeFullscreen];
};
_fullscreenView.likeBlock = ^{
@strongify(self);
[self likeVideoWithModel:nil];
};
}
return _fullscreenView;
}
- (NSMutableArray *)dataSources {
if (!_dataSources) {
_dataSources = [NSMutableArray array];
}
return _dataSources;
}
@end