1.首先得创建AVPlayer,一个播放对象。
2.但是AVPlayer不能直接添加到self.view上,所以我们得创建一个 AVPlayerLayer的对象,是播放器所在的图层,设置视频填充的模式,然后将AVPlayer添加到此图层上,再将这个图层添加到self.view或者子视图的layer图层上。
3.设置播放的对象,就是AVPlayer播放的资源
下面是代码的展示:
一:首先我们需要引进能够支持AVPlayer视频播放的框架。同时这个框架还是音频播放的框架
#import
<AVFoundation/AVFoundation.h>
将self.view的尺寸设置成全局
#define WIDTH self.view.bounds.size.width
#define HEIGHT self.view.bounds.size.height
@interface
ViewController
()
在Main.storyboard将这些布局设置好。
@property
(
weak
,
nonatomic
)
IBOutlet
UIView
*buttomVIew;
/**<
底部控制区
*/
@property
(
weak
,
nonatomic
)
IBOutlet
UIButton
*buttomBtn;
@property
(
weak
,
nonatomic
)
IBOutlet
UISlider
*progress;
/**<
进度条
*/
@property
(
weak
,
nonatomic
)
IBOutlet
UILabel
*timeLabel;
/**<
时间显示
*/
@property
(
weak
,
nonatomic
)
IBOutlet
UIView
*playerView;
/**<
播放视图
*/
进行基本属性的设置
@property
(
nonatomic
,
strong
)
AVPlayer
*player;
/**<
播放器对象
*/
@property
(
nonatomic
,
strong
)
AVPlayerLayer
*playerLayer;
/**<
播放图层
*/
@property
(
nonatomic
,
strong
)
AVPlayerItem
*playerItem;
/**<
播放对象
*/
@property
(
nonatomic
,
assign
)
BOOL
isPlay;
/**<
是否播放
*/
@property
(
nonatomic
,
assign
)
BOOL
isDismiss;
/**<
是否隐藏
*/
@property
(
nonatomic
,
assign
)
CGFloat
totalDuration;
/**<
总时长
*/
@end
二:在viewDidLoad中需要实现的方法或者设置的总体步骤
- (
void
)viewDidLoad {
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
// 初始化播放器
[ self createAVPlayer ];
// 播放
[ _player play ];
// 开始播放
_isPlay = YES ;
// 初始化时间显示
_timeLabel . text = @"00:00/00:00" ;
// 初始化进度条
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
// 初始化播放器
[ self createAVPlayer ];
// 播放
[ _player play ];
// 开始播放
_isPlay = YES ;
// 初始化时间显示
_timeLabel . text = @"00:00/00:00" ;
// 初始化进度条
_progress.value = 0;
// 添加手势 隐藏边栏<下边栏>
[
self
addTapToDismissBar
];
// 通过通知中心监听 播放器 / 视频 / 页面 状态信息
[ self addNotificationCenter ];
// 进度条监听
// 通过通知中心监听 播放器 / 视频 / 页面 状态信息
[ self addNotificationCenter ];
// 进度条监听
[self progressObserving];
三:初始化这个播放器
#pragma mark -
初始化播放器
- (
void
)createAVPlayer
{
//
视频网址
NSURL
*url = [
NSURL
URLWithString
:str];
//
创建播放对象
(playerItem),就是需要播放的资源
self
.
playerItem
= [
AVPlayerItem
playerItemWithURL
:url];
//
创建播放器
(player)
self
.
player
= [
AVPlayer
playerWithPlayerItem
:
_playerItem
];
//
创建显示
layer(playerLayer) 只有放在这个layer上才可以显示。
self
.
playerLayer
= [
AVPlayerLayer
playerLayerWithPlayer
:
_player
];
// layer
需要设置大小
_playerLayer
.
frame
=
CGRectMake
(
5
,
5
,
self
.
view
.
bounds
.
size
.
width
-
10
,
_playerView
.
frame
.
size
.
height
-
10
);
//
视频填充模式
_playerLayer
.
videoGravity
=
AVLayerVideoGravityResizeAspectFill
;
//
将显示的图层
放在页面里显示
[
_playerView
.
layer
insertSublayer
:
_playerLayer
atIndex
:
0
];
}
四:添加手势
#pragma mark -
添加手势
- (
void
)addTapToDismissBar
{
UITapGestureRecognizer
*tap = [[
UITapGestureRecognizer
alloc
]
initWithTarget
:
self
action
:
@selector
(tapAction:)];
[
_playerView
addGestureRecognizer
:tap];
}
#pragma mark -
隐藏边栏
- (
void
)tapAction:(
UITapGestureRecognizer
*)tap
{
//
初始播放
还未隐藏
isDismiss = NO
//
隐藏
if
(!
_isDismiss
) {
//
隐藏边栏
[
UIView
animateWithDuration
:
0.5
animations
:^{
_buttomVIew
.
alpha
=
0
;
}];
}
else
{
//
显示边栏
[
UIView
animateWithDuration
:
0.5
animations
:^{
_buttomVIew
.
alpha
=
0.8
;
}];
}
_isDismiss
= !
_isDismiss
;
}
五:#pragma mark -
通知中心
- (
void
)addNotificationCenter
{
//
是否播放完成
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(moviePlayDidEnd:)
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
nil
];
//
监听屏幕旋转
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(statusBarPositionChange:)
name
:
UIApplicationDidChangeStatusBarOrientationNotification
object
:
nil
];
}
#pragma mark -视频播放结束时进行的操作,可以在这里设置,进行下一个视频的播放。
- (
void
)moviePlayDidEnd:(
NSNotification
*)noti
{
NSLog
(
@"
视频播放已经结束
"
);
}
#pragma mark -监听屏幕是否旋转
- (
void
)statusBarPositionChange:(
NSNotification
*)noti
{
//
使用代码监听横竖屏
//
获取状态栏方向
UIInterfaceOrientation
orientation = [[
UIApplication
sharedApplication
]
statusBarOrientation
];
//
判断
if
(orientation ==
UIInterfaceOrientationLandscapeLeft
) {
NSLog
(
@"
向左横屏
"
);
[
self
landscape
];
}
else
if
(orientation ==
UIInterfaceOrientationLandscapeRight
) {
NSLog
(
@"
向右横屏
"
);
[
self
landscape
];
}
else
if
(orientation ==
UIInterfaceOrientationPortrait
) {
NSLog
(
@"
竖屏
"
);
[
self
portrait
];
}
}
#pragma mark -
横屏设置
- (
void
)landscape
{
_playerView
.
frame
=
self
.
view
.
bounds
;
_playerView
.
backgroundColor
= [
UIColor
redColor
];
_playerLayer
.
frame
=
CGRectMake
(
5
,
5
,
WIDTH
-
10
,
HEIGHT
-
10
);
NSLog
(
@"%@ %@"
,
NSStringFromCGRect
(
_playerView
.
frame
),
NSStringFromCGRect
(
self
.
view
.
frame
));
}
#pragma mark -
竖屏设置
- (
void
)portrait
{
_playerView
.
backgroundColor
= [
UIColor
cyanColor
];
_playerLayer
.
frame
=
CGRectMake
(
5
,
5
,
WIDTH
-
10
,
230
);
}
六:进度条监听
/*
CMTimeMake
是用來建立
CMTime
用的
,
CMTime
可是专门用来表示视频时间的
,
用法
: CMTimeMake(time, timeScale)
time
指的就是时间
(
不是秒
),
而时间要换成秒就要看第二个参数
timeScale
了
.
timeScale
指的是
1
秒需要由多少帧率构成
,
真正表示时间秒是
time / timeScale .
CMTime curFrame = CMTimeMake(
第几帧,
帧率)
*/
#pragma mark -
进度条监听
- (
void
)progressObserving
{
//
设置
(1, 1)
每秒刷新一次
//
参数
1:
时间监听器刷新时间
//
参数
2:
队列
//
参数
3:
刷新时执行的
block
__weak
ViewController
*vc =
self
;
[
_player
addPeriodicTimeObserverForInterval
:
CMTimeMake
(
1
,
1
)
queue
:
dispatch_get_main_queue
()
usingBlock
:^(
CMTime
time) {
//
获取总时长
CGFloat
duration =
CMTimeGetSeconds
(vc.
playerItem
.
duration
);
//
获取当前时长
CGFloat
current =
CMTimeGetSeconds
(vc.
player
.
currentTime
);
//
获取倒计时
CGFloat
rem = duration - current;
//
剩余时间
NSString
*totalT = [
NSString
stringWithFormat
:
@"%02d:%02d"
, (
int
)rem /
60
, (
int
)rem %
60
];
//
当前时间
NSString
*currentT = [
NSString
stringWithFormat
:
@"%02d:%02d"
, (
int
)current /
60
, (
int
)current %
60
];
//
拼接时间
NSString
*timeStr = [
NSString
stringWithFormat
:
@"%@/%@"
, currentT, totalT];
vc.
timeLabel
.
text
= timeStr;
//
保存总时长
用于
slider
手动控制进度
vc.
totalDuration
= duration;
//
控制
slider
的当前进度
vc.
progress
.
value
= current / duration;
}];
}