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

如果不去封装的话, 当向音乐盒中放了很多资源的时候, 就会出现一系列容易崩溃的地方.下面话不多说,上代码.
  我封装的是一个单例.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

版权声明:本文为qq_32780047原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。