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

实现效果:

一、半透明滑块的设置

复制代码
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 CGFloat sliderMaxX=self.view.width-self.slider.width;
13 self.slider.x+=t.x;
14 //控制滑块的frame,不让其越界
15 if(self.slider.x<0)
16 {
17 self.slider.x=0;
18 }else if (self.slider.x>sliderMaxX)
19 {
20 self.slider.x=sliderMaxX;
21 }
22 //设置进度条的宽度
23 self.progressView.width=self.slider.center.x;
24
25 //3.设置时间值
26 double progress=self.slider.x/sliderMaxX;
27 //当前的时间值=音乐的时长
当前的进度值
28 NSTimeInterval time=self.player.duration
progress;
29 [self.slider setTitle:[self strWithTime:time] forState:UIControlStateNormal];
30
31 //设置拖拽进度的X的值
32 self.currentTimeView.x=self.slider.x;
33 [self.currentTimeView setTitle:self.slider.currentTitle forState:UIControlStateNormal];
34
35 //4.如果开始拖动,那么就停止定时器
36 if (sender.state==UIGestureRecognizerStateBegan) {
37 //停止定时器
38 [self removeCurrentTime];
39
40 //设置拖拽进度
41 //显示
42 self.currentTimeView.hidden=NO;
43 self.currentTimeView.y=self.currentTimeView.superview.height-5-self.currentTimeView.height;
44
45 }else if(sender.state==UIGestureRecognizerStateEnded)
46 {
47 //隐藏
48 self.currentTimeView.hidden=YES;
49 //设置播放器播放的时间
50 self.player.currentTime=time;
51 #warning 如果正在播放,才需要添加定时器
52 // if (self.player.isPlaying) {
53 //开启定时器
54 [self addCurrentTimeTimer];
55 // }
56 }
57 }
复制代码
裁剪圆角的细节处理:

二、播放或暂停、上一首、下一首的实现

复制代码
1 //上一首
2 - (IBAction)previous {
3 //1.在开始播放之前,禁用一切的app点击事件
4 UIWindow *window=[[UIApplication sharedApplication].windows lastObject];
5 window.userInteractionEnabled=NO;
6
7 //2.重置当前歌曲
8 [self resetPlayingMusic];
9
10 //3.获得上一首歌曲
11 [YYMusicTool setPlayingMusic:[YYMusicTool previousMusic]];
12
13 //4.播放上一首歌曲
14 [self starPlayingMusic];
15
16 //5.回复window的点击为可用
17 window.userInteractionEnabled=YES;
18 }
19 //下一首
20 - (IBAction)next {
21 //1.在开始播放之前,禁用一切的app点击事件
22 UIWindow *window=[[UIApplication sharedApplication].windows lastObject];
23 window.userInteractionEnabled=NO;
24
25 //2.重置当前歌曲
26 [self resetPlayingMusic];
27
28 //3.获得下一首歌曲
29 [YYMusicTool setPlayingMusic:[YYMusicTool nextMusic]];
30
31 //4.播放下一首歌曲
32 [self starPlayingMusic];
33
34 //5.回复window的点击为可用
35 window.userInteractionEnabled=YES;
36 }
37
38 //继续或暂停播放
39 - (IBAction)playOrPause {
40 if (self.playOrPauseButton.isSelected) {//暂停
41 self.playOrPauseButton.selected=NO;
42 //暂停播放
43 [YYAudioTool pauseMusic:self.playingMusic.filename];
44 //停掉定时器
45 [self removeCurrentTime];
46 }else
47 {
48 self.playOrPauseButton.selected=YES;
49 //继续播放
50 [YYAudioTool playMusic:self.playingMusic.filename];
51 //开启定时器
52 [self addCurrentTimeTimer];
53 }
54 }
复制代码
说明:播放和暂停按钮的图片设置在两种状态下并不一样,设置播放按钮的状态

三、对存在的bug进行改进

拖拽还存在问题(定时器的问题)
  
更好的方法时在添加定时器的地方进行更细的控制:
  
