iOS开发拓展篇—音频处理(音乐播放器4)

iOS开发拓展篇—音频处理(音乐播放器4)

说明:该文主要介绍音乐播放器实现过程中的一些细节控制。

实现的效果:

  iOS开发拓展篇—音频处理(音乐播放器4)

一、完整的代码

YYPlayingViewController.m文件

  1 //

  2 //  YYPlayingViewController.m

  3 //  20-音频处理(音乐播放器1)

  4 //

  5 //  Created by apple on 14-8-13.

  6 //  Copyright (c) 2014年 yangyong. All rights reserved.

  7 //

  8 

  9 #import "YYPlayingViewController.h"

 10 #import "YYMusicTool.h"

 11 #import "YYMusicModel.h"

 12 #import "YYAudioTool.h"

 13 

 14 @interface YYPlayingViewController ()

 15 //进度条

 16 @property (weak, nonatomic) IBOutlet UIView *progressView;

 17 //滑块

 18 @property (weak, nonatomic) IBOutlet UIButton *slider;

 19 @property (weak, nonatomic) IBOutlet UIImageView *iconView;

 20 @property (weak, nonatomic) IBOutlet UILabel *songLabel;

 21 @property (weak, nonatomic) IBOutlet UILabel *singerLabel;

 22 //当前播放的音乐的时长

 23 @property (weak, nonatomic) IBOutlet UILabel *durationLabel;

 24 //正在播放的音乐

 25 @property(nonatomic,strong)YYMusicModel *playingMusic;

 26 //音乐播放器对象

 27 @property(nonatomic,strong)AVAudioPlayer *player;  28 //定时器

 29 @property(nonatomic,strong)NSTimer *CurrentTimeTimer;  30 - (IBAction)exit;

 31 - (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender;  32 - (IBAction)panSlider:(UIPanGestureRecognizer *)sender;  33 

 34 @end

 35 

 36 @implementation YYPlayingViewController

 37 #pragma mark-公共方法

 38 -(void)show

 39 {

 40     //1.禁用整个app的点击事件

 41     UIWindow *window=[UIApplication sharedApplication].keyWindow;

 42     window.userInteractionEnabled=NO;

 43     

 44     //2.添加播放界面

 45     //设置View的大小为覆盖整个窗口

 46     self.view.frame=window.bounds;

 47     //设置view显示

 48     self.view.hidden=NO;

 49     //把View添加到窗口上

 50     [window addSubview:self.view];

 51     

 52     //3.检测是否换了歌曲

 53     if (self.playingMusic!=[YYMusicTool playingMusic]) {

 54         [self RresetPlayingMusic];

 55     }

 56     

 57     //4.使用动画让View显示

 58     self.view.y=self.view.height;

 59     [UIView animateWithDuration:0.25 animations:^{

 60         self.view.y=0;

 61     } completion:^(BOOL finished) {

 62         

 63         //设置音乐数据

 64         [self starPlayingMusic];

 65         window.userInteractionEnabled=YES;

 66     }];

 67 }

 68 

 69 

 70 #pragma mark-私有方法

 71 //重置正在播放的音乐

 72 -(void)RresetPlayingMusic

 73 {

 74     //1.重置界面数据

 75     self.iconView.image=[UIImage imageNamed:@"play_cover_pic_bg"];

 76     self.songLabel.text=nil;

 77     self.singerLabel.text=nil;

 78     

 79     //2.停止播放

 80     [YYAudioTool stopMusic:self.playingMusic.filename];

 81     //把播放器进行清空

 82     self.player=nil;  83     

 84     //3.停止定时器

 85     [self removeCurrentTime];

 86 }

 87 //开始播放音乐数据

 88 -(void)starPlayingMusic

 89 {

 90     //1.设置界面数据

 91     

 92     //如果当前播放的音乐就是传入的音乐,那么就直接返回

 93     if (self.playingMusic==[YYMusicTool playingMusic])

 94     {

 95         //把定时器加进去

 96         [self addCurrentTimeTimer];

 97         return;

 98     }

 99     //存取音乐

100     self.playingMusic=[YYMusicTool playingMusic];

101     self.iconView.image=[UIImage imageNamed:self.playingMusic.icon];

102     self.songLabel.text=self.playingMusic.name;

103     self.singerLabel.text=self.playingMusic.singer;

104     

105     //2.开始播放

106     self.player = [YYAudioTool playMusic:self.playingMusic.filename]; 107     

108     //3.设置时长

109     //self.player.duration;  播放器正在播放的音乐文件的时间长度

110     self.durationLabel.text=[self strWithTime:self.player.duration];

111     

112     //4.添加定时器

113     [self addCurrentTimeTimer];

114     

115 }

116 

117 /**

118  *把时间长度-->时间字符串 119  */

120 -(NSString *)strWithTime:(NSTimeInterval)time 121 { 122     int minute=time / 60; 123     int second=(int)time % 60; 124     return [NSString stringWithFormat:@"%d:%d",minute,second]; 125 } 126 

127 #pragma mark-定时器控制

128 /**

129  *  添加一个定时器 130  */

131 -(void)addCurrentTimeTimer

132 {

133     //提前先调用一次进度更新,以保证定时器的工作时及时的

134     [self updateCurrentTime];

135     

136     //创建一个定时器,每一秒钟调用一次

137     self.CurrentTimeTimer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateCurrentTime) userInfo:nil repeats:YES];

