在PlayMusicViewController对应的.h文件中
#import<UIKit/UIKit.h>
@interface PlayMusicViewController : UIViewController
@property (nonatomic, strong)NSMutableArray *dataSource; //存储所有的音频数据
@property (nonatomic)NSInteger index; //存储当前需要播放的音频数据的下标
//声明一个方法创建音乐播放器界面对象
+ (PlayMusicViewController *)shareWithPlayMusicViewController;
//定义方法完成音频数据的播放
- (void)playMusic;
@end
在PlayMusicViewController对应的.m文件中代码如下:
#import "PlayMusicViewController.h"
#import
#import "JokeModel.h"
@interface PlayMusicViewController ()
@property (strong, nonatomic) IBOutlet UIImageView *backgroundImage; //背景图片
@property (strong, nonatomic) IBOutlet UILabel *titleLabel; //标题
@property (strong, nonatomic) IBOutlet UIImageView *needle; //播放杆
@property (strong, nonatomic) IBOutlet UISlider *progress;
@property (strong, nonatomic) IBOutlet UIButton *playBtn;
@property (nonatomic)BOOL orBegin; //记录当前播放杆是否处于起始位置
@property (nonatomic, strong)NSTimer *timer; //存储时间计时器对象
@property (nonatomic, strong)AVPlayer *player; //存储播放器对象
@property (nonatomic, strong)AVPlayerItem *playerItem; //存储音频信息
@end
@implementation PlayMusicViewController
+ (PlayMusicViewController *)shareWithPlayMusicViewController {
static PlayMusicViewController *playV = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
playV = [[PlayMusicViewController alloc]initWithNibName:@"PlayMusicViewController" bundle:nil];
});
return playV;
}
//懒加载常见音频播放器对象
- (AVPlayer *)player {
if (_player == nil) {
self.player = [AVPlayer playerWithPlayerItem:nil];
}
return _player;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//为背景图片添加高斯模糊效果
UIVisualEffectView *effectView = [[UIVisualEffectView alloc]initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
effectView.frame = self.backgroundImage.frame;
[self.backgroundImage addSubview:effectView];
//修改标签的边角
self.titleLabel.layer.masksToBounds = YES;
self.titleLabel.layer.cornerRadius = self.titleLabel.frame.size.width / 2;
JokeModel *joke = self.dataSource[self.index];
self.titleLabel.text = joke.title;
//修改播放杆的锚点坐标
self.needle.layer.anchorPoint = CGPointMake(0.28, 0.18);
self.orBegin = YES;
}
#pragma mark PlayMusic
//播放音乐
- (void)playMusic {
//1:获取对应的音频数据
JokeModel *joke = self.dataSource[self.index];
self.titleLabel.text = joke.title;
//2:创建AVPlayerItem对象
AVPlayerItem *playItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:joke.audio_64_url]];
//3:替换播放器之前的Item
[self.player replaceCurrentItemWithPlayerItem:playItem];
//4:开始播放
[self.player play];
//5:监听播放进度
[self addObserverForProgress];
//6:监听播放器的状态
[self addObserverForState];
}
//监听播放进度
- (void)addObserverForProgress {
//获取当前播放器的音频信息
AVPlayerItem *playItem = self.player.currentItem;
//开始监听播放器播放进度的变化
__weak PlayMusicViewController *playV = self;
[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 10.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
//获取当前播放的进度
float currentTime = CMTimeGetSeconds(time);
//获取音频文件的总时间
float totleTime = CMTimeGetSeconds(playItem.duration);
//设置进度条的总大小
playV.progress.maximumValue = totleTime;
//改变进度条的进度
[playV.progress setValue:currentTime animated:YES];
}];
}
//KVO监听当前播放器的播放状态
- (void)addObserverForState {
//添加监听者
[self.player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//获取当前的状态
AVPlayerStatus statu = [change[@"new"] intValue];
NSLog(@"%ld", (long)statu);
//如果状态是准备播放执行相应的操作
if (statu == AVPlayerStatusReadyToPlay) {
[self.playBtn setImage:[UIImage imageNamed:@"playing_btn_pause_n"] forState:UIControlStateNormal];
//旋转播放杆
[self handleNeedleRoation:NO];
[self.timer invalidate];
//创建计时器旋转标题
self.timer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(handleTitleLabelRotation) userInfo:nil repeats:YES];
}
}
//添加播放完成的监听事件
-(void)addNotification{
//给AVPlayerItem添加播放完成通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startPlayNextMusic) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
//移除观察者
-(void)removeNotification{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark Btn Click
//上一首
- (IBAction)previousMusic:(id)sender {
if (self.index > 0) {
self.index--;
}else {
self.index = self.dataSource.count - 1;
}
[self stop];
[self playMusic];
}
//下一首
- (IBAction)nextMusic:(id)sender {
[self startPlayNextMusic];
}
//执行播放下一首操作
- (void)startPlayNextMusic {
if (self.index < self.dataSource.count - 1) {
self.index++;
}else {
self.index = 0;
}
[self stop];
[self playMusic];
}
//播放按钮
- (IBAction)playMusic:(id)sender {
//1:判断播放器的状态
//播放状态
if (self.player.rate == 1) {
[self stop];
}else {
[self playing];
}
}
//定义方法将播放界面的控件恢复为未播放的状态
- (void)stop {
[self.player pause]; //暂停播放
[self.playBtn setImage:[UIImage imageNamed:@"playing_btn_play_n"] forState:UIControlStateNormal];//修改按钮显示的图片
[self.timer invalidate]; //暂停计时器
[self handleNeedleRoation:YES];
}
//定义方法将播放界面设置为播放状态
- (void)playing {
[self.player play]; //启动播放器
[self.playBtn setImage:[UIImage imageNamed:@"playing_btn_pause_n"] forState:UIControlStateNormal];
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(handleTitleLabelRotation) userInfo:nil repeats:YES];
[self handleNeedleRoation:NO];
}
#pragma mark Roation
- (void)handleTitleLabelRotation {
self.titleLabel.transform = CGAffineTransformRotate(self.titleLabel.transform, M_PI / 50);
}
//定义方法实现播放杆的旋转
- (void)handleNeedleRoation:(BOOL)orPause {
//播放状态
__weak PlayMusicViewController *playV = self;
if (orPause == NO && self.orBegin == YES) {
[UIView animateWithDuration:.5 animations:^{
playV.needle.transform = CGAffineTransformRotate(playV.needle.transform, M_PI / 6);
}];
self.orBegin = NO;
}else if(orPause == YES && self.orBegin == NO) {
//暂停状态
[UIView animateWithDuration:.5 animations:^{
playV.needle.transform = CGAffineTransformRotate(playV.needle.transform, -M_PI / 6);
}];
self.orBegin = YES;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark Change Progress
- (IBAction)changeProgress:(UISlider *)sender {
//改变播放器的进度
[self.player seekToTime:CMTimeMake(sender.value, 1.0)];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
效果图:
参考代码下载链接:http://pan.baidu.com/s/1pJUSzKR
如果问题,请加QQ850270358,备注写解决问题,和我单独沟通哦。
网友评论