如何用html+css+js实现卡拉OK歌词效果及桌面歌词

勿忘初心2018-10-26 10:24

此文已由作者严跃杰授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。


卡拉OK桌面歌词自从诞生以来一直广受音乐爱好者的欢迎,几乎成为众多PC端音乐软件标准配置。

桌面歌词的一般表现效果如下(由于ks只能上传10FPS GIF图,所以下图动画效果略有卡顿),同时用户可以根据自己喜好设置显示方式(单行,多行)、字体、颜色、透明度等,此外还提供了歌词窗口锁定等功能。

桌面歌词的诞生要归功于windows2000开始ms开放的layered window解决方案,它为应用开发者提供了开发异形窗口功能强大的API。音乐软件开发者用这些API开发出了桌面歌词,此后长久以来桌面歌词的实现原理都不尽相同,主要有如下两个步骤:

1. GDI/GDI+绘制

2. layered window输出

那么有没有其他实现桌面歌词的方法呢? layered window作为异形窗口唯一的解决方案我们无法绕过去,但是显然直接操作GDI/GDI+不是绘制歌词的唯一方法,今天我们就来看通过浏览器离屏渲染绘制卡拉OK歌词的实现方法。

要浏览器实现绘制,自然就要用到html/css/js。虽然css3.0提供了一系列动画功能,但是我们很快发现只靠css无法实现卡拉OK歌词效果的动画。那么如何实现呢,我们最终找到一种方法:镂空字体+背景色推进方式,如下:

采用上述方法,我们有两种实现方案可以选择:

1.一行歌词设置一个背景,歌词推进时将红色背景从左逐步推进。如下图

这是一种比较直观和好理解方式,但是在实现时遇到如下两个问题:

1)性能损失:js每次修改背景页面需要重新渲染整行歌词,性能有所损失,特别是在pc端混合应用中采用离屏渲染模式用该方案实现桌面歌词的时候,

性能损失较为明显。

2)实现复杂度:在固定刷新频率下,推进量和时间计算较为复杂。

2.每个字单独设置背景,在这个字所在的时间段内,只完成该字背景的推进,如下图。

该方案下,js每次修改背景实现推进时,页面只需要渲染单个字所在的区域,降低了性能损失。在实现复杂度上,由于处理的对象粒度变小了,相当于简化了处理对象的行为模式,因此实现难度也有所降低(虽然还是有点复杂),具体的实现这里不做介绍,感兴趣的可以查阅附件代码。代码可以直接通过chrome打开运行。

krc demo.rar

至于如何将上述html+css+js实现的卡拉OK歌词效果应用到桌面歌词中,实现原理可以参阅文章 一种结合CEF离屏渲染技术实现Windows桌面异形窗口应用的技术方案 。前端组目前正在实现PC混合应用容器框架,届时可以直接引入,并通过js实现窗口开关、移动、锁定等等功能。


性能问题

layered window方案中存在一个对应用性能影响较大的一个限制因素:每次需要更新窗口时,都要更新整个窗口,而不能更新局部。如果我们更新频率过高,会导致性能出现明显下降。正因为如此,我们没有采用按像素推进的方式,而采用了定时刷新模式。这样一来我们可以通过调节刷新频率满足动画平滑度(用户体验)和应用性能之间的平衡关系,经过测试我们发现30ms左右比较合适(这个值可以开放给用户根据自身需求进行配置)。

以上介绍的通过浏览器离屏渲染实现桌面歌词的方案适合于应用了混合框架的音乐软件,因为需要内置支持离屏渲染浏览器引擎,所以单独用于实现桌面歌词是不合适的。不过鉴于目前云终端应用开发模式,市场上大部分pc音乐软件都内置了浏览器引擎。应用这种方式,将极大的提升开发维护效率并降低相应的成本。


网易云免费体验馆,0成本体验20+款云产品! 

更多网易技术、产品、运营经验分享请点击


相关文章:
【推荐】 分布式存储系统可靠性系列五:副本放置算法 & CopySet Replication
【推荐】 wap html5播放器和直播开发小结
【推荐】 Web框架下安全漏洞的测试反思