138     //把定时器加入到运行时中

139     [[NSRunLoop mainRunLoop]addTimer:self.CurrentTimeTimer forMode:NSRunLoopCommonModes];

140 }

141 /**

142  *移除一个定时器

143  */

144 -(void)removeCurrentTime

145 {

146     [self.CurrentTimeTimer invalidate];

147     

148     //把定时器清空

149     self.CurrentTimeTimer=nil;

150 }

151 

152 /** 153  * 更新播放进度 154  */

155 -(void)updateCurrentTime 156 { 157     //1.计算进度值

158     double progress=self.player.currentTime/self.player.duration; 159     

160     //2.计算滑块的x值 161     // 滑块的最大的x值

162     CGFloat sliderMaxX=self.view.width-self.slider.width; 163     self.slider.x=sliderMaxX*progress; 164     //设置滑块上的当前播放时间

165  [self.slider setTitle:[self strWithTime:self.player.currentTime] forState:UIControlStateNormal]; 166     

167     //3.设置进度条的宽度

168     self.progressView.width=self.slider.center.x; 169     

170 } 171 

172 #pragma mark-内部的按钮监听方法

173 //返回按钮

174 - (IBAction)exit {

175     

176     //0.移除定时器

177  [self removeCurrentTime]; 178     //1.禁用整个app的点击事件

179     UIWindow *window=[UIApplication sharedApplication].keyWindow;

180     window.userInteractionEnabled=NO;

181     

182     //2.动画隐藏View

183     [UIView animateWithDuration:0.25 animations:^{

184         self.view.y=window.height;

185     } completion:^(BOOL finished) {

186         window.userInteractionEnabled=YES;

187         //设置view隐藏能够节省一些性能

188         self.view.hidden=YES;

189     }];

190 }

191 

192 /**

193  *点击了进度条 194  */

195 - (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender { 196     //获取当前单击的点

197     CGPoint point=[sender locationInView:sender.view]; 198     //切换歌曲的当前播放时间

199     self.player.currentTime=(point.x/sender.view.width)*self.player.duration; 200     //更新播放进度

201  [self updateCurrentTime]; 202 } 203 

204 - (IBAction)panSlider:(UIPanGestureRecognizer *)sender { 205     

206     //1.获得挪动的距离

207     CGPoint t=[sender translationInView:sender.view]; 208     //把挪动清零

209  [sender setTranslation:CGPointZero inView:sender.view]; 210     

211     //2.控制滑块和进度条的frame

212     self.slider.x+=t.x; 213     //设置进度条的宽度

214     self.progressView.width=self.slider.center.x; 215     

216     //3.设置时间值

217     CGFloat sliderMaxX=self.view.width-self.slider.width; 218     double progress=self.slider.x/sliderMaxX; 219     //当前的时间值=音乐的时长*当前的进度值

220     NSTimeInterval time=self.player.duration*progress; 221  [self .slider setTitle:[self strWithTime:time] forState:UIControlStateNormal]; 222     

223     //4.如果开始拖动,那么就停止定时器

224     if (sender.state==UIGestureRecognizerStateBegan) { 225         //停止定时器

226  [self removeCurrentTime]; 227     }else if(sender.state==UIGestureRecognizerStateEnded) 228  { 229         //设置播放器播放的时间

230         self.player.currentTime=time; 231         //开启定时器

232  [self addCurrentTimeTimer]; 233  } 234 } 235 @end

二、代码说明(一)

  调整开始播放音乐按钮,让其返回一个音乐播放器,而非BOOL型的。

 1 /**

 2  *播放音乐

 3  */

 4 +(AVAudioPlayer *)playMusic:(NSString *)filename

 5 {

 6     if (!filename) return nil;//如果没有传入文件名,那么直接返回

 7     //1.取出对应的播放器

 8     AVAudioPlayer *player=[self musicPlayers][filename];

 9     

10     //2.如果播放器没有创建,那么就进行初始化

11     if (!player) {

12         //2.1音频文件的URL

13         NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];

14         if (!url) return nil;//如果url为空,那么直接返回

15         

16         //2.2创建播放器

17         player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];

18         

19         //2.3缓冲

20         if (![player prepareToPlay]) return nil;//如果缓冲失败,那么就直接返回

21         

22         //2.4存入字典

23         [self musicPlayers][filename]=player;

24     }

