您的位置:首页 > 理论基础 > 计算机网络

AVPlayer(网络音频资源)的封装

2016-04-06 21:01 309 查看
如果不去封装的话, 当向音乐盒中放了很多资源的时候, 就会出现一系列容易崩溃的地方.下面话不多说,上代码.
我封装的是一个单例.PlayerSingle
// 1. 单列老步骤, 初始化.
// 2. 属性
(1)设置数据源musicArray, 存放所有音乐数组
(2)下坐标,音乐存放都是有序的, 想找到对应的数组indexPath才可以 选中
(3)播放类型,播放状态,写成枚举( 整型, typedef NS_ENUM(NSInterger,family) {zdf,joner}; )
(4)AVPlayer, 增长生命周期
(5)float 类型的 currentTime以及总时间
// 3.方法
(1)播放
(2)暂停
(3)停止
(4)上一曲
(5)下一曲
(6)指定下标进行播放
(7)指定位置进行播放
(8)播放后的操作.

代码如下:
#import "PlayerSingle.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import "RadioDetailModel.h"
@implementation PlayerSingle
+ (PlayerSingle *)sharePlayer {
static PlayerSingle *palyer = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
palyer = [[PlayerSingle alloc]init];
});
return palyer;
}
// 默认配置
- (instancetype)init {
if (self = [super init]) {
//
self.playType = PlayerTypeList;
self.PlayerStatus = PlayerStatusPause;
}
return self;
}

#pragma mark - 数据源
- (void)setMusicArray:(NSMutableArray *)musicArray {
// 清空以前的数据
[_musicArray removeAllObjects];
// 把传过来的数组重新赋值, 充指向
_musicArray = [musicArray mutableCopy];
// 根据下标获取对应的 url
RadioDetailModel *model = [_musicArray objectAtIndex:_indexPath];
AVPlayerItem *item = [[AVPlayerItem alloc]initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",model.musicUrl]]];
// 如果存在播放器, 进行更换 item, 如果没有进行初始化
if (_avPlayer) {
[_avPlayer replaceCurrentItemWithPlayerItem:item];// 相当于更换数据源, 进行新的 url 进行播放
} else {
_avPlayer = [[AVPlayer alloc]initWithPlayerItem:item];
}
}

// 总时长
- (float )totalTime {
// 安全判断
if (_avPlayer.currentItem.duration.timescale == 0) {
return 0;
} else {
return _avPlayer.currentItem.duration.value / _avPlayer.currentItem.duration.timescale;
}
}

// 当前时长
- (float)currentTime {
if (_avPlayer.currentTime.timescale == 0) {
return 0;
} else {
return _avPlayer.currentTime.value / _avPlayer.currentTime.timescale;
}
}

// 播放
- (void)play {
[_avPlayer play];
self.PlayerStatus = PlayerStatusPlay;
// 配置后台播放时的信息, 如:歌手名,歌曲名,背景图,专辑
[self configLockScreen];
}
- (void)configLockScreen {
NSMutableDictionary *infoDic = [NSMutableDictionary dictionary];// 这个字典包含后天所有的配置信息
// 专辑名
[infoDic setObject:@"虎哥最帅" forKey:MPMediaItemPropertyAlbumTitle];
// 歌曲名
[infoDic setObject:@"虎哥歌曲" forKey:MPMediaItemPropertyTitle];
// 歌手名
[infoDic setObject:@"虎哥" forKey: MPMediaItemPropertyArtist];
// 封面图片
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pkimg.image.alimmdn.com/upload/20160401/b8eeed43c83698f9f06b5214dc23ffc8.JPG!300300"]];
UIImage *img = [UIImage imageWithData:data];
MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc]initWithImage:img];
[infoDic setObject: artwork forKey:MPMediaItemPropertyArtwork];
// 播放时长
[infoDic setObject:[NSNumber numberWithDouble:CMTimeGetSeconds(self.avPlayer.currentItem.duration)] forKey:MPMediaItemPropertyPlaybackDuration];
// 当前播放的信息中心
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = infoDic;
}
// 暂停
- (void)pause {
[_avPlayer pause];
self.PlayerStatus = PlayerStatusPause;
}

// 停止
- (void)stop {
[self seekToTime:0];
[_avPlayer pause];

}

// 上一首
- (void)previewMusic {
if (self.playType == PlayerTypeRandom) {
// 随机模式
_indexPath = arc4random() % self.musicArray.count;
} else {
// 包含单曲循环
if (_indexPath == 0) {
_indexPath = self.musicArray.count - 1;
} else {
_indexPath --;
}
}
[self changeMusicWithIndexPath:_indexPath];
}

// 下一首
- (void)nextMusic {
if (self.playType == PlayerTypeRandom) {
_indexPath = arc4random() % self.musicArray.count;
} else {
_indexPath++;
if (_indexPath == self.musicArray.count) {
_indexPath = 0;
}
}
[self changeMusicWithIndexPath:_indexPath];
}

// 指定下坐标的位置进行播放(选取数组中的某个对象进行播放)
- (void)changeMusicWithIndexPath:(NSInteger)indexPath {
// 记住:
_indexPath = indexPath;// indexPath传过来的值
RadioDetailModel *model = [self.musicArray objectAtIndex:_indexPath];
// 更换 item 数据
AVPlayerItem *item = [[AVPlayerItem alloc]initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",model.musicUrl]]];
[_avPlayer replaceCurrentItemWithPlayerItem:item];
[self play];
}
// 播放模式 单曲, 随机 列表

// 指定位置进行播放(进度条更改后进行播放)
- (void)seekToTime:(float)time {
// 当前时间
CMTime newTime = _avPlayer.currentTime;
// 重设时间
newTime.value = newTime.timescale * time;
// 给播放器跳转到新的时间
[_avPlayer seekToTime:newTime];
}
// 播放完成后的操作
- (void)playDidFinish {
[self nextMusic];
}
@end

// 注意: (1)导入 AVFoundation, MediaPlayer, 都是系统的
(2)重写父类,一定要加上 self = [super 方法]
(3)重写数据源 musicArray的 set 方法.(清空以前数据removeAll, 传过来的数组重新赋值mutableCopy, 根据下标获取对应的 url, 创建 item, 如果存在播放器,进行更换,如果没有就初始化, 有个方法 replaceCurrentItemWithPlayerItem )
(4)总时长-  player.currentItem.duration.value / player.currentItem.duration.timeScale; 当前时长 player.currentTime.value /  player.currentTime.timeScale
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: