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.点击进度条

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

往控制器拖线:

涉及的代码:

复制代码
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.拖拽进度条

先添加拖拽手势识别器

往控制器拖线

涉及的代码:

复制代码
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 }
复制代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容