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日

相关文章

  • css hover对其包含的子元素进行样式设置示例

    当我们在网页设计中使用CSS样式时,使用:hover伪类来为鼠标移动到元素上时设置一些特殊的样式是很有用的。这个功能可以很方便地对网站的交互性和美观性进行调整和完善。接下来,我会详细讲解如何使用CSS设置:hover的样式,以及如何对其包含的子元素进行样式设置。下面是示例: 改变父元素及其子元素样式 首先,我们准备一个HTML文档: <div clas…

    css 2023年6月10日
    00
  • css 半透明 让IE6支持png图片半透明解决方法

    下面详细讲解“css半透明让IE6支持png图片半透明解决方法”的完整攻略。 一、问题描述 PNG(Portable Network Graphics)格式是一种支持透明度的图像格式,我们可以将PNG图形文件作为页面的背景或图片等元素来使用。但是在IE6下,它并不完美支持PNG图片的透明效果。为了让IE6也能支持PNG图片透明度,我们需要通过以下两种解决方案…

    css 2023年6月10日
    00
  • CSS3中伪元素::before和::after的用法示例

    CSS3 中的伪元素 ::before 和 ::after 是非常有用的,它们可以让我们在元素的前面或后面插入内容,而无需修改 HTML 代码。本文将详细讲解 ::before 和 ::after 的用法示例,以及如何使用它们来实现一些常见的效果。 ::before 和 ::after 的用法 ::before 和 ::after 是 CSS3 中新增的伪元…

    css 2023年5月18日
    00
  • 清除css、javascript及背景图在浏览器中缓存的简单方法

    清除浏览器缓存可以避免一些样式和脚本的更新问题,以下是清除css、javascript及背景图在浏览器中缓存的简单方法攻略。 手动清除浏览器缓存 手动清除浏览器缓存是最基本的操作方式,以下是详细步骤: 打开浏览器,进入设置界面,找到“历史记录”或“隐私设置”选项。 点击“清除浏览数据”或“删除浏览历史”,勾选“缓存图片和文件”、“cookies和其他网站数据…

    css 2023年6月9日
    00
  • 谈谈对css属性box-sizing的了解

    关于 CSS 属性 box-sizing,我来给你详细讲解一下。 什么是 box-sizing? CSS 属性 box-sizing 是用来设置盒模型的计算方式。如果采用默认的 content-box,那么盒模型的宽度是由 border、padding 和 content 的宽度共同决定的;而如果设置为 border-box,那么盒模型的宽度就由 borde…

    css 2023年6月9日
    00
  • 学习CSS的背景图像属性background

    CSS中的背景图像属性 在CSS中,我们可以使用background属性来设置一个元素的背景。通过设置background属性的不同参数,我们可以对背景进行更精细的控制。其中一个非常重要的参数就是背景图像属性background-image。 背景图像属性background-image的使用方法 通过使用background-image,我们可以指定元素的…

    css 2023年6月9日
    00
  • 使用CSS+JavaScript或纯js实现半透明遮罩效果的实例分享

    我来为您详细讲解使用CSS+JavaScript或纯js实现半透明遮罩效果的实例分享的完整攻略。 一、使用CSS实现半透明遮罩效果 CSS中实现半透明黑色遮罩的方法如下: .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.…

    css 2023年6月10日
    00
  • 纯CSS流星雨背景的示例代码

    下面是纯CSS流星雨背景的完整攻略,包含示例代码和示例说明。 1. 纯CSS流星雨背景的示例代码 以下是纯CSS流星雨背景的示例代码: <!DOCTYPE html> <html> <head> <title>CSS Meteor Rain Background</title> <style&…

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