iOS音频播放器锁屏歌词显示与性能优化 原

iOS音频播放器锁屏歌词显示与性能优化

一、引言

    前边有博客探讨了有关iOS开发中音频播放的技术与进行后台音频播放并在后台与用户进行交互的方法,本篇将探讨一种在锁屏界面同步显示歌词歌词的方法,并在应用性能上进行一些处理。前边博客地址如下:

iOS音频开发AVAudioPlayer的应用:http://my.oschina.net/u/2340880/blog/420129

iOS后台音频开发与交互技术:http://my.oschina.net/u/2340880/blog/420183

二、在锁屏界面同步显示歌词

   我们知道,在音频后台播放时,锁屏界面的信息是由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];
}

锁屏歌词的显示效果如下:

三、应用性能的优化

   从功能上来说,通过一直合成刷新锁屏界面的封面图是可行的,然而在使用中我发现,不停和合成图片和刷新操作将使设备非常耗电,如果可以完成下面的优化,则可以大大提高应用的性能:

1.应用在前台时不进行后台锁屏界面的刷新操作。

2.应用在后台时不进行前台歌词信息、歌曲信息的相应更新。

3.当屏幕变黑关闭时,停止所有刷新操作。

4.当屏幕从新被点亮时,进行后台信息刷新。

    上面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

专注技术,热爱生活,交流技术,也做朋友。 ——珲少

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏葡萄城控件技术团队

用FlexGrid做开发,轻松处理百万级表格数据

表格数据处理是我们项目开发中经常会遇到的设计需求之一,所需处理的数据量也较大,通常是万级、甚至百万级。此时,完全依赖平台自带的表格工具,往往无法加载如此大的数据...

2208
来自专栏知晓程序

开发|只需 10 分钟!让你的小程序轻松接入「微信支付」

你可能需要花半天时间看微信支付文档,再花半天调试支付签名,最后还得加两天时间搞定支付回调通知以及和自己的业务结合。

1462
来自专栏极乐技术社区

小程序一周报 | 小程序开发工具支持真机调试 / 春节期间小程序暂停审核通知

开发者可直接在开发工具内控制微信客户端中的小程序,进行断点、单步执行,调用所有微信原生API,查看所有小程序输出日志等。

1090
来自专栏编程微刊

进阶攻略|前端完整的学习路线

1622
来自专栏安恒网络空间安全讲武堂

0CTF h4x0rs.club1/2 复现

周末肛了一下0ctf,发现自己依旧那么菜。一道题也没解出来,成功的再一次拖了队伍后退。 今天发现国外大佬们已经开始放wp了。于是自己学习一波,复现一下。 先吐槽...

3967
来自专栏Jerry的SAP技术分享

SAP成都研究院大卫哥:SAP C4C中国本地化之微信小程序集成

今天的文章来自Wu David,SAP成都研究院C4C开发团队的架构师,在加入团队之前曾经在SAP上海研究院工作,组内同事习惯亲切地称呼他为大卫哥。

1092
来自专栏维恩的派VNPIE

用于回测的Python交互K线工具

开发策略时,如何直观地检查自己的交易逻辑是否正确?代码所实现的和自己的策略逻辑是否一致?moonnejs在「维恩的派」论坛里分享了一个可以用于回测的交互K线工具...

4352
来自专栏CDA数据分析师

教你一招 | 用Python写一个简单的微博爬虫

我是个微博重度用户,工作学习之余喜欢刷刷timeline看看有什么新鲜事发生,也因此认识了不少高质量的原创大V,有分享技术资料的,比如好东西传送门;有时不时给你...

21810
来自专栏黑白安全

如何防范黑客人肉搜索

不要在网络上泄露自己的隐私 这里的隐私指的是自己的真实身份,例如我们在注册一些网站、论坛的ID时,会让你填写一些个人的真实情况,这时我们最好不要填写(通常在注册...

1465
来自专栏张戈的专栏

WordPress 4.0 Benny简体中文版现已开放下载

昨天,收到了 WordPress 官方邮件,告知 4.0 已发布,要我确认中国联盟的导航插件是否兼容新版本。 ? 不过后台看了下,却没提示更新。直到今早才在后台...

3627

扫码关注云+社区

领取腾讯云代金券