前邊有博客探討了有關iOS開發中音頻播放的技術與進行後臺音頻播放並在後臺與用戶進行交互的方法,本篇將探討一種在鎖屏界面同步顯示歌詞歌詞的方法,並在應用性能上進行一些處理。前邊博客地址以下:git
iOS音頻開發AVAudioPlayer的應用:http://my.oschina.net/u/2340880/blog/420129。github
iOS後臺音頻開發與交互技術:http://my.oschina.net/u/2340880/blog/420183。spring
咱們知道,在音頻後臺播放時,鎖屏界面的信息是由MPNowPlayingInfoCenter來設置的,其中的歌曲信息字典能夠設置相似歌曲封面,藝術家,歌曲名,歌曲時間等。然而,對於MPNowPlayingInfoCenter中能夠由開發者掌握的接口十分有限,若要在鎖屏界面同步的顯示歌曲歌詞,一個比較簡單的方法是不停的將當前歌詞與封面進行圖片合成,以後刷新鎖屏界面的圖片。下面代碼是根據解析好的LRC歌詞數據進行圖片合成的示例代碼:性能優化
//這個方法經過傳入的LRC歌詞數據進行圖片的合成 array參數爲每行lrc歌詞數據集合 index爲當前須要播放的lrc歌詞行數 -(void)setCurretLRCArray:(NSArray *)array index:(int)index{ //LRCItem是歌詞模型 裏面的lrc方法獲取歌詞文字字符串 NSString * lineLRC = [(LRCItem *)array[index] lrc]; //提升性能 進行判斷 當前顯示的歌詞有無變化 若是沒變化 不進行後續操做 if ([_lrcLabel.text isEqualToString:lineLRC]) { return; } _lrcLabel.text = lineLRC; //將歌詞整理成整齊數據 //進行行數設置 NSMutableString * lrcStr = [[NSMutableString alloc]init]; if (index<_lines/2) { //前面用\n補齊 int offset = (int)_lines/2-index; for (int j=0; j<offset; j++) { [lrcStr appendFormat:@"\n"]; } for (int j=0; j<_lines-offset; j++) { [lrcStr appendFormat:@"%@\n",[(LRCItem *)array[j] lrc]]; } } else if (array.count-1-index<_lines/2) { //後面用\n補齊 int offset = (int)_lines/2-(int)(array.count-index-1); for (int j=index-(_lines/2); j<array.count; j++) { [lrcStr appendFormat:@"%@\n",[(LRCItem *)array[j] lrc]]; } for (int j=0; j<offset; j++) { [lrcStr appendFormat:@"\n"]; } }else { for (int j=0; j<_lines; j++) { [lrcStr appendString:[(LRCItem *)array[index-_lines/2+j] lrc]]; [lrcStr appendString:@"\n"]; } } //將當前顯示的歌詞部分高亮 NSMutableAttributedString * attriStr = [[NSMutableAttributedString alloc]initWithString:lrcStr]; NSRange range = [lrcStr rangeOfString:[array[index] lrc]]; [attriStr setAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]} range:range]; _lrcView.attributedText = attriStr; _lrcIMGLabel.attributedText = attriStr; //進行截屏 if (!_lrcIMGbg) { _lrcIMGbg = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; _lrcIMGbg.image = [UIImage imageNamed:@"BG.jpeg"]; [_lrcIMGbg addSubview:_lrcIMGLabel]; } //獲取添加了歌詞數據的背景圖 UIGraphicsBeginImageContext(_lrcIMGbg.frame.size); CGContextRef context = UIGraphicsGetCurrentContext(); [_lrcIMGbg.layer renderInContext:context]; UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); _lrcImage = [img copy]; }
鎖屏歌詞的顯示效果以下:app
從功能上來講,經過一直合成刷新鎖屏界面的封面圖是可行的,然而在使用中我發現,不停和合成圖片和刷新操做將使設備很是耗電,若是能夠完成下面的優化,則能夠大大提升應用的性能:框架
1.應用在前臺時不進行後臺鎖屏界面的刷新操做。post
2.應用在後臺時不進行前臺歌詞信息、歌曲信息的相應更新。性能
3.當屏幕變黑關閉時,中止全部刷新操做。優化
4.當屏幕重新被點亮時,進行後臺信息刷新。ui
上面4點需求,前兩點十分容易搞定,在AppDelegate中有以下的方法能夠監聽應用程序前臺與後臺的切換:
//應用進入後臺時調用 - (void)applicationWillResignActive:(UIApplication *)application { //發送通知 [[NSNotificationCenter defaultCenter]postNotificationName:@"goBack" object:nil]; } //應用進入前臺時調用 - (void)applicationDidBecomeActive:(UIApplication *)application { [[NSNotificationCenter defaultCenter]postNotificationName:@"goForward" object:nil]; }
在相應的類中監聽這兩個通知便可以作到刷新模式的切換。
對於上面需求的第3點與第4點,Foundation框架中沒有提供公開的方法來監聽屏幕設備的點亮狀態,可是能夠經過notify_register_dispath()方法來監聽。使用示例代碼以下:
#import <notify.h> //在定時器中使用以下代碼實時監聽屏幕狀態 uint64_t locked; __block int token = 0; notify_register_dispatch("com.apple.springboard.hasBlankedScreen",&token,dispatch_get_main_queue(),^(int t){ }); notify_get_state(token, &locked); //若是屏幕變暗 直接不走更新方法 lock爲1則爲變暗關閉狀態 0則爲點亮狀態 if (locked) { return; }
經過上面優化的代碼,性能將會強不少。
因爲前面博客已經詳細的介紹了音頻開發與後臺交互的內容,這篇博客主要探討了鎖屏歌詞相關的開發思路與優化方向,提供的示例代碼都是片斷,並不完整,通過優化的音頻播放器源碼在以下git地址上,須要的朋友能夠做爲參考:
同步顯示鎖屏歌詞的音樂播放器:https://github.com/ZYHshao/MyPlayer。
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592