仍是直接上代碼,詳情以下:網絡
一.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; }
效果如圖: