AVPlayer介紹
AVPlayer屬于AVFoundation框架,它的強(qiáng)大之處在于,不僅能夠播放音頻,還可以播放視頻,支持本地和網(wǎng)鏈,而且使用起來(lái)非常方便.
AVPlayer之音頻
使用AVPlayer播放音頻必須知道的三個(gè)類
1.1 AVPlayer : 可以理解成播放器
1.2 AVPlayerItem : 播放器需要播放的資源,比如一首歌曲
1.3 CMTime : 記錄AVPlayerItem資源的播放進(jìn)度以及這個(gè)資源的其他信息,當(dāng)你需要顯示播放進(jìn)度的時(shí)候可以用到它,它本身是個(gè)結(jié)構(gòu)體音頻播放示例
2.1 說(shuō)明 : 此處只介紹一下簡(jiǎn)單的使用過(guò)程
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;//資源是否準(zhǔn)備完畢
}
@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;
}
//播放音頻的方法(下面會(huì)在控制器調(diào)用)
- (void)musicPlayerWithURL:(NSURL *)playerItemURL{
//創(chuàng)建要播放的資源
AVPlayerItem *playerItem = [[AVPlayerItem alloc]initWithURL:playerItemURL];
//添加觀察者
//當(dāng)資源的status發(fā)生改變時(shí)就會(huì)觸發(fā)觀察者事件
[playerItem addObserver:self forKeyPath:@"status" options:(NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew) context:nil];
//播放當(dāng)前資源
[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中調(diào)用單例里的方法
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AVPlayerManager *manger = [AVPlayerManager shareManager];
NSString *Path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp3"];//我在本地有一個(gè)1.mp3的歌曲,當(dāng)然也可以直接鏈接網(wǎng)上的URL
NSURL *Url = [NSURL fileURLWithPath:Path];
[manger musicPlayerWithURL:Url];//根據(jù)url播放
}
@end
AVPlayer之視頻
使用AVPlayer播放視頻必須知道的三個(gè)類
1.1 AVPlayer : 同樣理解成播放器
1.2 AVPlayerItem : 同樣是播放器需要播放的資源,比如一首歌曲
1.3 AVPlayerLayer : 要顯示視頻我們就要把AVPlayerLayer對(duì)象加到要顯示的視圖的layer層上,因此我們只要能拿到AVPlayer的layer,然后把拿到的layer 賦值給 AVPlayerLayer對(duì)象即可視頻播放示例
2.1 說(shuō)明 : 此處只介紹一下簡(jiǎn)單的使用過(guò)程
2.2 代碼 :
//創(chuàng)建一個(gè)item
AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:@"xxxxx.mp4"]];//以前用的鏈接丟了,自己找個(gè)添上吧
//初始化播放器
self.player = [[AVPlayer alloc] initWithPlayerItem:item];
//獲取播放器的layer
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
//設(shè)置播放器的layer
playerLayer.frame = self.view.frame;
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
playerLayer.backgroundColor = [[UIColor blueColor] CGColor];
//講layer添加到當(dāng)期頁(yè)面的layer層中
[self.view.layer addSublayer:playerLayer];
//播發(fā)器開(kāi)始播放
[self.player play];
容易出現(xiàn)的問(wèn)題:AVPlayer不釋放網(wǎng)絡(luò)導(dǎo)致memory占用越來(lái)越大
- 問(wèn)題:當(dāng)在項(xiàng)目中使用AVPlayer,可以正常播放的時(shí)候,此時(shí)你退出了播放器,即使播放器被置空,觀察者也已經(jīng)移除,但是在Xcode中會(huì)發(fā)現(xiàn)播放器依然在緩存資源,導(dǎo)致memory占用越來(lái)越高.
- 解決方法(親測(cè):可以解決)
2.1 在播放器走dealloc方法之前,重新把當(dāng)前資源替換為nil
[self.player replaceCurrentItemWithPlayerItem:nil];
2.2 然后播放器會(huì)走到下面的方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
此時(shí)播放器資源就不會(huì)是AVPlayerItemStatusReadyToPlay
狀態(tài),就不會(huì)再繼續(xù)緩沖了
2.3 最后在dealloc方法里面把通知中心之類的移除就好了(其實(shí)到上面一步已經(jīng)解決問(wèn)題了)