iOS AVPlayer播放mp3

**注释: [self.player play];一定要写在- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> )change context:(void )context 监听方法中,不然音频没有加载完成是无法播放的

//
//  TFPlayMusicManager.m
//  iOS-TutorTeacher
//
//  Created by kent J on 2017/6/28.
//  Copyright © 2017年 aizhikang. All rights reserved.
//

#import "TFPlayMusicManager.h"
static TFPlayMusicManager *playerManager = nil;

@implementation TFPlayMusicManager
#pragma mark - Private
+(TFPlayMusicManager *)defaultManager{
    
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    
    
        playerManager = [[self alloc] init];
    });
    
    return playerManager;
}
// 当前是否正在录音
+(BOOL)isPlaying{
    
    
    return [[TFPlayMusicManager defaultManager] isPlaying];
}
-(BOOL)isPlaying{
    
    
    return !!_player;
}
// 播放
+ (void)asyncPlayMusicWithPreparePath:(NSString *)musicUrl
                           completion:(void(^)(NSError *error))completion{
    
    
    [TFPlayMusicManager asyncPlayMusicWithPreparePath:musicUrl completion:completion];
}
// 停止播放
+(void)asyncStopMusicWithCompletion:(void(^)(NSString *recordPath))completion{
    
    
    [TFPlayMusicManager asyncStopMusicWithCompletion:completion];
}
// 取消录音
+(void)cancelCurrentRecording{
    
    
    [[TFPlayMusicManager defaultManager] cancelCurrentRecording];
}
// 取消录音
- (void)cancelCurrentRecording
{
    
    
    
}
+(AVPlayer *)recorder{
    
    
    return [TFPlayMusicManager defaultManager].player;
}
// 开始播放,文件放到musicUrl下
- (void)asyncPlayMusicWithPreparePath:(NSString *)musicUrl
                           completion:(void(^)(NSError *error))completion
{
    
    
    __weak TFPlayMusicManager *weakSelf = self;
    NSURL * url  = [NSURL URLWithString:musicUrl];
    self.playItem = [[AVPlayerItem alloc]initWithURL:url];
    self.player = [[AVPlayer alloc]initWithPlayerItem:self.playItem];
    self.playItem = self.player.currentItem;
    self.player.automaticallyWaitsToMinimizeStalling = NO;
    [self.playItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [self.playItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

    //添加播放进度观察者
    self.timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
    
    
        float current = CMTimeGetSeconds(time);
        float total = CMTimeGetSeconds(weakSelf.playItem.duration);
        if (current) {
    
    
            weakSelf.progress = current / total;
            weakSelf.playTime = [NSString stringWithFormat:@"%.f",current];
            weakSelf.playDuration = [NSString stringWithFormat:@"%.2f",total];
        }
        DebugLog(@"progress = %f playTime = %@ playDuration = %@",weakSelf.progress,weakSelf.playTime,weakSelf.playDuration);
    }];
    //    completion(completion);
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
    
    /*
     AVPlayerTimeControlStatusPaused,
     AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate,
     AVPlayerTimeControlStatusPlaying
     */
    if ([keyPath isEqualToString:@"status"]) {
    
    
        switch (self.player.status) {
    
    
            case AVPlayerStatusUnknown:
                DebugLog(@"KVO:未知状态,此时不能播放");
                break;
            case AVPlayerStatusReadyToPlay:
                //                self.status = AVPlayerStatusReadyToPlay;
            {
    
    
                if (self.player.timeControlStatus == AVPlayerTimeControlStatusPlaying) {
    
    
                    
                }
                DebugLog(@"KVO:准备完毕,可以播放   %ld++++++%@",(long)self.player.timeControlStatus,self.player.reasonForWaitingToPlay);
               
                [self.player play];

            }

                break;
            case AVPlayerStatusFailed:
                DebugLog(@"KVO:加载失败,网络或者服务器出现问题");
                break;
            default:
                break;
        }
    }
    
    if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
    
    
        NSArray * array = self.playItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue]; //本次缓冲的时间范围
        NSTimeInterval totalBuffer = CMTimeGetSeconds(timeRange.start) + CMTimeGetSeconds(timeRange.duration); //缓冲总长度
        DebugLog(@"共缓冲%.2f",totalBuffer);
    }
    
}
//移除观察者
-(void)removeObserver{
    
    
    //    [self.playItem removeObserver:self forKeyPath:@"status"];
    if (_timeObserve) {
    
    
        [_player removeTimeObserver:_timeObserve];
        _timeObserve = nil;
    }
}
// 停止录音
-(void)asyncStopMusicWithCompletion:(void(^)(NSString *recordPath))completion{
    
    
    playFinish = completion;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
    
        [self->_player pause];
    });
}
#pragma mark - getter
- (NSDictionary *)recordSetting
{
    
    
    if (!_musicSetting) {
    
    
        _musicSetting = [[NSDictionary alloc] initWithObjectsAndKeys:
                         [NSNumber numberWithFloat: 11025.0],AVSampleRateKey, //采样率
                         [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
                         [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数 默认 16
                         [NSNumber numberWithInt: 2], AVNumberOfChannelsKey,//通道的数目
                         AVAudioQualityMin, AVEncoderAudioQualityKey,//通道的数目
                         
                         nil];
    }
    
    return _musicSetting;
}
-(instancetype)init{
    
    
    if (self = [super init]) {
    
    
        
    }
    
    return self;
}

-(void)dealloc{
    
    
    DebugLog(@"内存释放");

}
@end

**注释: [self.player play];一定要写在- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> )change context:(void )context 监听方法中,不然音频没有加载完成是无法播放的

猜你喜欢

转载自blog.csdn.net/u011374880/article/details/107344936