25     

26     //3.播放

27     if (![player isPlaying]) {

28         //如果当前没处于播放状态,那么就播放

29          [player play];

30     }

31 

32     return player;//正在播放,那么就返回YES

33 }

三、代码说明(二)

  把时间转换为时间字符串的方法:

1 /**

2  *把时间长度-->时间字符串

3  */

4 -(NSString *)strWithTime:(NSTimeInterval)time

5 {

6     int minute=time / 60;

7     int second=(int)time % 60;

8     return [NSString stringWithFormat:@"%d:%d",minute,second];

9 }

四、代码说明(三)

  说明:进度控制

  监听当前的播放,使用一个定时器,不断的监听当前是第几秒。

  关于定时器的处理:这里使用了三个方法,分别是添加定时器,移除定时器,和更新播放进度。

注意细节

(1)移除定时器后,对定时器进行清空处理。

 1 /**

 2  *移除一个定时器

 3  */

 4 -(void)removeCurrentTime

 5 {

 6     [self.CurrentTimeTimer invalidate];

 7     

 8     //把定时器清空

 9     self.CurrentTimeTimer=nil;

10 }

(2)当看不到界面的时候,停止定时器。

(3)在开始播放音乐的方法中进行判断,如果当前播放的音乐和传入的音乐一致,那么添加定时器后直接返回。

(4)重置播放的音乐方法中,停止定时器。

五、代码说明(四)

  说明:点击和拖动进度条的处理

1.点击进度条

  先添加单击的手势识别器。

  iOS开发拓展篇—音频处理(音乐播放器4)  

  往控制器拖线:

    iOS开发拓展篇—音频处理(音乐播放器4)

涉及的代码:

 1 /**

 2  *点击了进度条

 3  */

 4 - (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender {

 5     //获取当前单击的点

 6     CGPoint point=[sender locationInView:sender.view];

 7     //切换歌曲的当前播放时间

 8     self.player.currentTime=(point.x/sender.view.width)*self.player.duration;

 9     //更新播放进度

10     [self updateCurrentTime];

11 }

2.拖拽进度条

  先添加拖拽手势识别器

  iOS开发拓展篇—音频处理(音乐播放器4)

往控制器拖线

  iOS开发拓展篇—音频处理(音乐播放器4)

涉及的代码:

 1 /**

 2  *拖动滑块

 3  */

 4 - (IBAction)panSlider:(UIPanGestureRecognizer *)sender {

 5     

 6     //1.获得挪动的距离

 7     CGPoint t=[sender translationInView:sender.view];

 8     //把挪动清零

 9     [sender setTranslation:CGPointZero inView:sender.view];

10     

11     //2.控制滑块和进度条的frame

12     self.slider.x+=t.x;

13     //设置进度条的宽度

14     self.progressView.width=self.slider.center.x;

15     

16     //3.设置时间值

17     CGFloat sliderMaxX=self.view.width-self.slider.width;

18     double progress=self.slider.x/sliderMaxX;

19     //当前的时间值=音乐的时长*当前的进度值

20     NSTimeInterval time=self.player.duration*progress;

21     [self .slider setTitle:[self strWithTime:time] forState:UIControlStateNormal];

22     

23     //4.如果开始拖动,那么就停止定时器

24     if (sender.state==UIGestureRecognizerStateBegan) {

25         //停止定时器

26         [self removeCurrentTime];

27     }else if(sender.state==UIGestureRecognizerStateEnded)

28     {

29         //设置播放器播放的时间

30         self.player.currentTime=time;

31         //开启定时器

32         [self addCurrentTimeTimer];

33     }

34 }

你可能感兴趣的:(ios开发)