复制代码
1 /**
2 * 添加一个定时器
3 */
4 -(void)addCurrentTimeTimer
5 {
6 //如果当前没有在播放,那么就直接返回
7 if (self.player.isPlaying==NO) return;
8
9 //在添加一个定时器之前,先把以前的定时器移除
10 [self removeCurrentTime];
11
12 //提前先调用一次进度更新,以保证定时器的工作时及时的
13 [self updateCurrentTime];
14
15 //创建一个定时器,每一秒钟调用一次
16 self.CurrentTimeTimer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateCurrentTime) userInfo:nil repeats:YES];
17 //把定时器加入到运行时中
18 [[NSRunLoop mainRunLoop]addTimer:self.CurrentTimeTimer forMode:NSRunLoopCommonModes];
19 }
复制代码

四、补充

完整的代码如下:

复制代码
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 UIButton *currentTimeView;
17 //进度条
18 @property (weak, nonatomic) IBOutlet UIView *progressView;
19 //滑块
20 @property (weak, nonatomic) IBOutlet UIButton *slider;
21 @property (weak, nonatomic) IBOutlet UIImageView *iconView;
22 @property (weak, nonatomic) IBOutlet UILabel *songLabel;
23 @property (weak, nonatomic) IBOutlet UILabel *singerLabel;
24 //当前播放的音乐的时长
25 @property (weak, nonatomic) IBOutlet UILabel *durationLabel;
26 //正在播放的音乐
27 @property(nonatomic,strong)YYMusicModel *playingMusic;
28 //音乐播放器对象
29 @property(nonatomic,strong)AVAudioPlayer *player;
30 //定时器
31 @property(nonatomic,strong)NSTimer *CurrentTimeTimer;
32 - (IBAction)exit;
33 - (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender;
34 - (IBAction)panSlider:(UIPanGestureRecognizer )sender;
35 - (IBAction)previous;
36 - (IBAction)playOrPause;
37 - (IBAction)next;
38 @property (weak, nonatomic) IBOutlet UIButton playOrPauseButton;
39
40 @end
41
42 @implementation YYPlayingViewController
43
44 -(void)viewDidLoad
45 {
46 [super viewDidLoad];
47
48 //裁剪圆角
49 self.currentTimeView.layer.cornerRadius=8;
50
51 }
52 #pragma mark-公共方法
53 -(void)show
54 {
55 //1.禁用整个app的点击事件
56 UIWindow window=[UIApplication sharedApplication].keyWindow;
57 window.userInteractionEnabled=NO;
58
59 //2.添加播放界面
60 //设置View的大小为覆盖整个窗口
61 self.view.frame=window.bounds;
62 //设置view显示
63 self.view.hidden=NO;
64 //把View添加到窗口上
65 [window addSubview:self.view];
66
67 //3.检测是否换了歌曲
68 if (self.playingMusic!=[YYMusicTool playingMusic]) {
69 [self resetPlayingMusic];
70 }
71
72 //4.使用动画让View显示
73 self.view.y=self.view.height;
74 [UIView animateWithDuration:0.25 animations:^{
75 self.view.y=0;
76 } completion:^(BOOL finished) {
77
78 //设置音乐数据
79 [self starPlayingMusic];
80 window.userInteractionEnabled=YES;
81 }];
82 }
83
84
85 #pragma mark-私有方法
86 //重置正在播放的音乐
87 -(void)resetPlayingMusic
88 {
89 //1.重置界面数据
90 self.iconView.image=[UIImage imageNamed:@"play_cover_pic_bg"];
91 self.songLabel.text=nil;
92 self.singerLabel.text=nil;
93
94 //2.停止播放
95 [YYAudioTool stopMusic:self.playingMusic.filename];
96 //把播放器进行清空
97 self.player=nil;
98
99 //3.停止定时器
100 [self removeCurrentTime];
101
102 //4.设置音乐播放按钮的状态
103 self.playOrPauseButton.selected=NO;
104 }
105 //开始播放音乐数据
106 -(void)starPlayingMusic
107 {
108 //1.设置界面数据
109
110 //如果当前播放的音乐就是传入的音乐,那么就直接返回
111 if (self.playingMusic==[YYMusicTool playingMusic])
112 {
113 //把定时器加进去
114 [self addCurrentTimeTimer];
115 return;
116 }
117 //存取音乐
118 self.playingMusic=[YYMusicTool playingMusic];
119 self.iconView.image=[UIImage imageNamed:self.playingMusic.icon];
120 self.songLabel.text=self.playingMusic.name;
121 self.singerLabel.text=self.playingMusic.singer;
122
123 //2.开始播放
124 self.player = [YYAudioTool playMusic:self.playingMusic.filename];
125
126 //3.设置时长
127 //self.player.duration; 播放器正在播放的音乐文件的时间长度
128 self.durationLabel.text=[self strWithTime:self.player.duration];
129
130 //4.添加定时器
131 [self addCurrentTimeTimer];
132
133 //5.设置音乐播放按钮的状态
134 self.playOrPauseButton.selected=YES;
135 }
136
137 /

138 把时间长度-->时间字符串
139 /
140 -(NSString )strWithTime:(NSTimeInterval)time
141 {
142 int minute=time / 60;
143 int second=(int)time % 60;
144 return [NSString stringWithFormat:@"%d:%d",minute,second];
145 }
146
147 #pragma mark-定时器控制
148 /

149 * 添加一个定时器
150 /
151 -(void)addCurrentTimeTimer
152 {
153 //如果当前没有在播放,那么就直接返回
154 if (self.player.isPlaying==NO) return;
155
156 //在添加一个定时器之前,先把以前的定时器移除
157 [self removeCurrentTime];
158
159 //提前先调用一次进度更新,以保证定时器的工作时及时的
160 [self updateCurrentTime];
161
162 //创建一个定时器,每一秒钟调用一次
163 self.CurrentTimeTimer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateCurrentTime) userInfo:nil repeats:YES];
164 //把定时器加入到运行时中
165 [[NSRunLoop mainRunLoop]addTimer:self.CurrentTimeTimer forMode:NSRunLoopCommonModes];
166 }
167 /

