视频播放器(AVPlayer)
2016-03-07 09:07
253 查看
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";
//
初始化进度条
_progress.value
=
0;
//
添加手势
隐藏边栏<下边栏>
[self
addTapToDismissBar];
//
通过通知中心监听
播放器/视频/页面
状态信息
[self
addNotificationCenter];
//
进度条监听
[self
progressObserving];
三:初始化这个播放器
#pragma mark -
初始化播放器
- (void)createAVPlayer
{
//
视频网址
NSString
*str =
@"http://flv2.bn.netease.com/videolib3/1505/24/HYUCE6348/SD/HYUCE6348-mobile.mp4";
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;
}];
}
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";
//
初始化进度条
_progress.value
=
0;
//
添加手势
隐藏边栏<下边栏>
[self
addTapToDismissBar];
//
通过通知中心监听
播放器/视频/页面
状态信息
[self
addNotificationCenter];
//
进度条监听
[self
progressObserving];
三:初始化这个播放器
#pragma mark -
初始化播放器
- (void)createAVPlayer
{
//
视频网址
NSString
*str =
@"http://flv2.bn.netease.com/videolib3/1505/24/HYUCE6348/SD/HYUCE6348-mobile.mp4";
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;
}];
}
相关文章推荐
- 【机器学习学习过程中的笔记1——Stochastic gradient descent 和 Batch gradient descent 】
- TF-IDF及其算法
- myeclipse10 中的UTF-8 设置
- CRC16校验C语言程序源码
- 李学斌:论复杂系统中的应用间协作V3
- UESTC - 1251 谕神的密码 (模拟) 水
- 蓝桥杯-十六进制转八进制
- java中的移位操作
- sql 跨域
- 自我介绍(作业)
- 使用Retrofit 在代码混淆后 提示 Last parameter must be of type Callback or Callback
- Zend Framework教程之前端控制器Zend_Controller_Front用法详解
- 简单的百度定位
- transaction.addToBackStack(null);无效问题
- gh60 刷固件
- Android之AIDL服务
- shell编程(二):文件操作
- 数据结构(18)--Prim算法求解无向网的最小生成树
- Codeforces Round #340 (Div. 2)C. Watering Flowers(暴力)
- Oracle中"行转列"的实现方式