AVPlayer介绍
AVPlayer属于AVFoundation框架,它的强大之处在于,不仅能够播放音频,还可以播放视频,支持本地和网链,而且使用起来非常方便.
AVPlayer之音频
使用AVPlayer播放音频必须知道的三个类
1.1 AVPlayer : 可以理解成播放器
1.2 AVPlayerItem : 播放器需要播放的资源,比如一首歌曲
1.3 CMTime : 记录AVPlayerItem资源的播放进度以及这个资源的其他信息,当你需要显示播放进度的时候可以用到它,它本身是个结构体音频播放示例
2.1 说明 : 此处只介绍一下简单的使用过程
2.2 代码 :
AVPlayerManager.h
#import <Foundation/Foundation.h>
@interfaceAVPlayerManager : NSObject
+ (instancetype)shareManager;
- (void)musicPlayerWithURL:(NSURL *)playerItemURL;
- (void)pause;
@end
AVPlayerManager.m
#import "AVPlayerManager.h"
#import <AVFoundation/AVFoundation.h>
@interface AVAudioManager(){
BOOL isPlaying;//是否正在播放
BOOL isPrepare;//资源是否准备完毕
}
@property (nonatomic, strong) AVPlayer *player;//播放器
@end
@implementation AVAudioManager
//单例
+ (instancetype)shareManager{
static AVPlayerManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [AVPlayerManager new];
});
return manager;
}
//播放音频的方法(下面会在控制器调用)
- (void)musicPlayerWithURL:(NSURL *)playerItemURL{
//创建要播放的资源
AVPlayerItem *playerItem = [[AVPlayerItem alloc]initWithURL:playerItemURL];
//添加观察者
//当资源的status发生改变时就会触发观察者事件
[playerItem addObserver:self forKeyPath:@"status" options:(NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew) context:nil];
//播放当前资源
[self.player replaceCurrentItemWithPlayerItem:playerItem];
}
//播放
- (void)play{
if (!isPrepare) {
return;
}
[self.player play];
isPlaying = YES;
}
//暂停
- (void)pause{
if (!isPlaying) {
return;
}
[self.player pause];
isPlaying = NO;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
AVPlayerItemStatus status = [change[@"new"] integerValue];
switch (status) {
case AVPlayerItemStatusReadyToPlay:
isPrepare = YES;
[self play];
break;
case AVPlayerItemStatusFailed:
NSLog(@"加载失败");
break;
case AVPlayerItemStatusUnknown:
NSLog(@"未知资源");
break;
default:
break;
}
}
//播放器懒加载
-(AVPlayer *)player{
if (!_player) {
_player = [AVPlayer new];
}
return _player;
}
@end
#import "ViewController.h"
#import "AVPlayerManager.h"
@interface ViewController ()
@end
ViewController.m中调用单例里的方法
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AVPlayerManager *manger = [AVPlayerManager shareManager];
NSString *Path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp3"];//我在本地有一个1.mp3的歌曲,当然也可以直接链接网上的URL
NSURL *Url = [NSURL fileURLWithPath:Path];
[manger musicPlayerWithURL:Url];//根据url播放
}
@end
AVPlayer之视频
使用AVPlayer播放视频必须知道的三个类
1.1 AVPlayer : 同样理解成播放器
1.2 AVPlayerItem : 同样是播放器需要播放的资源,比如一首歌曲
1.3 AVPlayerLayer : 要显示视频我们就要把AVPlayerLayer对象加到要显示的视图的layer层上,因此我们只要能拿到AVPlayer的layer,然后把拿到的layer 赋值给 AVPlayerLayer对象即可视频播放示例
2.1 说明 : 此处只介绍一下简单的使用过程
2.2 代码 :
//创建一个item
AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:@"xxxxx.mp4"]];//以前用的链接丢了,自己找个添上吧
//初始化播放器
self.player = [[AVPlayer alloc] initWithPlayerItem:item];
//获取播放器的layer
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
//设置播放器的layer
playerLayer.frame = self.view.frame;
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
playerLayer.backgroundColor = [[UIColor blueColor] CGColor];
//讲layer添加到当期页面的layer层中
[self.view.layer addSublayer:playerLayer];
//播发器开始播放
[self.player play];
容易出现的问题:AVPlayer不释放网络导致memory占用越来越大
- 问题:当在项目中使用AVPlayer,可以正常播放的时候,此时你退出了播放器,即使播放器被置空,观察者也已经移除,但是在Xcode中会发现播放器依然在缓存资源,导致memory占用越来越高.
- 解决方法(亲测:可以解决)
2.1 在播放器走dealloc方法之前,重新把当前资源替换为nil
[self.player replaceCurrentItemWithPlayerItem:nil];
2.2 然后播放器会走到下面的方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
此时播放器资源就不会是AVPlayerItemStatusReadyToPlay
状态,就不会再继续缓冲了
2.3 最后在dealloc方法里面把通知中心之类的移除就好了(其实到上面一步已经解决问题了)