HTML5使用Audio标签实现歌词同步的效果

下面是详细的攻略说明。

什么是HTML5的Audio标签?

HTML5的Audio标签是一种用于在网页上播放音频的标签。它可以加载并播放MP3、WAV等音频格式文件。除了简单的播放控制外,它还支持许多高级特性,例如事件处理、音乐可视化和歌词同步等。

实现歌词同步的原理

在实现歌词同步的过程中,我们需要先将歌词文件加载到网页中,并把每一行的歌词内容和对应的时间信息保存下来。然后我们需要监听音频播放的事件,根据当前音频播放的时间,找到对应的歌词并将其高亮显示出来。

具体地,我们可以使用timeupdate事件来监听音频播放时间的更新。每次事件触发时,我们需要根据当前的播放时间,找到对应的歌词并将其高亮显示出来。代码示例如下:

<audio id="myAudio" src="song.mp3"></audio>

<div id="lyrics">
  <p data-time="0">歌词第一行</p>
  <p data-time="10">歌词第二行</p>
  <p data-time="20">歌词第三行</p>
  <!-- 其他歌词行 -->
</div>

<script>
  var audio = document.getElementById('myAudio');
  var lyricsElement = document.getElementById('lyrics');
  var lyrics = lyricsElement.getElementsByTagName('p');
  var currentLyricIndex = -1;

  audio.addEventListener('timeupdate', function() {
    var currentTime = audio.currentTime;

    // 找到歌词所在行
    for (var i = lyrics.length - 1; i >= 0; i--) {
      if (lyrics[i].getAttribute('data-time') <= currentTime) {
        currentLyricIndex = i;
        break;
      }
    }

    // 高亮显示歌词
    for (var i = 0; i < lyrics.length; i++) {
      if (i === currentLyricIndex) {
        lyrics[i].classList.add('active');
      } else {
        lyrics[i].classList.remove('active');
      }
    }
  });
</script>

示例一:歌词滚动实现

除了高亮显示当前歌词外,我们还可以实现歌词滚动的效果,让用户更方便地看到当前唱到了哪一句歌词。具体实现方法是在当前歌词的基础上,再找到前后一句歌词以及它们所对应的时间,然后根据当前播放时间和这三个时间的差值来计算出歌词应该滚动的距离。代码示例如下:

<audio id="myAudio" src="song.mp3"></audio>

<div id="lyrics">
  <p data-time="0">歌词第一行</p>
  <p data-time="10">歌词第二行</p>
  <p data-time="20">歌词第三行</p>
  <!-- 其他歌词行 -->
</div>

