//
// ViewController.m
// VideoPlay
//
//
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController (){
AVPlayer *player;
AVPlayerItem*item;
AVPlayerLayer *showVideoLayer ;
NSTimer * sliderTimer;
UIButton *button;
UIButton *stopBtn;
UIButton *fullScreenbBtn;
}
@property(nonatomic,strong)UISlider *slider;
@property (assign, nonatomic)BOOL isReadToPlay;
@property(assign,nonatomic)BOOL isFullScreen;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"http://221.228.226.8/5/o/t/q/n/otqntbuuqzoaoolokhamenlecztdph/hc.yinyuetai.com/F28501478A4F57F03808A953E5A818CD.flv?sc=0b0c1a531cf7ecbe"];
item = [AVPlayerItem playerItemWithURL:url];
player = [AVPlayer playerWithPlayerItem:item];
showVideoLayer = [AVPlayerLayer playerLayerWithPlayer:player];
showVideoLayer.frame = CGRectMake(0, 200, self.view.frame.size.width, 300);
[self.view.layer addSublayer:showVideoLayer];
[item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
[self.slider addTarget:self action:@selector(action) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchCancel|UIControlEventTouchUpOutside];
button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(30, 530, 50, 30);
button.backgroundColor = [UIColor redColor];
[button setTitle:@"播放" forState:UIControlStateNormal];
[button addTarget:self action:@selector(playAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
stopBtn = [UIButton buttonWithType:UIButtonTypeSystem];
stopBtn.frame = CGRectMake(self.view.bounds.size.width-80, 530, 50, 30);
stopBtn.backgroundColor = [UIColor redColor];
[stopBtn setTitle:@"暂停" forState:UIControlStateNormal];
[stopBtn addTarget:self action:@selector(stopAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:stopBtn];
;
sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES];
[sliderTimer setFireDate:[NSDate distantFuture]];
fullScreenbBtn = [UIButton buttonWithType:UIButtonTypeSystem];
fullScreenbBtn.frame = CGRectMake(self.view.bounds.size.width/2-25, 530, 50, 30);
fullScreenbBtn.backgroundColor = [UIColor redColor];
[fullScreenbBtn setTitle:@"全屏" forState:UIControlStateNormal];
[fullScreenbBtn addTarget:self action:@selector(fullAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:fullScreenbBtn];
}
/*************计算播放进度,刷新进度条****************************/
-(void)updateSlider{
float seconds = CMTimeGetSeconds(item.duration);
_slider.maximumValue = 1;
NSLog(@"总时长:%f",seconds);
float current = CMTimeGetSeconds(item.currentTime);
NSLog(@"当前进度:%f",current);
_slider.value = CMTimeGetSeconds(item.currentTime) / CMTimeGetSeconds(item.duration);
NSLog(@"播放进度%f",_slider.value);
if (_slider.value ==1) {
_slider.value = 0;
}
}
/****************播放视频,恢复定时器*******************/
-(void)playAction{
if ( self.isReadToPlay) {
//开始计时
[sliderTimer setFireDate:[NSDate date]];
[player play];
}else{
NSLog(@"视频正在加载中");
}
}
/****************暂停视频,暂停定时器*******************/
-(void)stopAction {
[sliderTimer setFireDate:[NSDate distantFuture]];
[player pause];
}
/****************全屏/小屏**************************/
-(void)fullAction{
if (self.isFullScreen == NO) {
NSLog(@"全屏");
[UIView animateWithDuration:0.25 animations:^{
self.view.transform = CGAffineTransformMakeRotation(M_PI / 2);
}];
self.view.frame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
showVideoLayer.frame = CGRectMake(25, 25, [[UIScreen mainScreen] bounds].size.height-50, [[UIScreen mainScreen] bounds].size.width-100);
showVideoLayer.backgroundColor = [UIColor redColor].CGColor;
button.frame = CGRectMake(50, [UIScreen mainScreen].bounds.size.width-50, 50, 30);
stopBtn.frame = CGRectMake([UIScreen mainScreen].bounds.size.height-100, [UIScreen mainScreen].bounds.size.width - 50, 50, 30);
fullScreenbBtn.frame = CGRectMake([UIScreen mainScreen].bounds.size.height/2.0-25, [UIScreen mainScreen].bounds.size.width-50, 50, 30);
self.isFullScreen = YES;
_slider.frame=CGRectMake(10, 0,[UIScreen mainScreen].bounds.size.height-20, 30);
}else {
NSLog(@"小屏");
[UIView animateWithDuration:0.25 animations:^{
self.view.transform = CGAffineTransformMakeRotation(M_PI*2);
//复原
//CGAffineTransformIdentity;
}];
self.view.frame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
showVideoLayer.frame =CGRectMake(0, 200, self.view.frame.size.width, 300);
showVideoLayer.backgroundColor = [UIColor redColor].CGColor;
button.frame = CGRectMake(30, 530, 50, 30);
stopBtn.frame = CGRectMake(self.view.bounds.size.width-80, 530, 50, 30);
fullScreenbBtn.frame = CGRectMake(self.view.bounds.size.width/2-25, 530, 50, 30);
_slider.frame=CGRectMake(10, [UIScreen mainScreen].bounds.size.height-50, [UIScreen mainScreen].bounds.size.width-20, 30);
self.isFullScreen = NO;
}
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.isFullScreen = NO;
}
/************懒加载创建滑块(进度条)*****************/
-(UISlider*)slider {
if(!_slider){
_slider = [[UISlider alloc] initWithFrame:CGRectMake(10, self.view.frame.size.height-50, self.view.bounds.size.width-20, 30)];
_slider.minimumTrackTintColor = [UIColor redColor];
_slider.maximumValue = 1;
_slider.maximumTrackTintColor = [UIColor lightGrayColor];
[self.view addSubview:_slider];
}
return _slider;
}
/******************监测加载时的状态**********************************/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:
(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"status"]) {
//取出status的新值
AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey]intValue];
switch (status) {
case AVPlayerItemStatusFailed:
NSLog(@"item 有误");
self.isReadToPlay = NO;
break;
case AVPlayerItemStatusReadyToPlay:
NSLog(@"准好播放了");
self.isReadToPlay = YES;
self.slider.maximumValue = item.duration.value / item.duration.timescale;
break;
case AVPlayerItemStatusUnknown:
NSLog(@"视频资源出现未知错误");
self.isReadToPlay = NO;
break;
default:
break;
}
}
//移除监听(观察者)
[object removeObserver:self forKeyPath:@"status"];
}
/**************移动滑块t,跳转到指定进度******************************/
- (void)action{
//暂停定时器:原理是把触发时间设置在未来,既很久之后,这样定时器自动进入等待触发的状态,估计要等很久。。。
[sliderTimer setFireDate:[NSDate distantFuture]];
float sec = CMTimeGetSeconds(item.duration);
//slider的value值为视频的时间
float seconds = self.slider.value*sec;
//让视频从指定的CMTime对象处播放。
CMTime startTime = CMTimeMakeWithSeconds(seconds, item.currentTime.timescale);
//让视频从指定处播放 senkToTime 跳转进度
[player seekToTime:startTime completionHandler:^(BOOL finished) {
if (finished) {
[self playAction];
}
}];
}
-(void)dealloc {
[sliderTimer invalidate];
sliderTimer = nil;
}
/***************************************************************************************
AVPlayer 播放音视频 视频操作相关
play 播放
pause 暂停
seekToTime: 跳转进度
currentItem 当前播放的视频元素
volume 调节音量
externalPlaybackVideoGravity 视频显示的播放样式
AVLayerVideoGravityResizeAspect 普通的
AVLayerVideoGravityResizeAspectFill 充满的
currentTime 获得当前播放时间 -》CMTime
CMTimeGetSeconds(<#CMTime time#>) 通过CMTime获得当前播放时间(秒)
************************************************************************************/
/***************************************************************************************
AVPlayerItem 音视频对象 视频内容相关
duration 总时长
status 加载时的状态
AVPlayerItemStatusUnknown 未知的状态
AVPlayerItemStatusReadyToPlay 准备播放状态
AVPlayerItemStatusFailed 失败状态
时间控制的一个类目
currentTime 获得当前播放时间
forwardPlaybackEndTime跳到结束位置
reversePlaybackEndTime 调到开始位置
seekToTime: 调到指定位置
************************************************************************************/
/***********************************************************************************
AVPlayerLayer播放显示视频的图层界面
AVPlayerViewController 视图控制器 #import <AVKit/AVKit.h> 可以显示视频 并且有调节控件
***********************************************************************************/
/****
使用:
AVPlayerItem
创建方式
1. playerItemWithURL:类方法通过URl地址创建要播放的对象 可以是本地内容也可以是在线内容
2. initWithURL:构造方法
3. playerItemWithAsset:通过设备相册里面的内容 创建一个 要播放的对象
4. playerItemWithAsset:automaticallyLoadedAssetKeys自动根据要求的Key去加载相册里面的内容
5. initWithAsset:automaticallyLoadedAssetKeys:
AVPlayer
创建方式
1. playerWithURL:根据URL去创建播放器 不需使用item
2. initWithURL:
3. playerWithPlayerItem:需要传入一个视频播放内容
seekToTime:跳转到某一个进度
timeScale(帧率)
创建AVPlayerLayer 添加到父视图
[AVPlayerLayer playerLayerWithPlayer:“AVPlayer对象”];
设置frame,添加到父视图上。
["AVPlayer对象" play];播放
***/
@end