仍是直接上代码,详情以下:网络
一.ZFPlayer的导入。pod 'ZFPlayer',头文件 #import "ZFPlayer.h"app
二.在cell中使用图片看得更清晰,代码能够直接复制ide
图片: .h文件学习
.m文件atom
代码:url
// // CellShowController.h // TestZFPlayer // // Created by 黄亚男 on 2018/2/23. // Copyright © 2018年 黄亚男. All rights reserved. // #import <UIKit/UIKit.h> #import "ZFPlayer.h" @interface CellShowController : UIViewController + (instancetype)sharedInstance ; @property (nonatomic, strong) ZFPlayerView *playerView; @end
// // CellShowController.m // TestZFPlayer // // Created by 黄亚男 on 2018/2/23. // Copyright © 2018年 黄亚男. All rights reserved. //› #import "CellShowController.h" #import "VideoCell.h" @interface CellShowController ()<UITableViewDelegate,UITableViewDataSource,ZFPlayerDelegate> @property (nonatomic, strong) UITableView *tbView; //视频数据 @property (nonatomic,strong) NSArray *videoData; //图片数据 @property (nonatomic,strong) NSArray *coverUrl; @property (nonatomic, strong) ZFPlayerControlView *controlView; @end @implementation CellShowController + (instancetype)sharedInstance { static CellShowController *_sharedVideoVC = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedVideoVC = [[CellShowController alloc] init]; _sharedVideoVC.playerView = [[ZFPlayerView alloc] init]; }); return _sharedVideoVC; } //视频数据 -(NSArray *)videoData { if(!_videoData){ //网络数据,这里为假数据 _videoData = [NSArray arrayWithObjects: @"1.mp4", @"2.mp4", @"3.mp4", @"4.mp4", @"5.mp4", nil]; } return _videoData; } //图片数据 -(NSArray *)coverUrl { if(!_coverUrl){ _coverUrl = [NSArray arrayWithObjects: @"1.jpg", @"2.png", @"3.jpg", @"4.jpg", @"5.jpg", nil]; } return _coverUrl; } -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; ZFPlayerShared.isStatusBarHidden = NO; } // 页面消失时候 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.playerView resetPlayer]; } - (UIStatusBarStyle)preferredStatusBarStyle { // 这里设置横竖屏不一样颜色的statusbar if (ZFPlayerShared.isLandscape) { return UIStatusBarStyleLightContent; } return UIStatusBarStyleDefault; } - (BOOL)prefersStatusBarHidden {//ZFPlayerShared.isStatusBarHidden return ZFPlayerShared.isStatusBarHidden; } - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"cell中播放"; [self createTableView]; } -(void)createTableView { _tbView = [[UITableView alloc] initWithFrame:CGRectMake(0, 20, KSCREEN_WIDTH, KSCREEN_HEIGHT-20) style:UITableViewStyleGrouped]; _tbView.delegate = self; _tbView.dataSource = self; //隐藏cell的分割线 _tbView.separatorStyle = UITableViewCellSeparatorStyleNone; _tbView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; _tbView.estimatedRowHeight = 0; _tbView.estimatedSectionHeaderHeight = 0; _tbView.estimatedSectionFooterHeight = 0; if (@available(iOS 11.0, *)) { UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; _tbView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } [self.view addSubview:self.tbView]; } #pragma mark UITableViewDataSource---分区数 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.videoData.count; } #pragma mark UITableViewDataSource---行数 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; } #pragma mark UITableViewDataSource---行单元 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { VideoCell *cell = [VideoCell cellWithTableView:tableView]; [cell.headerImage sd_setImageWithURL:[NSURL URLWithString:self.coverUrl[indexPath.section]]]; __block NSIndexPath *weakIndexPath = indexPath; __block VideoCell *weakCell = cell; __weak typeof(self) weakSelf = self; cell.viewBlock = ^(UIView *view) { ZFPlayerModel *playerModel = [[ZFPlayerModel alloc] init]; playerModel.title = @""; //本地播放 // 文件存放路径 // NSString *path = FILE_PATH(model.fileName); // NSURL *videoURL = [NSURL fileURLWithPath:path]; //网络播放 playerModel.videoURL = [NSURL URLWithString:self.videoData[indexPath.section]]; playerModel.scrollView = weakSelf.tbView; playerModel.indexPath = weakIndexPath; // 赋值分辨率字典 //playerModel.resolutionDic = dic; // player的父视图tag playerModel.fatherViewTag = weakCell.headerImage.tag; weakSelf.playerView.delegate = self; // 设置播放控制层和model [weakSelf.playerView playerControlView:nil playerModel:playerModel]; // 下载功能 //weakSelf.playerView.hasDownload = YES; // 自动播放 [weakSelf.playerView autoPlayTheVideo]; }; return cell; } #pragma mark UITableViewDelegate---点击行单元调用 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; } #pragma mark UITableViewDelegate---表头高度 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 10; } #pragma mark UITableViewDelegate---表位高度 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.01; } #pragma mark UITableViewDelegate---行高 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 250*SCREEN_WIDTH_RATIO47; } #pragma ================视频播放================== - (ZFPlayerView *)playerView { if (!_playerView) { _playerView = [ZFPlayerView sharedPlayerView]; _playerView.delegate = self; //(可选设置)能够设置视频的填充模式 _playerView.playerLayerGravity = ZFPlayerLayerGravityResizeAspect; // 当cell播放视频由全屏变为小屏时候,不回到中间位置 // _playerView.cellPlayerOnCenter = NO; // 当cell划出屏幕的时候中止播放 _playerView.stopPlayWhileCellNotVisable = YES; // 静音 // _playerView.mute = YES; //打开预览图 self.playerView.hasPreviewView = YES; } return _playerView; } - (ZFPlayerControlView *)controlView { if (!_controlView) { _controlView = [[ZFPlayerControlView alloc] init]; _controlView.backgroundColor = [UIColor clearColor]; } return _controlView; } @end
// // VideoCell.h // TestZFPlayer // // Created by 黄亚男 on 2018/2/23. // Copyright © 2018年 黄亚男. All rights reserved. // #import <UIKit/UIKit.h> typedef void(^viewBlock)(UIView *view); @interface VideoCell : UITableViewCell @property(nonatomic, copy) viewBlock viewBlock; /**占位图*/ @property (nonatomic, strong) UIImageView *headerImage; /**播放按钮*/ @property (nonatomic, strong) UIButton *playerButton; + (instancetype)cellWithTableView:(UITableView *)tableView; @end
// // VideoCell.m // TestZFPlayer // // Created by 黄亚男 on 2018/2/23. // Copyright © 2018年 黄亚男. All rights reserved. // #import "VideoCell.h" @implementation VideoCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { //建立UI [self createUI]; } return self; } //建立UI -(void)createUI{ CGFloat originX,originY,width,hight; //背景图片 originX = 0; originY = 0; width = KSCREEN_WIDTH; hight = 250*SCREEN_WIDTH_RATIO47; UIImageView *bgView = [[UIImageView alloc] initWithFrame:CGRectMake(originX, originY, width, hight)]; _headerImage = bgView; _headerImage.tag = 20030; _headerImage.userInteractionEnabled = YES; [self.contentView addSubview:bgView]; //播放按钮 originX = KSCREEN_WIDTH/2-25; width = 50; originY = 100*SCREEN_WIDTH_RATIO47; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = CGRectMake(originX, originY, width, width); [btn setBackgroundImage:[UIImage imageNamed:@"viedo_stop_icon"] forState:UIControlStateNormal]; _playerButton = btn; btn.tag = 2005; [btn addTarget:self action:@selector(playVideo:) forControlEvents:UIControlEventTouchUpInside]; [_headerImage addSubview:btn]; } //视频播放 -(void)playVideo:(UIButton *)sender { if (self.viewBlock) { _viewBlock(sender); } } + (instancetype)cellWithTableView:(UITableView *)tableView{ static NSString *identify = @"VideoCellID"; VideoCell *cell = [tableView dequeueReusableCellWithIdentifier:identify]; if (cell == nil) { cell = [[self alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identify]; } return cell; } @end
效果图:spa
三.在View中,这个比较简单3d
上图:代理
代码:code
// // ViewShowController.m // TestZFPlayer // // Created by 黄亚男 on 2018/2/24. // Copyright © 2018年 黄亚男. All rights reserved. // #import "ViewShowController.h" @interface ViewShowController () <ZFPlayerDelegate> @property (strong, nonatomic) ZFPlayerView *playerView; /** 播放器View的父视图*/ @property (strong, nonatomic) UIImageView *fatherView; @property (nonatomic, strong) ZFPlayerModel *playerModel; @end @implementation ViewShowController -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; ZFPlayerShared.isStatusBarHidden = NO; } // 页面消失时候 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.playerView resetPlayer]; } - (UIStatusBarStyle)preferredStatusBarStyle { // 这里设置横竖屏不一样颜色的statusbar if (ZFPlayerShared.isLandscape) { return UIStatusBarStyleLightContent; } return UIStatusBarStyleDefault; } - (void)viewDidLoad { [super viewDidLoad]; [self createUI]; } -(void)createUI { UIImageView *bgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 64, KSCREEN_WIDTH, 250*SCREEN_WIDTH_RATIO47)]; _fatherView = bgView; _fatherView.tag = 10090; _fatherView.userInteractionEnabled = YES; //图片网址,为假数据 [_fatherView sd_setImageWithURL:[NSURL URLWithString:@"http://2.jpg"]]; [self.view addSubview:bgView]; //播放按钮 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = CGRectMake(KSCREEN_WIDTH/2-25, 100*SCREEN_WIDTH_RATIO47,50, 50); [btn setBackgroundImage:[UIImage imageNamed:@"viedo_stop_icon"] forState:UIControlStateNormal]; btn.tag = 2005; [btn addTarget:self action:@selector(playViewVideo:) forControlEvents:UIControlEventTouchUpInside]; [_fatherView addSubview:btn]; } - (ZFPlayerModel *)playerModel { if (!_playerModel) { _playerModel = [[ZFPlayerModel alloc] init]; _playerModel.title = @"这里设置视频标题"; _playerModel.placeholderImage = [UIImage imageNamed:@"loading_bgView1"]; _playerModel.fatherView = self.fatherView; } return _playerModel; } - (ZFPlayerView *)playerView { if (!_playerView) { _playerView = [[ZFPlayerView alloc] init]; [_playerView playerControlView:nil playerModel:self.playerModel]; // 设置代理 _playerView.delegate = self; //(可选设置)能够设置视频的填充模式,内部设置默认(ZFPlayerLayerGravityResizeAspect:等比例填充,直到一个维度到达区域边界) // _playerView.playerLayerGravity = ZFPlayerLayerGravityResize; // 打开下载功能(默认没有这个功能) _playerView.hasDownload = YES; // 打开预览图 _playerView.hasPreviewView = YES; // _playerView.forcePortrait = YES; /// 默认全屏播放 // _playerView.fullScreenPlay = YES; } return _playerView; } #pragma mark -点击按钮播放 -(void)playViewVideo:(UIButton *)btn { _playerModel.videoURL = [NSURL URLWithString:@"http://1.mp4"];//网络地址(为假连接) _playerModel.placeholderImage = [UIImage imageNamed:@"1"]; [self.playerView resetToPlayNewVideo:self.playerModel]; } #pragma mark - ZFPlayerDelegate //小屏时返回按钮 //- (void)zf_playerBackAction //{ // [self.navigationController popViewControllerAnimated:YES]; //} //下载按钮 - (void)zf_playerDownload:(NSString *)url { NSLog(@"0000"); } @end
效果图:
写的比较匆忙,不足之处,请留言
小记:在录制完视频后,直接播放本地文件时,老是出现问题,调了很久,才发现加载本地视频文件时,支持http协议,不支持file协议,须要进行路径转换:
好比在录制完生成的NSURL: file:///var/mobile/Containers/Data/Application/509C4CBD-65CC-419A-85C3-264B6988327C/Documents/Video/123456.mp4
可是ZFPlayer加载本地文件时,videoUrl为NSString类型,须要简单处理一下:
NSString *path = [[[_videoDict valueForKey:@"UIImagePickerControllerMediaURL"] absoluteString] substringFromIndex:7];
这样path 处理完为:/var/mobile/Containers/Data/Application/509C4CBD-65CC-419A-85C3-264B6988327C/Documents/Video/123456.mp4
可直接进行本地视频加载
新版本的ZFPlayer使用
在pod 文件
pod 'ZFPlayer/ControlView', '~> 3.2.13' pod 'ZFPlayer/AVPlayer', '~> 3.2.13'
在view中引入头文件
//视频 #import "ZFPlayer.h" #import "ZFPlayerControlView.h" #import "ZFAVPlayerManager.h"
//视频 @property (nonatomic, strong) ZFAVPlayerManager *playerManager; @property (nonatomic, strong) ZFPlayerController *player; //视频表头 直接继承UIView,也能够继承ZFPlayerControlView,可对视频播放进行设置 @property (nonatomic, strong) YNVideoPresidentView *videoTableHeadView; //TODO:视频表头 - (YNVideoPresidentView *)videoTableHeadView { YNWeakSelf if (!_videoTableHeadView) { _videoTableHeadView = [[YNVideoPresidentView alloc]initWithFrame:CGRectMake(0, 0, KSCREEN_WIDTH, 269)]; _videoTableHeadView.playBtnBlock = ^(UIButton * _Nonnull sender) { [weakSelf crateVideo:sender]; }; } return _videoTableHeadView; } //TODO:点击播放按钮 -(void)crateVideo:(UIButton *)sender { //视频播放 ZFAVPlayerManager *playerManager = [[ZFAVPlayerManager alloc] init]; /// 播放器相关 self.player = [ZFPlayerController playerWithPlayerManager:playerManager containerView:self.videoTableHeadView.playBackImage]; self.player.controlView = self.controlView; /// 设置退到后台继续播放 self.player.pauseWhenAppResignActive = NO; @weakify(self) self.player.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) { @strongify(self) [self setNeedsStatusBarAppearanceUpdate]; }; YNWeakSelf [self.player setPlayerPlayTimeChanged:^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) { //缓冲时间大于当前时间 if ((NSInteger)currentTime % 10 == 0 && (NSInteger)(currentTime * 10) % 10 == 0 && asset.bufferTime >= currentTime) { //每隔10s上传学习进度 [weakSelf presidentVideoRecord]; } }]; /// 播放完成 中止并设置背景图 self.player.playerDidToEnd = ^(id _Nonnull asset) { @strongify(self) [self.player.currentPlayerManager stop]; self.videoTableHeadView.playBackImage.image = GetImage(@"president_musicbg"); }; //设置播放url self.player.assetURL = [NSURL URLWithString:[YNTools getNewNSStringWithOutLogoFromString:self.homeModel.mediaUrl]]; //设置标题、封面、全屏模式 [self.controlView showTitle:self.homeModel.title coverURLString:@"" fullScreenMode:ZFFullScreenModeLandscape]; sender.hidden = YES; } //视频控制层的View - (ZFPlayerControlView *)controlView { if (!_controlView) { _controlView = [ZFPlayerControlView new]; _controlView.fastViewAnimated = NO; _controlView.prepareShowLoading = YES; _controlView.prepareShowControlView = NO; _controlView.customDisablePanMovingDirection = YES; } return _controlView; }
效果如图: