這是Xib的圖,不知道怎麼直接傳工程,知道的朋友能夠說一下,我就直接發工程了,僅供參考
#import "PlayerViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface PlayerViewController ()
{
BOOL falg;
BOOL falg1;
AVPlayerLayer *playerLayer;
NSString *URLString;
UIImageView *media_starImageView;
NSString *filePath;
NSURL *url;
NSString *urlStr;
NSArray *arr1;
unsigned int i;
}
@property (nonatomic,strong) AVPlayer *player;//播放器對象
@property (weak, nonatomic) IBOutlet UIView *container; //播放器容器
@property (weak, nonatomic) IBOutlet UIButton *playOrPause; //播放/暫停按鈕
@property (weak, nonatomic) IBOutlet UIButton *nextButton;//下一集按鈕
@property (strong, nonatomic) IBOutlet UISlider *slider;//滑塊調整播放進度
@property (weak, nonatomic) IBOutlet UIButton *fullButton;//全屏按鈕
@property (weak, nonatomic) IBOutlet UILabel *leftLabel;
@property (weak, nonatomic) IBOutlet UILabel *rightLabel;
@end
@implementation PlayerViewController
#pragma mark - 控制器視圖方法
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"視頻播放器";
//初始化視頻數組(在線播放)
arr1 = @[@"http://123.134.67.201:80/play/BEDF14F6FF4FF604DCCB053EEE20536EB33EFC37.mp4",
@"http://221.204.189.54:80/play/0F7758AF15BD3895E07E360C34B95AB42E631487.mp4",
@"http://123.134.67.198:80/play/BFD75E46DE50B2D8BBD810F259B2CC892DE9F690.mp4",
@"http://123.134.67.197:80/play/4B07614CBE84228E2645AC9F14C4BABFC5E6F0E1.mp4",
@"http://58.244.255.12/play/82846AEB3B80981E4A674374C05B3F771144D3AF/1074654_smooth.mp4"];
i = 0;
//初始化容器
self.container.frame = CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.width);
falg = YES;
falg1 = YES;
[self.playOrPause setImage:[UIImage imageNamed:@"pui_pausebtn_b_disable@2x"] forState:UIControlStateNormal];
//建立播放器層
[self setupUI];
//播放
[self.player play];
//將底部進度條等視圖提早,否則會被播放內容覆蓋掉
[self.container bringSubviewToFront:_playOrPause];
[self.container bringSubviewToFront:_nextButton];
[self.container bringSubviewToFront:_leftLabel];
[self.container bringSubviewToFront:_slider];
[self.container bringSubviewToFront:_rightLabel];
[self.container bringSubviewToFront:_fullButton];
}
-(void)dealloc{
[self removeObserverFromPlayerItem:self.player.currentItem];
[self removeNotification];
}
#pragma mark - 私有方法
-(void)setupUI{
//建立播放器層
playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = self.container.bounds;
playerLayer.videoGravity = AVLayerVideoGravityResize;//視頻填充模式
[self.container.layer addSublayer:playerLayer];
}
/**
* 截取指定時間的視頻縮略圖
*
* @param timeBySecond 時間點
*/
/**
* 初始化播放器
*
* @return 播放器對象
*/
//初始化播放器
-(AVPlayer *)player{
if (!_player) {
AVPlayerItem *playerItem=[self getPlayItem:0];
_player=[AVPlayer playerWithPlayerItem:playerItem];
//給播放器添加進度更新
[self addProgressObserver];
//給AVPlayerItem添加監控
[self addObserverToPlayerItem:playerItem];
}
return _player;
}
/**
* 根據視頻索引取得AVPlayerItem對象
*
* @param videoIndex 視頻順序索引
*
* @return AVPlayerItem對象
*/
-(AVPlayerItem *)getPlayItem:(int)videoIndex{
#warning 爲了節約體積,本地視頻沒有上傳,本身找mp4格式的本地視頻
//本地播放
// NSString *file = [[NSBundle mainBundle] pathForResource:@"火影忍者65" ofType:@"mp4"];
// NSURL *url = [NSURL fileURLWithPath:file];
//在線播放
urlStr=[NSString stringWithFormat:@"http://123.134.67.201:80/play/BEDF14F6FF4FF604DCCB053EEE20536EB33EFC37.mp4"];
url=[NSURL URLWithString:urlStr];
AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url];
return playerItem;
}
#pragma mark - 通知
/**
* 添加播放器通知
*/
-(void)addNotification{
//給AVPlayerItem添加播放完成通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
//移除本地通知
-(void)removeNotification{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
/**
* 播放完成通知
*
* @param notification 通知對象
*/
-(void)playbackFinished:(NSNotification *)notification{
NSLog(@"視頻播放完成.");
}
#pragma mark - 監控
/**
* 給播放器添加進度更新
*/
-(void)addProgressObserver{
AVPlayerItem *playerItem = self.player.currentItem;
UISlider *slider = self.slider;
[slider addTarget:self action:@selector(changeValue:) forControlEvents:UIControlEventValueChanged];
__weak PlayerViewController *blockSelf = self;
//這裏設置每秒執行一次
[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
//當前時間(秒)
float current=CMTimeGetSeconds(time);
//總時間(秒)
float total=CMTimeGetSeconds([playerItem duration]);
[blockSelf leftLabel:[blockSelf convertTime:current]];
NSLog(@"當前播放時長%@", [blockSelf convertTime:current]);
if (current) {
[slider setValue:(current/total) animated:YES];
}
}];
}
- (void)changeValue:(UISlider *)aSlider
{
AVPlayerItem *playerItem = self.player.currentItem;
//從當前位置播放
[self.player seekToTime:CMTimeMakeWithSeconds(aSlider.value * CMTimeGetSeconds([playerItem duration]), 1)];
//機智的暫停,防止形成拖動時進度條卡頓的尷尬(由於AVPlayer這個拖動後會暫停,不會自動播放)
[self.player pause];
[self.playOrPause setImage:[UIImage imageNamed:@"pui_playbtn_b_disable@2x"] forState:UIControlStateNormal];
}
//計算時間,返回字符串
- (NSString *)convertTime:(CGFloat)second{
NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
if (second/3600 >= 1) {
[formatter setDateFormat:@"01:mm:ss"];
} else {
[formatter setDateFormat:@"mm:ss"];
}
NSString *showtimeNew = [formatter stringFromDate:d];
return showtimeNew;
}
/**
* 給AVPlayerItem添加監控
*
* @param playerItem AVPlayerItem對象
*/
-(void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{
//監控狀態屬性,注意AVPlayer也有一個status屬性,經過監控它的status也能夠得到播放狀態
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
//監控網絡加載狀況屬性
[playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}
-(void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{
[playerItem removeObserver:self forKeyPath:@"status"];
[playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}
/**
* 經過KVO監控播放器狀態
*
* @param keyPath 監控屬性
* @param object 監視器
* @param change 狀態改變
* @param context 上下文
*/
//經過KVO監控播放器狀態
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
AVPlayerItem *playerItem=object;
__weak PlayerViewController *blockSelf = self;
if ([keyPath isEqualToString:@"status"]) {
AVPlayerStatus status= [[change objectForKey:@"new"] intValue];
if(status==AVPlayerStatusReadyToPlay){
[blockSelf rightLabel:[blockSelf convertTime:CMTimeGetSeconds(playerItem.duration)]];
NSLog(@"視頻總時長%@", [blockSelf convertTime:CMTimeGetSeconds(playerItem.duration)]);
}
}else if([keyPath isEqualToString:@"loadedTimeRanges"]){
NSArray *array=playerItem.loadedTimeRanges;
CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次緩衝時間範圍
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval totalBuffer = startSeconds + durationSeconds;//緩衝總長度
NSLog(@"視頻共緩衝時長%@", [blockSelf convertTime:totalBuffer]);
}
}
- (void)leftLabel:(NSString *)leftLabelText
{
_leftLabel.text = leftLabelText;
}
- (void)rightLabel:(NSString *)rightLabelText
{
_rightLabel.text = rightLabelText;
}
#pragma mark - UI事件
/**
* 點擊播放/暫停按鈕
*
* @param sender 播放/暫停按鈕
*/
- (IBAction)playClick:(UIButton *)sender {
if(self.player.rate==0){ //說明時暫停
[sender setImage:[UIImage imageNamed:@"pui_pausebtn_b_disable@2x"] forState:UIControlStateNormal];
[self.player play];
}else if(self.player.rate==1){//正在播放
[self.player pause];
[sender setImage:[UIImage imageNamed:@"pui_playbtn_b_disable@2x"] forState:UIControlStateNormal];
}
}
//關閉自動旋轉
- (BOOL)shouldAutorotate{
return NO;
}
//全屏或退出Button
- (IBAction)fullOrExit:(UIButton *)sender {
if (falg) {
[sender setImage:[UIImage imageNamed:@"pui_zoomoutbtn@2x"] forState:UIControlStateNormal];
falg = !falg;
self.container.frame = CGRectMake(0, 0, self.view.bounds.size.height, self.view.bounds.size.width);
playerLayer.frame = self.container.bounds;
[self.view bringSubviewToFront:self.container];
// playerLayer.videoGravity = AVLayerVideoGravityResize;//視頻填充模式
//旋轉屏幕,可是隻旋轉當前的View
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);
CGRect frame = [UIScreen mainScreen].applicationFrame;
self.view.bounds = CGRectMake(0, 64, frame.size.height, frame.size.width);
//隱藏導航欄
[[self navigationController] setNavigationBarHidden:YES animated:YES];
} else {
[sender setImage:[UIImage imageNamed:@"pui_zoominbtn@2x"] forState:UIControlStateNormal];
falg = !falg;
self.container.frame = CGRectMake(0, 0, self.view.bounds.size.height, self.view.bounds.size.height);
playerLayer.frame = self.container.bounds;
[self.view bringSubviewToFront:self.container];
//旋轉屏幕,可是隻旋轉當前的View
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
self.view.transform = CGAffineTransformMakeRotation(M_PI*2);
CGRect frame = [UIScreen mainScreen].applicationFrame;
self.view.bounds = CGRectMake(0, 0, frame.size.height, frame.size.width);
//顯示導航欄
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
}
//下一個視頻Button
- (IBAction)nextButton:(UIButton *)sender {
i++;
[self removeNotification];
if (i == arr1.count) {
i = 0;
}
urlStr=[NSString stringWithFormat:arr1[i]];
url=[NSURL URLWithString:urlStr];
AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url];
[self.player replaceCurrentItemWithPlayerItem:playerItem];
[self addNotification];
}
//點擊隱藏或者出現播放進度控制欄
- (IBAction)tapPlayer:(id)sender {
if (falg1) {
falg1 = !falg1;
_playOrPause.hidden = YES;
_nextButton.hidden = YES;
_slider.hidden = YES;
_fullButton.hidden = YES;
_leftLabel.hidden = YES;
_rightLabel.hidden = YES;
} else {
falg1 = !falg1;
_playOrPause.hidden = NO;
_nextButton.hidden = NO;
_slider.hidden = NO;
_fullButton.hidden = NO;
_leftLabel.hidden = NO;
_rightLabel.hidden = NO;
}
}
下面上傳圖片,只是解壓別的軟件裏面的圖片,也不知道上傳了能不能下載下來,png的傳不上去,就轉成jpg的了。
github主頁:https://github.com/ShaoWenLe