//
|
// PBAVPlayerManager.m
|
// IphoneBIMe
|
//
|
// Created by zjf on 2019/1/3.
|
// Copyright © 2019 ProBIM. All rights reserved.
|
//
|
|
#import "PBAVPlayerManager.h"
|
|
@interface PBAVPlayerManager()<AVPlayerItemOutputPullDelegate>
|
@property (nonatomic, strong) AVPlayer *player;
|
@property (nonatomic, strong) AVPlayerItem *item;
|
@end
|
|
@implementation PBAVPlayerManager
|
+ (instancetype)sharedManager{
|
static PBAVPlayerManager *manager;
|
static dispatch_once_t onceToken;
|
dispatch_once(&onceToken, ^{
|
manager = [[PBAVPlayerManager alloc] init];
|
});
|
return manager;
|
}
|
- (instancetype)init {
|
self = [super init];
|
if (self) {
|
_player = [[AVPlayer alloc] init];
|
}
|
return self;
|
}
|
#pragma mark - 播放本地录音
|
- (void)playItemWithName:(NSString *)recodingName {
|
if (recodingName != nil) {
|
//真机必须添加此代码
|
AVAudioSession *session = [AVAudioSession sharedInstance];
|
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
|
[session setActive:YES error:nil];
|
NSURL *sourceMovieUrl = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:recodingName]];
|
AVAsset *movieAsset = [AVURLAsset URLAssetWithURL:sourceMovieUrl options:nil];
|
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:movieAsset];
|
if (self.item) {
|
[self removeObserverFromPlayerItem:self.item];
|
[_player replaceCurrentItemWithPlayerItem:playerItem];
|
}else {
|
_player = [AVPlayer playerWithPlayerItem:playerItem];
|
}
|
self.item = playerItem;
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
|
[self addObserverToPlayerItem:self.item];
|
[_player play];
|
}else {
|
[YJProgressHUD showMessage:@"没有找到此音频文件" inView:nil];
|
}
|
}
|
|
#pragma mark - 播放网络音频
|
- (void)playItemWithUrl:(NSString *)recordingUrl {
|
AVAudioSession *session = [AVAudioSession sharedInstance];
|
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
|
[session setActive:YES error:nil];
|
// NSURL *sourceMovieUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",BaseUrl,recordingUrl]];
|
NSURL *sourceMovieUrl = [NSURL URLWithString:recordingUrl];
|
AVAsset *movieAsset = [AVURLAsset URLAssetWithURL:sourceMovieUrl options:nil];
|
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:movieAsset];
|
if (self.item) {
|
[self removeObserverFromPlayerItem:self.item];
|
[_player replaceCurrentItemWithPlayerItem:playerItem];
|
} else {
|
_player = [AVPlayer playerWithPlayerItem:playerItem];
|
}
|
self.item = playerItem;
|
[_player replaceCurrentItemWithPlayerItem:playerItem];
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
|
[self addObserverToPlayerItem:self.item];
|
[_player play];
|
}
|
/**
|
* 给AVPlayerItem添加监控
|
*
|
* @param playerItem AVPlayerItem对象
|
*/
|
- (void)addObserverToPlayerItem:(AVPlayerItem *)playerItem
|
{
|
if (playerItem) {
|
[playerItem addObserver:self
|
forKeyPath:@"status"
|
options:NSKeyValueObservingOptionNew
|
context:nil];
|
//监控网络加载情况属性
|
[playerItem addObserver:self
|
forKeyPath:@"loadedTimeRanges"
|
options:NSKeyValueObservingOptionNew
|
context:nil];
|
//给AVPlayerItem添加播放完成通知
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
|
}
|
}
|
|
- (void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem
|
{
|
if (playerItem) {
|
[playerItem removeObserver:self forKeyPath:@"status"];
|
[playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
|
[[NSNotificationCenter defaultCenter]removeObserver:self
|
name:AVPlayerItemDidPlayToEndTimeNotification
|
object:playerItem];
|
}
|
}
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
|
AVPlayerItem *playerItem = object;
|
if ([keyPath isEqualToString:@"status"]) {
|
AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
|
switch (status) {
|
case AVPlayerStatusUnknown:{
|
self.status = ETPlayer_UnkonwError;
|
if ([self respondsDelegate]) {
|
[self.delegate currentPlayerStatus:ETPlayer_UnkonwError];
|
}
|
break;
|
}
|
case AVPlayerStatusReadyToPlay:{
|
self.status = ETPlayer_ReadyToPlay;
|
if ([self respondsDelegate]) {
|
[self.delegate currentPlayerStatus:ETPlayer_ReadyToPlay];
|
}
|
CMTime time = _player.currentItem.duration;
|
float value1 = time.value / time.timescale;
|
float value2 = CMTimeGetSeconds(self.player.currentItem.asset.duration);
|
NSLog(@"正在播放,_player.currentItem.duration 总长度:%.2f", value1);
|
NSLog(@"正在播放,_player.currentItem.asset.duration总长度:%.2f", value2);
|
break;
|
}
|
case AVPlayerStatusFailed: {
|
self.status = ETPlayer_PlayFailed;
|
if ([self respondsDelegate]) {
|
[self.delegate currentPlayerStatus:ETPlayer_PlayFailed];
|
}
|
[PBNoteCenter postNotificationName:PBNoteCenterPlayOver object:nil];
|
[YJProgressHUD showMessage:@"加载音频失败" inView:nil];
|
break;
|
}
|
default:
|
break;
|
}
|
}else if([keyPath isEqualToString:@"loadedTimeRanges"]) {
|
double timeInterval = [self availableDuration];
|
CMTime duration = playerItem.duration;
|
double totalDuration = CMTimeGetSeconds(duration);
|
NSLog(@"timeInterval:%f",timeInterval);
|
NSLog(@"totalDuration:%f",totalDuration);
|
if (timeInterval < 1.5 * totalDuration) {
|
self.status = ETPlayer_Loading;
|
if ([self respondsDelegate]) { [self.delegate currentPlayerStatus:ETPlayer_Loading]; }
|
}else if ([self isPlaying]) {
|
self.status = ETPlayer_Playing;
|
if ([self respondsDelegate]) { [self.delegate currentPlayerStatus:ETPlayer_Playing]; }
|
} else {
|
self.status = ETPlayer_Loading;
|
if ([self respondsDelegate]) { [self.delegate currentPlayerStatus:ETPlayer_Loading]; }
|
}
|
}
|
}
|
- (BOOL)respondsDelegate {
|
if (self.delegate && [self.delegate respondsToSelector:@selector(currentPlayerStatus:)]) {
|
return YES;
|
}
|
return NO;
|
}
|
- (BOOL)isPlaying
|
{
|
// 可以根据值去判断播放还是暂停
|
if (_player.rate == 0.0) {
|
return NO;
|
}
|
return YES;
|
}
|
- (double)availableDuration{
|
NSArray *loadedTimeRanges = self.player.currentItem.loadedTimeRanges;
|
NSValue *value = loadedTimeRanges.firstObject;
|
CMTimeRange timeRange = value.CMTimeRangeValue;
|
double startSeconds = CMTimeGetSeconds(timeRange.duration);
|
double durationSeconds = CMTimeGetSeconds(timeRange.duration);
|
return startSeconds + durationSeconds;
|
}
|
- (void)playbackFinished:(NSNotification *)noti {
|
[PBNoteCenter postNotificationName:PBNoteCenterPlayOver object:nil];
|
}
|
|
- (void)stopPlay {
|
[_player pause];
|
}
|
|
|
|
|
|
|
@end
|