168 移除一个定时器
169 /
170 -(void)removeCurrentTime
171 {
172 [self.CurrentTimeTimer invalidate];
173
174 //把定时器清空
175 self.CurrentTimeTimer=nil;
176 }
177
178 /

179 * 更新播放进度
180 /
181 -(void)updateCurrentTime
182 {
183 //1.计算进度值
184 double progress=self.player.currentTime/self.player.duration;
185
186 //2.计算滑块的x值
187 // 滑块的最大的x值
188 CGFloat sliderMaxX=self.view.width-self.slider.width;
189 self.slider.x=sliderMaxX
progress;
190 //设置滑块上的当前播放时间
191 [self.slider setTitle:[self strWithTime:self.player.currentTime] forState:UIControlStateNormal];
192
193 //3.设置进度条的宽度
194 self.progressView.width=self.slider.center.x;
195
196 }
197
198 #pragma mark-内部的按钮监听方法
199 //返回按钮
200 - (IBAction)exit {
201
202 //0.移除定时器
203 [self removeCurrentTime];
204 //1.禁用整个app的点击事件
205 UIWindow window=[UIApplication sharedApplication].keyWindow;
206 window.userInteractionEnabled=NO;
207
208 //2.动画隐藏View
209 [UIView animateWithDuration:0.25 animations:^{
210 self.view.y=window.height;
211 } completion:^(BOOL finished) {
212 window.userInteractionEnabled=YES;
213 //设置view隐藏能够节省一些性能
214 self.view.hidden=YES;
215 }];
216 }
217
218 /

219 点击了进度条
220 /
221 - (IBAction)tapProgressBg:(UITapGestureRecognizer )sender {
222 //获取当前单击的点
223 CGPoint point=[sender locationInView:sender.view];
224 //切换歌曲的当前播放时间
225 self.player.currentTime=(point.x/sender.view.width)
self.player.duration;
226 //更新播放进度
227 [self updateCurrentTime];
228 }
229 /

