最近由于需求要自己单独实现视频播放,但是在网上走遍,取到的Demo都不尽人意,要么无法实现按钮的显示隐藏,要么拖动视频进度滑竿无法快进,再次自己做了一个Demo,链接为
视频播放器Demo
视频播放器播放效果图
在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要导入 MediaPlayer.Framework框架)使用方法可参考 http://blog.csdn.net/zzfsuiye/article/details/7824692,还有一种是使用AVPlayer,需要导入 AVFoundation/AVFoundation.h框架,使用稍微麻烦点,不过功能更加强大.其不仅能够播放视频(设置layer层时),而且可以实现音频播放(取消layer层的添加),能够实现在线播放等功能.
第一步 : 首先创建一个播放器视图控制器MoviePlayerController,继承自UIViewController,在其MoviePlayerController.m的延展接口 内配置如下属性:
#import "MoviePlayerController.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
//声明宏 显示主屏的宽高
#define kHeight ([[UIScreen mainScreen]bounds].size.width)
#define kWidth ([[UIScreen mainScreen]bounds].size.height)
@interface MoviePlayerController ()
@property(nonatomic,strong)AVPlayer *player; //创建播放器
@property(nonatomic,strong)AVPlayerItem *playItem; //播放对象
@property(nonatomic,strong)AVPlayerLayer *layer; //播放图层
@property (strong, nonatomic) IBOutlet UIView *backView;//和屏幕大小一样的透明的视图,其上加载有滑竿,topView,暂停按钮 , 置于控制器视图最前端
@property (strong, nonatomic) IBOutlet UIView *topView;//其上放置了返回按钮(还可以添加label显示电影名,此处省略没有添加)
@property (strong, nonatomic) IBOutlet UIButton *backButton;//返回按钮
@property (strong, nonatomic) IBOutlet UIButton *playPauseButton;//播放/暂停按钮
@property (strong, nonatomic) IBOutlet UISlider *slideView;//进度滑竿
@end
二.在viewDidLoad方法中创建播放器,并通过通知中心添加观察者监控当前播放节目的状态,同时添加计时器监听节目的时间来实现滑竿的进度变化,为了实现轻拍手势显隐 backView上的控件需要将backView置于界面的最上层
- (void)viewDidLoad {
[super viewDidLoad];
[self playMovie];
//AVPlayer播放完成通知
//给电影播放器player的当前播放对象 添加观察者,监控当前电影的播放进度
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
//计时器监听正在播放的节目的当前时间进度,每隔1秒 改变滑竿的滑块位置
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sliderChange) userInfo:nil repeats:YES];
//将放置按钮 (返回, 暂停,滑竿等)的backView移动至最顶层
[self.view bringSubviewToFront:self.backView];
}
//改变滑竿的滑块位置(滑竿的范围设置为0-1)
- (void)sliderChange {
CGFloat rateK = CMTimeGetSeconds(self.player.currentTime) / CMTimeGetSeconds(self.playItem.duration); //当前时间除以总的视频时间,(这里滑竿的范围设置为0-1,如果不为0-1则需要rateK * 滑竿范围(max - min)后赋值给下边代码的value)
self.slideView.value = rateK;
}
***AVPlayer实现的播放器需要添加layer层(相当于影院放映室的幕布),并将其添加到视图控制器的layer层上***
#pragma mark --------------------播放节目
-(void)playMovie{
//创建要播放的节目
self.playItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://baobab.cdn.wandoujia.com/14468618701471.mp4"]];
//创建播放器及播放的节目
self.player = [AVPlayer playerWithPlayerItem:self.playItem];
// self.player = [AVPlayer playerWithURL:[ NSURL URLWithString:@"http://baobab.cdn.wandoujia.com/14468618701471.mp4"]];
//创建播放图层(框) : 相当于电影播放时的幕布
AVPlayerLayer * playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = CGRectMake(0, 0, kWidth, kHeight);//设置播放框大小
//视频根据重力重设自适应size(用于横屏等转屏实现)
playerLayer.videoGravity = AVLayerVideoGravityResize;
[self.view.layer addSublayer:playerLayer];
[self.player play];//播放器播放节目
}
三. 通常点击视频播放后视频进入横屏状态其代码段如下:
#pragma mark -------------------------------------- 横屏代码 (UIViewController的方法)
//当前viewcontroller是否支持转屏
- (BOOL)shouldAutorotate{
return NO;
}
//当前viewcontroller支持哪些转屏方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
//设置转屏方式
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
//设置转屏bar隐藏
- (BOOL)prefersStatusBarHidden {
return NO; // 返回NO表示要显示,返回YES将hidden
}
四. 对于事件的处理,主要包括 轻拍实现暂停/播放按钮 , 返回按钮,滑竿等控件的显示隐藏
#pragma mark -----------------------------------------轻拍手势事件
- (IBAction)handleTapGuesterAction:(UITapGestureRecognizer *)sender {
if (self.backView.hidden == NO) {//显示
self.backView.hidden =!self.backView.hidden;
} else {
self.backView.hidden =!self.backView.hidden;
}
}
#pragma mark --------------------------------------------button事件
// 播放/暂停
- (IBAction)handlePlayPauseButtonAction:(UIButton *)sender {
//当播放速率为零时表示暂停,为1表示正常速率播放
if (self.player.rate == 0) {
[self.player play];
[sender setImage:[UIImage imageNamed:@"playBtn"] forState:UIControlStateNormal];
}else{
[self.player pause];
[sender setImage:[UIImage imageNamed:@"pauseBtn"] forState:UIControlStateNormal];
}
}
//返回电影列表界面(返回按钮)
- (IBAction)goBackMovieListButtonAction:(UIButton *)sender {
[self.player pause];
[self dismissViewControllerAnimated:YES completion:^{
}];
}
#pragma mark ----------------------------------------拖动滑竿滑块改变视频播放进度
- (IBAction)prograssSliderAction:(UISlider *)sender {
if (self.player.status == AVPlayerStatusReadyToPlay) {
//计算出拖动停止时滑块位置对应的视频的时间
//self.playItem.duration.value 当前节目的帧数,
//self.playItem.duration.timescale 当前节目的每一秒播放的帧数
float currTimeSecond = sender.value * (self.playItem.duration.value/self.playItem.duration.timescale);
//转换成CMTime才能给player来控制播放进度, 因为视频的播放是以帧为单位的
CMTime dragedCMTime = CMTimeMake(currTimeSecond, 1);
[self.player seekToTime:dragedCMTime completionHandler:^(BOOL finish){
[_player play];
}];
}
}
#pragma mark ----------------------播放结束事件
- (void)moviePlayDidEnd:(id)sender {
// [_player pause];
[self dismissViewControllerAnimated:YES completion:^{
}];
}
Share with you, never stop asking others when you have any questions , send emails to my email : nynxsjy@163.com