首页 > 代码库 > iOS开发拓展篇—音频处理(音乐播放器5)

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

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.控制滑块和进度条的frame12     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     }else47     {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)starPlayingMusic107 {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)time141 {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)addCurrentTimeTimer152 {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)removeCurrentTime171 {172     [self.CurrentTimeTimer invalidate];173     174     //把定时器清空175     self.CurrentTimeTimer=nil;176 }177 178 /**179  *  更新播放进度180  */181 -(void)updateCurrentTime182 {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.动画隐藏View209     [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.控制滑块和进度条的frame240     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     }else332     {333         self.playOrPauseButton.selected=YES;334         //继续播放335         [YYAudioTool playMusic:self.playingMusic.filename];336         //开启定时器337         [self addCurrentTimeTimer];338     }339 }340 341 342 @end