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方法里面把通知中心之類的移除就好了(其實到上面一步已經解決問題了)