iOS中想播放视频,那么就要用到AVFoundation库,在头文件导入#import <AVFoundation/AVFoundation.h>
库
下面介绍一下三个要使用到的类:
//播放器
@property(nonatomic,strong) AVPlayer *myPlayer;
//播放单元(多媒体资源)
@property(nonatomic,strong) AVPlayerItem *item;
//播放界面
@property(nonatomic,strong) AVPlayerLayer *playerLayer;
我们可以看到有视频播放,其实是因为AVPlayerLayer加入到父视图的layer中,才看得到的视频播放。
通过以下代码,可以实现一个简单的视频播放:
//播放网站
NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com/1455782903700jy.mp4"];
//初始化一个播放单元
self.item = [AVPlayerItem playerItemWithURL:mediaURL];
//初始化一个对象播放器
self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];
//初始化一个播放器的Layer
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
self.playerLayer.frame = CGRectMake(0, 0, ScreenW, 300);
[self.view.layer addSublayer:self.playerLayer];
//开始播放视频
[self.myPlayer play];
想获取播放的总时长,并且实时用Lable显示播放时间,用UISlider显示播放进度,请看如下代码:
获取播放总时长:
self.mySlider.maximumValue = self.item.duration.value / self.item.duration.timescale;
播放进度CMTime类型一般是用来表示视频或者动画的时间类型,CMTime对象的Value属性是用来得到当前视频或者动画一共有多少帧,timescale是指每秒多少帧。视频总时长 = value / timescale(秒)
滑动UISlider时候,改变播放进度:
//value值为视频的时间
float seconds = self.mySlider.value;
//让视频从指定的CMTime对象处播放
CMTime startTime = CMTimeMakeWithSeconds(seconds, self.item.currentTime.timescale);
//让视屏从指定处播放
[self.myPlayer seekToTime:startTime completionHandler:^(BOOL finished) {
[self startToPlay];
}];
实时更新UISider进度:
self.mySlider.value = self.item.currentTime.value / self.item.currentTime.timescale;
self.leftLb.text = [self changeSecondsTime:self.mySlider.value];
将总时长转化成固定时间格式的方法:
//将秒数转化成00:00的格式,用于显示
-(NSString *)changeSecondsTime:(NSInteger)time
{
NSInteger min = time / 60;
NSInteger seconds = time % 60;
return [NSString stringWithFormat:@"%02ld:%02ld",(long)min,(long)seconds];
}
很多视频播放中,都会用到KVO来处理视频播放,例如视频是否加载好了,视频的缓存处理等等。这里只演示视频是否加载好。
贴上完整代码:
//
// ViewController.m
// AVPlayer
//
// Created by HZhenF on 2017/6/2.
// Copyright © 2017年 Huangzhengfeng. All rights reserved.
//
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#define ScreenW [UIScreen mainScreen].bounds.size.width
#define ScreenH [UIScreen mainScreen].bounds.size.height
@interface ViewController ()
//播放器
@property(nonatomic,strong) AVPlayer *myPlayer;
//播放单元(多媒体资源)
@property(nonatomic,strong) AVPlayerItem *item;
//播放界面
@property(nonatomic,strong) AVPlayerLayer *playerLayer;
//实现视频的播放进度
@property(nonatomic,strong) UISlider *mySlider;
//用来判断当前视频是否准备好播放
@property(nonatomic,assign) BOOL isReadToPlay;
@property(nonatomic,strong) NSTimer *timer;
@property(nonatomic,strong) UILabel *leftLb;
@property(nonatomic,strong) UILabel *rightLb;
@end
@implementation ViewController
-(UILabel *)rightLb
{
if (!_rightLb) {
_rightLb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, ScreenW*0.1, 30)];
_rightLb.center = CGPointMake(ScreenW*0.95, self.mySlider.center.y);
_rightLb.textColor = [UIColor grayColor];
_rightLb.font = [UIFont systemFontOfSize:12.0];
_rightLb.text = @"00:00";
_rightLb.textAlignment = NSTextAlignmentCenter;
}
return _rightLb;
}
-(UILabel *)leftLb
{
if (!_leftLb) {
_leftLb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, ScreenW*0.1, 30)];
_leftLb.center = CGPointMake(ScreenW*0.05, self.mySlider.center.y);
_leftLb.textColor = [UIColor grayColor];
_leftLb.font = [UIFont systemFontOfSize:12.0];
_leftLb.text = @"00:00";
_leftLb.textAlignment = NSTextAlignmentCenter;
}
return _leftLb;
}
-(NSTimer *)timer
{
if (!_timer) {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
return _timer;
}
-(UISlider *)mySlider
{
if (!_mySlider) {
_mySlider = [[UISlider alloc] initWithFrame:CGRectMake(ScreenW*0.1, CGRectGetMaxY(self.playerLayer.frame) - 30, ScreenW*0.8, 30)];
_mySlider.minimumTrackTintColor = [UIColor orangeColor];
_mySlider.maximumTrackTintColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1];
[_mySlider addTarget:self action:@selector(mySliderAction) forControlEvents:UIControlEventValueChanged];
}
return _mySlider;
}
- (void)viewDidLoad {
[super viewDidLoad];
//初始化视频
[self setupAVPlayer];
[self.view addSubview:self.mySlider];
[self addControls];
[self.view addSubview:self.leftLb];
[self.view addSubview:self.rightLb];
}
-(void)addControls
{
UIButton*button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(250,600,100,100);
button.backgroundColor= [UIColor redColor];
[button setTitle:@"播放" forState:UIControlStateNormal];
[button addTarget:self action:@selector(playAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
//实时更新UISlider和时间
-(void)updateSlider
{
self.mySlider.value = self.item.currentTime.value / self.item.currentTime.timescale;
self.leftLb.text = [self changeSecondsTime:self.mySlider.value];
}
//将秒数转化成00:00的格式,用于显示
-(NSString *)changeSecondsTime:(NSInteger)time
{
NSInteger min = time / 60;
NSInteger seconds = time % 60;
return [NSString stringWithFormat:@"%02ld:%02ld",(long)min,(long)seconds];
}
//滑动UISlider,改变播放进度
-(void)mySliderAction
{
//value值为视频的时间
float seconds = self.mySlider.value;
//让视频从指定的CMTime对象处播放
CMTime startTime = CMTimeMakeWithSeconds(seconds, self.item.currentTime.timescale);
//让视屏从指定处播放
[self.myPlayer seekToTime:startTime completionHandler:^(BOOL finished) {
[self startToPlay];
}];
}
//点击播放按钮
-(void)playAction:(UIButton *)sender
{
if (sender.isSelected) {
sender.selected = !sender.selected;
[sender setTitle:@"播放" forState:UIControlStateNormal];
[self.timer invalidate];
self.timer = nil;
self.isReadToPlay = 0;
[self startToPlay];
}
else
{
sender.selected = !sender.selected;
[sender setTitle:@"暂停" forState:UIControlStateSelected];
self.isReadToPlay = 1;
//开始播放
[self startToPlay];
[self timer];
}
}
-(void)startToPlay
{
if (self.isReadToPlay) {
//开始播放视频
[self.myPlayer play];
}
else
{
//暂停播放视频
[self.myPlayer pause];
}
}
-(void)setupAVPlayer
{
//播放网站
NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com/1455782903700jy.mp4"];
//初始化一个播放单元
self.item = [AVPlayerItem playerItemWithURL:mediaURL];
//初始化一个对象播放器
self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];
//初始化一个播放器的Layer
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
self.playerLayer.frame = CGRectMake(0, 0, ScreenW, 300);
[self.view.layer addSublayer:self.playerLayer];
//通过KVO来观察status属性的变化,来获取播放之前的错误信息
[self.item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}
//KVO的回调方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
/*
播放进度CMTime类型一般是用来表示视频或者动画的时间类型,CMTime对象的Value属性是用来得到当前视频或者动画一共有多少帧,timescale是指每秒多少帧。视频总时长 = value / timescale(秒)
*/
//取出status的新值
AVPlayerStatus status = [change[NSKeyValueChangeNewKey] intValue];
switch (status) {
case AVPlayerStatusFailed:
NSLog(@"item有误");
self.isReadToPlay = NO;
break;
case AVPlayerStatusReadyToPlay:
NSLog(@"准备好播放了");
self.isReadToPlay = YES;
self.mySlider.maximumValue = self.item.duration.value / self.item.duration.timescale;
self.rightLb.text = [self changeSecondsTime:self.mySlider.maximumValue];
break;
case AVPlayerItemStatusUnknown:
NSLog(@"视频资源出现位置错误");
self.isReadToPlay = NO;
break;
default:
break;
}
//移除监听
[object removeObserver:self forKeyPath:@"status"];
}
@end