AVPlayer 播放 使用 封装

由于本人学识尚浅如有不对请大神加以指正。


AVPlayer 播放 使用 封装_第1张图片

本文主要讲解AVPlayer的基本使用和简单封装,主要使用AVPlayer做音乐播放。

AVPlayer在使用之前应了解:

AVPlayer 的rate属性 这个属性表示AVPlayer的播放状态 0暂停 1播放

AVPlayerItem 媒体资源管理对象,每个AVPlayerItem对应一个视频或音频资源

AVPlayerItemStatus 视频音频播放状态

typedef NS_ENUM(NSInteger, AVPlayerItemStatus) {

AVPlayerItemStatusUnknown,未知资源

AVPlayerItemStatusReadyToPlay,准备播放

AVPlayerItemStatusFailed 加载失败

};

AVPlayerItem 的播放完成通知

AVPlayerItemDidPlayToEndTimeNotification

AVPlayer 监控播放时间的方法 用于更新进度条

- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(nullable dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;

AVPlayer 设置播放时间

- (void)seekToTime:(CMTime)time completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);



播放音乐

//播放网络音乐

AVPlayerItem *playerItem;

NSURL *url=[NSURL URLWithString:"音乐链接字符串"];

playerItem=[[AVPlayerItem alloc]initWithURL:url];

//播放项目中的音乐

NSString *audioPath = [[NSBundle mainBundle] pathForResource:@"音乐名" ofType:@"格式"];

NSURl *audioUrl = [NSURL fileURLWithPath:audioPath];

playerItem=[[AVPlayerItem alloc]initWithURL:audioUrl];

//播放下载在document中的音乐

NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *fullPath=[documentsDirectory stringByAppendingPathComponent:fileName];

NSURL *musicUrl=[NSURL fileURLWithPath:fullPath];

playerItem=[[AVPlayerItem alloc]initWithURL:url];

以上就是音乐的播放了


现在讲解对AVPlayer的简单封装

MusicManger.h

首先引入AVFoundation框架

#import

自己的音乐实体类

#import "Music.h"

设置代理协议

@protocol MusicMangerDelegate

@optional

-(void)updateProgressByCurrentTime:(float)currentPlayTime totalTime:(float)totalTime timeStr:(NSString *)str;

-(void)updateBufferProgress:(NSTimeInterval)progress;

-(void)updateCurrentMusic:(Music *)aMusic;

@end

设置功能函数

@interface MusicManager : NSObject

@property (weak,nonatomic) iddelegate;

+(instancetype)defaultManager;

-(void)playMusic:(Music *)aMusic musicArray:(NSArray *)array index:(NSInteger)index;

-(void)playerProgressChanged:(float)currentProgress;

-(BOOL)play;

-(void)pause;

-(void)playNext;

-(void)playPrevious;

@end


MusicManger.m

#import "MusicManager.h"

@interface MusicManager ()

@property (strong,nonatomic) AVPlayer *player;

@property (strong,nonatomic) NSTimer *timer;

@property (strong,nonatomic) Music *aMusic;

@property (strong,nonatomic) NSArray *musicArray;

@property (assign,nonatomic) NSInteger index;

@end

@implementation MusicManager

//AVPlayer懒加载

-(AVPlayer *)player