<script>
  var audio = document.getElementById('myAudio');
  var lyricsElement = document.getElementById('lyrics');
  var lyrics = lyricsElement.getElementsByTagName('p');
  var currentLyricIndex = -1;

  audio.addEventListener('timeupdate', function() {
    var currentTime = audio.currentTime;

    // 找到当前歌词和前后一句歌词,以及它们所对应的时间
    var currentLyric = null;
    var previousLyric = null;
    var nextLyric = null;
    var currentLyricTime = 0;
    var previousLyricTime = 0;
    var nextLyricTime = Number.MAX_VALUE;
    for (var i = lyrics.length - 1; i >= 0; i--) {
      var lyricTime = parseFloat(lyrics[i].getAttribute('data-time'));
      if (lyricTime <= currentTime) {
        currentLyric = lyrics[i];
        currentLyricTime = lyricTime;
        break;
      } else {
        nextLyric = lyrics[i];
        nextLyricTime = lyricTime;
      }
    }
    for (var i = 0; i < lyrics.length; i++) {
      var lyricTime = parseFloat(lyrics[i].getAttribute('data-time'));
      if (lyricTime < currentLyricTime && lyricTime > previousLyricTime) {
        previousLyric = lyrics[i];
        previousLyricTime = lyricTime;
      }
      if (lyricTime > currentLyricTime && lyricTime < nextLyricTime) {
        nextLyric = lyrics[i];
        nextLyricTime = lyricTime;
      }
    }

    // 高亮显示当前歌词
    for (var i = 0; i < lyrics.length; i++) {
      if (i === currentLyricIndex) {
        lyrics[i].classList.add('active');
      } else {
        lyrics[i].classList.remove('active');
      }
    }

    // 计算歌词滚动的距离
    if (currentLyric) {
      var scrollDistance = 0;
      var lineHeight = parseFloat(getComputedStyle(currentLyric).lineHeight);
      var currentLineTop = currentLyric.offsetTop - lyricsElement.offsetTop;
      var previousLineTop = previousLyric ? previousLyric.offsetTop - lyricsElement.offsetTop : currentLineTop - lineHeight;
      var nextLineTop = nextLyric ? nextLyric.offsetTop - lyricsElement.offsetTop : currentLineTop + lineHeight;
      var currentLineTime = currentLyricTime;
      var previousLineTime = previousLyricTime ? previousLyricTime : currentLyricTime - 1;
      var nextLineTime = nextLyricTime;
      var progress = (currentTime - currentLineTime) / (nextLineTime - currentLineTime);
      scrollDistance = (nextLineTop - currentLineTop) * progress + currentLineTop - lyricsElement.offsetHeight / 2 + lineHeight / 2;

      lyricsElement.scrollTop = scrollDistance;
    }
  });
</script>

示例二:根据歌曲进度显示歌词

除了根据音频的播放时间来显示歌词,我们还可以根据歌曲的进度来显示歌词。具体实现方法是在加载歌曲时,计算出每个歌词所对应的时间点,并将其保存在一个数组中。然后在歌曲播放的过程中,根据当前的进度找到对应的歌词并显示出来。代码示例如下:

<audio id="myAudio" src="song.mp3"></audio>

<div id="lyrics">
  <!-- 歌词行 -->
</div>

<script>
  var audio = document.getElementById('myAudio');
  var lyricsElement = document.getElementById('lyrics');
  var lyrics = lyricsElement.getElementsByTagName('p');
  var lyricTimes = [];
  var currentLyricIndex = -1;

  // 加载歌词并计算每个歌词所对应的时间点
  function loadLyrics(lyricsUrl) {
    fetch(lyricsUrl)
      .then(function(response) {
        return response.text();
      })
      .then(function(text) {
        var lines = text.split('\n');
        for (var i = 0; i < lines.length; i++) {
          var match = lines[i].match(/^\[(\d+):(\d+\.\d+)\](.*)$/);
          if (match) {
            var minutes = parseInt(match[1]);
            var seconds = parseFloat(match[2]);
            var time = minutes * 60 + seconds;
            var content = match[3];
            lyricsElement.innerHTML += '<p data-time="' + time + '">' + content + '</p>';
            lyricTimes.push(time);
          }
        }
      });
  }

  // 在歌曲播放的过程中,根据当前的进度找到对应的歌词并显示出来
  audio.addEventListener('timeupdate', function() {
    var currentTime = audio.currentTime;
    for (var i = 0; i < lyricTimes.length; i++) {
      if (lyricTimes[i] > currentTime) {
        if (currentLyricIndex !== i - 1) {
          for (var j = 0; j < lyrics.length; j++) {
            if (j === i - 1) {
              lyrics[j].classList.add('active');
            } else {
              lyrics[j].classList.remove('active');
            }
          }
          currentLyricIndex = i - 1;
          break;
        }
      }
    }
  });

  // 加载歌曲和歌词
  loadLyrics('song.lrc');
</script>

以上是使用HTML5的Audio标签实现歌词同步的完整攻略。在实际开发中,我们可以根据需要进行修改和优化,以达到更好的效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:HTML5使用Audio标签实现歌词同步的效果 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • 基于Bootstrap+jQuery.validate实现表单验证

    下面是关于“基于Bootstrap+jQuery.validate实现表单验证”的完整攻略: 操作步骤 第一步:下载Bootstrap和jQuery.validate Bootstrap官网提供了下载地址,你也可以在jQuery.validate的官网上下载该脚本。在下载的文件中,Bootstrap含有css、js等文件,而jQuery.validate只含…

    css 2023年6月11日
    00
  • 网站变黑白灰色的4种代码详细讲解

    讲解一下“网站变黑白灰色的4种代码详细讲解”: 1. CSS filter属性 可以使用 CSS 的 filter 属性轻松实现网站的黑白、灰度效果。该属性允许你使用各种不同的过滤器来修改指定元素的视觉效果。在这里,我们使用 greyscale 过滤器来实现灰度化: filter: grayscale(100%); 其中,grayscale 的参数表示灰度化…

    css 2023年6月9日
    00
  • css选择器四大类:基本、组合、属性、伪类

    CSS选择器四大类:基本、组合、属性、伪类攻略 基本选择器 基本选择器是最简单的选择器,包括四种类型: 1. 元素选择器 元素选择器是指根据元素的标签名称来选择网页中的元素,例如以下代码将选中 HTML 文档中所有的段落元素: p { color: red; } 2. 类选择器 类选择器是通过元素的 class 属性来进行选择(class 选择器以句点 . …

    css 2023年6月9日
    00
  • css关于position属性的用法详解(绝对定位和相对定位的混淆)

    CSS关于position属性的用法详解(绝对定位和相对定位的混淆) position属性的概述 position属性定义了元素的定位方式,其可选值有四种:static,relative,absolute和fixed。 static表示元素的默认定位方式,即元素在文档流中按照其自身的顺序排列 relative表示按照元素自身的偏移量来确定元素在文档流中的位置…

    css 2023年6月9日
    00
  • 设置链接颜色的伪类选择符的顺序为LVHA

    设置链接颜色的伪类选择符的顺序为LVHA,其中L、V、H、A分别代表的是Link、Visited、Hover、Active,即链接的默认状态、已访问状态、鼠标悬停状态、被点击状态。按照这个顺序,可以对链接状态进行不同的样式设置。 下面是设置链接颜色的伪类选择符的完整攻略: 1. 设置默认状态的链接颜色 对于链接的默认状态,使用a:link来进行设置。例如,下…

    css 2023年6月9日
    00
  • CSS3圆角边框和边界图片效果实例

    那么让我们来详细讲解“CSS3圆角边框和边界图片效果实例”的完整攻略。 一、CSS3圆角边框效果 1.1 border-radius属性 border-radius属性是CSS3中新增的一种属性,它可以实现圆角边框的效果。该属性可以设置1到4个参数值,分别表示左上角、右上角、右下角和左下角的半径,如果缺省,则默认为0。 div{ width: 100px; …

    css 2023年6月10日
    00
  • PHP详细彻底学习Smarty

    PHP详细彻底学习Smarty 什么是Smarty Smarty 是一个 PHP 模板引擎,它允许我们将业务逻辑与样式相分离。通过 Smarty,我们可以在 HTML 页面中直接嵌入 PHP 代码。 Smarty 的一个主要功能是变量输出,我们可以从 PHP 脚本中向模板中传递变量,以供模板来渲染。此外,Smarty 还支持复杂的逻辑操作,例如 if-els…

    css 2023年6月9日
    00
  • JavaScript CSS修改学习第六章 拖拽

    在学习JavaScript的CSS修改过程中,拖拽是一个重要的技能,它可以让用户像拖动窗口一样在页面内拖动元素。本章的攻略将会详细介绍如何实现拖拽功能。 原理 拖拽的原理就是通过鼠标事件和CSS属性的改变来实现。具体来说,需要监听以下几个鼠标事件: mousedown:鼠标按下时触发的事件 mousemove:鼠标移动时触发的事件 mouseup:鼠标抬起时…

    css 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部