600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > js音乐播放器的实现以及可视化

js音乐播放器的实现以及可视化

时间:2021-11-25 04:22:16

相关推荐

js音乐播放器的实现以及可视化

前言

我们尝试用原生js写一个音乐播放器,对音频做一个简单的可视化。

最终的效果如下图:

思路还是比较明显的,第一,我们要拿到音频的什么数据进行可视化,如何获取?第二,如何可视化,第二个问题就比较简单了,用canvas来操作。

获取音频相关的数据可以用 Web Audio API , 这里我们可以去 MDN 或者 W3C上查看相关的文档。

audio API

我们都知道在web中播放音频用audio这个标签来操作。Web Audio API 是对audio标签功能上的补充,它可以:

一秒内同时发出多个声音把音频流独立出来,进行复杂操作将音频输出到多个地方,比如canvas,从而实现可视化

audio node 有入口和出口,多个节点构成类似链表一样的结构,从一个或者多个音源出发,经过一个或者多个处理节点,最终输出到输出节点。web audio 的一个简单处理过程如下:

创建AudioContext对象在AudioContext对象内设置音源,例如标签创建affcet node(效果节点)选择音频的最终输出节点音频经过效果节点处理后,然后输入到下一个节点

// 获取AudioContext对象window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;// 创建AudioContext对象实例var actx = new AudioContext();// 创建AuidoSource,此处的audios为<audio>标签var audioSrc = actx.createMediaElementSource(audios);var analyser = actx.createAnalyser();// 输入的连接audioSrc.connect(analyser);// 输出的连接analyser.connect(actx.destination);// 本例子中我们获取音高数据来进行可视化var voiceHigh = new Uint8Array(analyser.frequencyBinCount);analyser.getByteFrequencyData(voiceHigh);

canvas

用canvas对音高数据进行可视化展示。

function draw() {var step=Math.round(voiceHigh.length/num);ctx.clearRect(0, 0, canvas.width, canvas.height);ctx.beginPath();for(var i=0; i<num; i++) {var value = voiceHigh[step*i];ctx.fillColor = color;ctx.fillRect(i * 10 + canvas.width * .5, 250, 7, -value + 1);ctx.fillRect(canvas.width * .5 - (i - 1) * 10, 250, 7, -value + 1);ctx.fill();ctx.fillStyle = colort;ctx.fillRect(i * 10 + canvas.width * .5, 250, 7, value + 1);ctx.fillRect(canvas.width * .5 - (i - 1) * 10, 250, 7, value + 1);}requestAnimationFrame(draw);}

进度条

进度条算是比较简单好做的了,我们用一个背景div填充,另外一个div表示当前进度,宽度是动态变化的,根据音频播放的当前时间除以总时间,然后乘背景div的宽度,计算得到结果即可。

var bglen = document.getElementById('bgline').offsetWidth;var fillbar = document.getElementById('fillbar');fillbar.style.width = parseFloat(cur / duration) * bglen + 'px';

滚动歌词

歌词这一块,首先要找好思路,如何解析歌词?如何控制歌词滚动?如何判断当前是哪句歌词?弄清楚这几个问题后,事情就变得不困难了。

解析歌词

这一块可能是这部分内容里面最复杂的,需要一些简单的算法,这里用到了递归。

解析前的lrc歌词是这样的:

[ti:不要在我寂寞的时候说爱我] [ar:郑源] [by:] [00:21.57]柔柔的晚风轻轻吹过 [00:25.39]我的心情平静而寂寞 [00:29.96]当我想忘记爱情去勇敢生活 [00:34.11]是谁到我身边唱起了情歌 [01:48.86][00:39.01]当初的爱情勿匆走过 [01:52.69][00:42.79]除了伤口没留下什么 [01:57.27][00:47.40]你总是在我寂寞流泪的时候 [02:01.67][00:51.80]用你的双臂紧紧抱着我 [02:59.75][02:05.19][00:55.27]不要在我寂寞的时候说爱我 [03:04.15][02:09.69][00:59.96]除非你真的能给予我快乐 [03:09.30][02:14.78][01:04.97]那过去的伤总在随时提醒我 [03:13.94][02:19.40][01:09.65]别再被那爱情折磨 [03:17.17][02:22.65][01:12.82]不要在我哭泣的时候说爱我 [03:21.62][02:27.11][01:17.32]除非你真的不让我难过 [03:25.65][02:31.13][01:21.33]我不想听太多那虚假的承诺 [03:30.00][02:35.44][01:25.69]让我为爱再次后悔犯下的错!

解析处理后是这样的:

function getnext(y, lrc) {var rs = '';var i = y + 1;if(lrc[i]) {t = lrc[i].split(']');if(t[1] == '') {rs = getnext(i, lrc);}else {rs = t[1]}}return rs;}

歌词滚动

歌词滚动最简单的一种方法,让包含歌词的盒子的top值不断减少,歌词就会一直往上走。通过当前播放的时间和歌词的时间对个比较,判断当前时间对应的歌词,给对应的dom添加标识。

cur = parseInt(audio.currentTime);min = parseInt(cur / 60);sec = parseInt(cur % 60);sec = sec < 10 ? '0' + sec : sec;curTime.innerHTML = min + ':' + sec;fillbar.style.width = parseFloat(cur / duration) * bglen + 'px';if(lrcTimeArr.indexOf(cur) > -1) {document.querySelectorAll('#lrc li').forEach(function(e) {e.className = '';})document.querySelector('#lrc li[time="'+cur+'"]').className = 'active';lrcEl.style.top = lrcOffsetTop - lrcTimeArr.indexOf(cur) * 16 + 'px';}

写在最后

以上是在音乐播放器以及可视化方面的一些实验。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。