230 *拖动滑块
231 /
232 - (IBAction)panSlider:(UIPanGestureRecognizer )sender {
233
234 //1.获得挪动的距离
235 CGPoint t=[sender translationInView:sender.view];
236 //把挪动清零
237 [sender setTranslation:CGPointZero inView:sender.view];
238
239 //2.控制滑块和进度条的frame
240 CGFloat sliderMaxX=self.view.width-self.slider.width;
241 self.slider.x+=t.x;
242 //控制滑块的frame,不让其越界
243 if(self.slider.x<0)
244 {
245 self.slider.x=0;
246 }else if (self.slider.x>sliderMaxX)
247 {
248 self.slider.x=sliderMaxX;
249 }
250 //设置进度条的宽度
251 self.progressView.width=self.slider.center.x;
252
253 //3.设置时间值
254 double progress=self.slider.x/sliderMaxX;
255 //当前的时间值=音乐的时长
当前的进度值
256 NSTimeInterval time=self.player.duration
progress;
257 [self.slider setTitle:[self strWithTime:time] forState:UIControlStateNormal];
258
259 //设置拖拽进度的X的值
260 self.currentTimeView.x=self.slider.x;
261 [self.currentTimeView setTitle:self.slider.currentTitle forState:UIControlStateNormal];
262
263 //4.如果开始拖动,那么就停止定时器
264 if (sender.state==UIGestureRecognizerStateBegan) {
265 //停止定时器
266 [self removeCurrentTime];
267
268 //设置拖拽进度
269 //显示
270 self.currentTimeView.hidden=NO;
271 self.currentTimeView.y=self.currentTimeView.superview.height-5-self.currentTimeView.height;
272
273 }else if(sender.state==UIGestureRecognizerStateEnded)
274 {
275 //隐藏
276 self.currentTimeView.hidden=YES;
277 //设置播放器播放的时间
278 self.player.currentTime=time;
279 #warning 如果正在播放,才需要添加定时器
280 // if (self.player.isPlaying) {
281 //开启定时器
282 [self addCurrentTimeTimer];
283 // }
284 }
285 }
286
287 //上一首
288 - (IBAction)previous {
289 //1.在开始播放之前,禁用一切的app点击事件
290 UIWindow *window=[[UIApplication sharedApplication].windows lastObject];
291 window.userInteractionEnabled=NO;
292
293 //2.重置当前歌曲
294 [self resetPlayingMusic];
295
296 //3.获得上一首歌曲
297 [YYMusicTool setPlayingMusic:[YYMusicTool previousMusic]];
298
299 //4.播放上一首歌曲
300 [self starPlayingMusic];
301
302 //5.回复window的点击为可用
303 window.userInteractionEnabled=YES;
304 }
305 //下一首
306 - (IBAction)next {
307 //1.在开始播放之前,禁用一切的app点击事件
308 UIWindow *window=[[UIApplication sharedApplication].windows lastObject];
309 window.userInteractionEnabled=NO;
310
311 //2.重置当前歌曲
312 [self resetPlayingMusic];
313
314 //3.获得下一首歌曲
315 [YYMusicTool setPlayingMusic:[YYMusicTool nextMusic]];
316
317 //4.播放下一首歌曲
318 [self starPlayingMusic];
319
320 //5.回复window的点击为可用
321 window.userInteractionEnabled=YES;
322 }
323 //继续或暂停播放
324 - (IBAction)playOrPause {
325 if (self.playOrPauseButton.isSelected) {//暂停
326 self.playOrPauseButton.selected=NO;
327 //暂停播放
328 [YYAudioTool pauseMusic:self.playingMusic.filename];
329 //停掉定时器
330 [self removeCurrentTime];
331 }else
332 {
333 self.playOrPauseButton.selected=YES;
334 //继续播放
335 [YYAudioTool playMusic:self.playingMusic.filename];
336 //开启定时器
337 [self addCurrentTimeTimer];
338 }
339 }
340
341
342 @end
复制代码

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

推荐阅读更多精彩内容