多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > iOS 簡單實用的音樂播放器,少年,自己做個歌單吧。。。。。。

iOS 簡單實用的音樂播放器,少年,自己做個歌單吧。。。。。。

來源:程序員人生   發布時間:2016-07-09 13:08:07 閱讀次數:3154次

    我也不知道為何突然會想寫1下音樂播放器的,感覺應當挺好的玩,自己把自己喜歡的歌曲導出來,用程序加載跑

起來,那歌聽起來一定很帶感啊。。。。。。不過那首Love Story被我聽了無數遍。。。。。。聽吐了


各位看官有興趣也能夠聽聽。其實前期準備是很坑爹的,找歌詞真的蛋疼啊


空話不多說,老規矩,看成品先:



尼瑪這東西占得空間太大了,錄不了太多。。。。。。


先介紹吧


首先

做個播放器的界面出來,上面是個tableView來加載歌詞,底部兩個Slider,1個聲音,1個進度,最底下3個Button。


這里簡單介紹下用AutoLayout實現底部3個Button等寬,等間距的需求實現

// 底部3個按鈕平分屏幕的寬度做法

// 1.首先固定左邊第1個按鈕的下和左的束縛固定好,其中高度可以給也能夠不給,讓文字自動填充

// 2.然后選中3個按鈕,選中垂直對齊和等寬的兩個必要條件

// 3.以后中間的按鈕只要設置距離左邊按鈕的束縛就好

// 4.最后讓最右邊的按鈕距離右側的束縛,左邊的束縛固定好,選中3個,按下option + command + =,對齊便可


簡單到爆,根本不需要代碼



然后

導入需要操作的歌曲和歌詞進行路徑存儲



先看看屬性和控件

#import "ViewController.h" #import <AVFoundation/AVFoundation.h> #import "MKJParserLrc.h" #import "UIImage+ImageEffects.h" @interface ViewController () <UITableViewDataSource,UITableViewDelegate,AVAudioPlayerDelegate> @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (weak, nonatomic) IBOutlet UISlider *volSlider; @property (weak, nonatomic) IBOutlet UISlider *progressSlider; @property (nonatomic,strong) AVAudioPlayer *audioPlayer; // AVAudioPlayer ----> 音頻 本地 @property (nonatomic,strong) NSArray *mp3Arr; // mp3路徑 @property (nonatomic,strong) NSArray *lrcArr; // 歌詞路徑 @property (nonatomic,assign) NSInteger mp3Index; // 當前的播放下表 @property (nonatomic,assign) NSUInteger currentRow; // 當前哪1行 @property (nonatomic,strong) MKJParserLrc *mkj; // 解析歌詞用的 @end


這里我的圖片我做了簡單的高斯模糊,這里介紹個類給大家,1并把代碼都給出來,需要的拿去用把



- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = [UIColor colorWithRed:193/255.4 green:193/255.0 blue:193/255.4 alpha:0.7]; [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; self.tableView.rowHeight = 60; // 圖片高斯模糊 UIImage *image = [UIImage imageNamed:@"436c1b64a2b6a4cbab09ee22db3851f4⑴400x2100.jpg"]; image = [image applyBlurWithRadius:15 tintColor:nil saturationDeltaFactor:1.5 maskImage:nil]; self.tableView.backgroundView = [[UIImageView alloc] initWithImage:image]; // 存儲路徑 self.mp3Arr = @[[[NSBundle mainBundle] pathForResource:@"Love Story" ofType:@"mp3"],[[NSBundle mainBundle] pathForResource:@"薛之謙-演員" ofType:@"mp3"],[[NSBundle mainBundle] pathForResource:@"華晨宇-異類" ofType:@"mp3"]]; self.lrcArr = @[[[NSBundle mainBundle] pathForResource:@"Love Story" ofType:@"lrc"],[[NSBundle mainBundle] pathForResource:@"薛之謙-演員" ofType:@"lrc"],[[NSBundle mainBundle] pathForResource:@"華晨宇-異類" ofType:@"lrc"]]; self.mkj = [[MKJParserLrc alloc] init]; // 根據路徑加載歌曲和歌詞 [self loadMp3:self.mp3Arr[self.mp3Index] lrcPath:self.lrcArr[self.mp3Index]]; // 啟動定時器,1直更新 [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(changeTime:) userInfo:nil repeats:YES]; }


以后

我們加載MP3歌曲和解析歌詞

#import <AVFoundation/AVFoundation.h>

導入這個頭文件,用AVAudioPlayer來進行播放

// 加載歌詞和歌曲 - (void)loadMp3:(NSString *)mp3Str lrcPath:(NSString *)lrcStr { // 這個方法是獲得網上的 // self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:mp3Str] error:nil]; // 下面的是本地的 self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3Str] error:nil]; self.audioPlayer.delegate = self; self.audioPlayer.volume = 0.5f; // 解析歌詞方法 [self.mkj parserLrcWithFileURL:lrcStr]; // 讓slider的進去和歌曲最大時間1致 self.progressSlider.maximumValue = self.audioPlayer.duration; // 準備播放 [self.audioPlayer prepareToPlay]; }

用自己創建的對象進行歌詞解析,暴露個方法傳本地URL進來

@interface MKJParserLrc : NSObject @property (nonatomic,strong) NSMutableArray *timeArr; @property (nonatomic,strong) NSMutableArray *lrcArr; - (void)parserLrcWithFileURL:(NSString *)lrcPath; @end

這里分割字符串的方法千千萬,咱只是展現1種

- (void)parserLrcWithFileURL:(NSString *)lrcPath { // 每次進來都清除掉之前的 [self.lrcArr removeAllObjects]; [self.timeArr removeAllObjects]; // 通過路徑讀取歌詞的字符串 NSString *lrcStr = [NSString stringWithContentsOfFile:lrcPath encoding:NSUTF8StringEncoding error:nil]; // 分割 NSArray *lrcArr = [lrcStr componentsSeparatedByString:@"["]; // 繼續分割 for (NSString *sepStr in lrcArr) { // 無腦分割 NSArray *sepArr = [sepStr componentsSeparatedByString:@"]"]; // 3種可能不要,第1種就是頭部歌詞,第2個時間中沒有歌詞的,第3個就是沒有歌詞換行的 if (!([sepArr[0] isEqualToString:@""] || [sepArr[1] isEqualToString:@"\n"] || [sepArr[1] isEqualToString:@"\r\n"])) { [self.timeArr addObject:sepArr[0]]; [self.lrcArr addObject:sepArr[1]]; } } }


第4步

把點擊事件和代理方法實現

// 上1首 - (IBAction)previousSong:(id)sender { [self.audioPlayer stop]; self.mp3Index--; if (_mp3Index==⑴) { self.mp3Index = 2; } [self loadMp3:self.mp3Arr[self.mp3Index] lrcPath:self.lrcArr[self.mp3Index]]; [self.audioPlayer play]; } // 播放或暫停 - (IBAction)play:(id)sender { if (self.audioPlayer.playing) { [self.audioPlayer pause]; } else { [self.audioPlayer play]; } } // 下1首 - (IBAction)NextSong:(id)sender { [self.audioPlayer stop]; self.mp3Index++; if (self.mp3Index == 3) { self.mp3Index = 0; } [self loadMp3:self.mp3Arr[self.mp3Index] lrcPath:self.lrcArr[self.mp3Index]]; [self.audioPlayer play]; } // 聲音change - (IBAction)volChange:(UISlider *)sender { self.audioPlayer.volume = sender.value; } // 進度change - (IBAction)rateChange:(UISlider *)sender { self.audioPlayer.currentTime = sender.value; } - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { [self NextSong:nil]; }
最后啟動個定時器,讓進度條和歌詞實時更新,讓歌詞和歌曲匹配,這個方法也是最關鍵的,最關鍵的

// 更新的方法 - (void)changeTime:(NSTimer *)timer { // 讓進度條和當前播放時間1直 self.progressSlider.value = self.audioPlayer.currentTime; // 遍歷歌詞,來記錄當前是播放哪一個row [self.mkj.timeArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { NSString *timeStr = self.mkj.timeArr[idx]; NSArray *timeArr = [timeStr componentsSeparatedByString:@":"]; CGFloat seconds = [timeArr[0] floatValue] * 60 + [timeArr[1] floatValue]; if (seconds >= self.audioPlayer.currentTime) { if (idx == 0) { self.currentRow = idx; } else { self.currentRow = idx - 1; } *stop = YES; } }]; // 刷新 [self.tableView reloadData]; // 轉動到指定的row現實歌詞 if (self.currentRow < self.mkj.lrcArr.count) { [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentRow inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; } }

天真的我以為這就完了,這破東西能讓你崩的措手不及!!!




像我這樣手速那末快的,瞬間就崩了,緣由以下

 (lldb) po indexPath

<NSIndexPath: 0xc000000007a00016> {length = 2, path = 0 - 61}

    2016-06-27 16:22:47.557 MusicPlayerDemo[5176:272368] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 61 beyond bounds [0 .. 51]'

    *** First throw call stack:


這就很好理解了,首先這3首歌的歌詞分別52 46 81行,當我們快速滑動進度條的時候,

再切換到上1首或下1首,數組越界了啊,歌詞不同,肯定會越界,找到緣由就好辦了

在加載CELL的方法里面加上這個判斷就妥妥的了,你想怎樣弄都不會蹦了

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if (indexPath.row < self.mkj.lrcArr.count) { cell.textLabel.text = self.mkj.lrcArr[indexPath.row]; }


看到這里,1個簡單的音樂播放器弄定啦,我心里想你們肯定是這樣的


但實際上你們肯定是這樣的




血的教訓,如果你也要寫個Demo,千萬別用你喜歡的歌曲去做,不然那首歌就被你毀


了,各位有興趣的去github下載下聽聽,有Bug記得告知我喲,Love Story確切很好聽,

但是被我聽吐了。。


Demo地址:https://github.com/DeftMKJ/MusicDemo





不早啦,再聽1遍就睡了,各位晚安








生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 老司机午夜精品99久久免费 | 波多野结衣手机视频一区 | 国产成人精品免费视频软件 | 国产精品国产三级国产专不∫ | 亚州精品一区二区三区 | 中文字幕资源在线 | 欧美一级毛片美99毛片 | 免费aⅴ网站 | 午夜在线精品不卡国产 | 日韩啊v| 久久人人澡 | 2019在线亚洲成年视频网站 | japanesefree日本护士 | 一级美国乱色毛片 | 理论毛片 | 日本中文字幕在线视频站 | 欧美亚洲综合另类在线观看 | 国产精品久久网 | 叼嘿在线观看 | 亚洲综合视频网 | 亚洲中午字幕 | 亚洲综合站 | 美女免费网站在线视频 | 亚洲剧情在线 | 欧美日韩国产成人精品 | 日本高清免费视频www | xxxxx免费| 国产亚洲欧美日本一二三本道 | 国产精品第1页 | 久草福利在线播放 | 美国毛片在线观看 | 性欧美大战久久久久久久 | 亚洲在线一区二区 | 亚洲精品久久99久久一区 | 日韩欧美片 | 一区二区三区四区视频 | 伊人久久大香线蕉75 | 欧美日韩精品免费一区二区三区 | 亚洲综合图片小说 | 羞羞视频免费观看网站 | 一二三四视频中文字幕在线看 |