{

if(_player==nil)

{

_player=[[AVPlayer alloc]init];

[_player addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

}

return _player;

}

//程序的入口

-(void)playMusic:(Music *)aMusic musicArray:(NSArray *)array index:(NSInteger)index

{

if (aMusic&&array!=nil&&index>=0) {

self.musicArray=array;

self.index=index;

[self addObserver:self forKeyPath:@"aMusic" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

[self playCurrentMusic:aMusic];

}else

{

NSLog(@"未传入aMusic或musicList或index");

return;

}

}

//播放当前音乐

-(void)playCurrentMusic:(Music *)aMusic

{

static Music *theMusic;

if (theMusic==aMusic) {

return;

}else{

AVPlayerItem *playerItem;

NSString *urlStr=[NSString stringWithFormat:@"%@",aMusic.musicLink];

NSString *encodingStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSURL *url=[NSURL URLWithString:encodingStr];

playerItem=[[AVPlayerItem alloc]initWithURL:url];

//播放前移除playerItem的系列观察者

[self currentItemRemoveObserver];

[self.player replaceCurrentItemWithPlayerItem:playerItem];

//为playerItem添加观察者

[self currentItemAddObserver];

theMusic=aMusic;

}

-(void)currentItemAddObserver

{

//监控AVPlayer的status属性获得播放状态

[self.player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

//监控缓冲加载情况属性获取缓冲情况

[self.player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

//AVPlayerTimeControlStatus

//监控播放完成通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];

//监控当前播放时间

__weak typeof (self) WeakSelf=self;

_timer=[_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 5) queue:dispatch_get_main_queue() usingBlock:^(CMTime time)

{

float currentTime = WeakSelf.player.currentItem.currentTime.value/WeakSelf.player.currentItem.currentTime.timescale;

float duration=CMTimeGetSeconds(WeakSelf.player.currentItem.duration);

NSString *timeStr=[WeakSelf timeStringFromSecond:currentTime];

if (self.delegate&&[self.delegate respondsToSelector:@selector(updateProgressByCurrentTime:totalTime:timeStr:)])

{

//将获得的音乐信息通过代理传出去

[WeakSelf.delegate updateProgressByCurrentTime:currentTime totalTime:duration timeStr:timeStr];

}

}];

}


//播放完成自动播放下一曲

-(void)playNext

{

if (self.index==self.musicArray.count-1) {

self.index=0;

}else

{

self.index++;

}

self.aMusic=self.musicArray[self.index];

[self playCurrentMusic:self.aMusic];

}


//移除playItem的观察者

-(void)currentItemRemoveObserver

{

[self.player.currentItem removeObserver:self forKeyPath:@"status"];

[self.player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];

[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];

[self.player removeTimeObserver:_timer];

}


//播放音乐

-(BOOL)play

{

if (self.player.status==AVPlayerStatusReadyToPlay) {

[self.player play];

return YES;

}

return NO;

}

//暂停播放

-(void)pause

{

[self.player pause];

}

//播放下一曲

-(void)playNext

{

if (self.index==self.musicArray.count-1) {

self.index=0;

}else

{

self.index++;

}

self.aMusic=self.musicArray[self.index];

[self playCurrentMusic:self.aMusic];

}

//播放上一曲

-(void)playPrevious

{

if (self.index==0) {

self.index=self.musicArray.count-1;

}else

{

self.index--;

}

self.aMusic=self.musicArray[self.index];

[self playCurrentMusic:self.aMusic];

}


这里KVO的实现和代理的实现


//KVO观察属性变化

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void *)context

{

AVPlayerItem *playerItem=object;

//播放状态

if ([keyPath isEqualToString:@"status"]) {

AVPlayerItemStatus status=[change[@"new"]integerValue];

switch (status) {

//资源加载成功

case AVPlayerItemStatusReadyToPlay:

{

[self.player play];

}

break;

case AVPlayerItemStatusFailed:

{

NSLog(@"加载失败,播放出错");

}

break;

case AVPlayerItemStatusUnknown:

{

NSLog(@"未知资源播放错误");

}

break;

default:

break;

}

}


//缓冲时间

else if([keyPath isEqualToString:@"loadedTimeRanges"])

{

NSArray *bufferArray=playerItem.loadedTimeRanges

;

CMTimeRange timeRange=[bufferArray.firstObject CMTimeRangeValue];

float startSeconds=CMTimeGetSeconds(timeRange.start);

float durationSeconds=CMTimeGetSeconds(timeRange.duration);

NSTimeInterval totalBuffer=startSeconds+durationSeconds;

NSLog(@"共缓冲:%.2f",totalBuffer);

if(self.delegate&&[self.delegate respondsToSelector:@selector(updateBufferProgress:)])

{

//将缓冲时间通过代理传出去

[self.delegate updateBufferProgress:totalBuffer];

}

}

//音乐对象的变化

else if ([keyPath isEqualToString:@"aMusic"])

{

Music *currentMusic=change[@"new"];

[[NSNotificationCenter defaultCenter]postNotificationName:@"currentMusic" object:currentMusic];

if (self.delegate&&[self.delegate respondsToSelector:@selector(updateCurrentMusic:)]) {

[self.delegate updateCurrentMusic:currentMusic];

}

}

//当前音乐的播放状态

else if ([keyPath isEqualToString:@"rate"])

{

NSString *rate=change[@"new"];

NSLog(@"%@",rate);

//利用通知中心将当前播放状态传出去

[[NSNotificationCenter defaultCenter]postNotificationName:@"isPlaying" object:rate];

}

}


最后感谢大家能看到最后

demo的话以后会上传

你可能感兴趣的:(AVPlayer 播放 使用 封装)