【前端】-音乐播放器(源代码和结构讲解,大家可以将自己喜欢的歌曲添加到数据当中,js实现页面动态显示音乐)

news2024/10/7 0:52:44

前言:音乐播放器是前端开发中的一个经典项目,通过它可以掌握很多核心技术,如音频处理、DOM操作、事件监听、动画效果等。这个项目不仅能提升前端开发的技能,还能让开发者深入理解JavaScript与HTML的协同作用。

页面展示:

歌曲页面+列表(html代码):

音乐

 

 下面有详细的注释讲解,大家可以对照着上图中的结构进行理解,当然也可以自己写,大家了解我的思路就行

  <div class="wrapper">
    <div class="player-warp">
      <!-- 歌曲信息卡片(隐藏页面) -->
      <div class="player-info">
        <div class="info">
          <div class="name">
            <h4>我记得</h4>
          </div>
          <div class="singer-album">赵雷-署前街少年</div>
          <div class="music-progress">
            <!-- 时间显示 -->
            <div class="music-progress-top">
              <!-- 当前时间 -->
              <span class="current-time">00:00</span>
               <!-- 歌曲总时间 -->
              <span class="time">05:29</span>
            </div>
            <!-- 音乐进度线 -->
            <div class="music-progress-bar">
              <!-- 绘制播放线 -->
              <div class="music-progress-line"></div>
            </div>
          </div>
        </div>
      </div>
      <!-- 歌曲控制页面 -->
      <div class="player-control">
        <div class="cover">
          <img src="" alt="">
        </div>
        <!-- 控制按钮 -->
        <div class="control">
          <i id="prevBtn" class="iconfont">&#xe844;</i>
          <i id="playBtn" class="iconfont paused">&#xe848;</i>
          <i id="nextBtn" class="iconfont">&#xe845;</i>
          <i id="openModal" class="iconfont">&#xe8bf;</i>
        </div>
      </div>
    </div>
  </div>
  <!-- 设置音乐背景页面 -->
  <div class="bg"></div>
  <!-- 绘制歌曲列表 -->
  <div class="modal">
    <div class="modal-box">
       <!-- 设置模块头部内容 -->
      <div class="modal-box-top">
        <div class="modal-title">
          <h3>音乐列表</h3>
        </div>
        <div class="modal-close">
          <!-- 放置让模块消失的图标 -->
          <i class="iconfont">&#xe8b9;</i>
        </div>
      </div>
      <div class="modal-wrapper">
        <!-- 容器 -->
        <ul class="song-list">
        </ul>
      </div>
    </div>
  </div>
  <!-- 音乐-->
  <audio src=""></audio>
  <script src="./js/jquery.js"></script>

 页面功能介绍:

1.点击播放按钮,音乐开始播放,歌曲信息将自然弹出,页面中的圆形图片开始旋转

2.点击前进和后退按钮,音乐和页面信息将进行相应改变

3.点击模块列表内容,可播放该音乐

js功能实现:

 家人们我是通过jQuery实现的

 1.使用ajax请求音乐数据

通过ajax请求数据,并且调用更新页面数据的函数,在页面中显示第一个歌曲, 添加音乐列表

    let musicList = [];
    let currentIndex = 0;  // 当前播放音乐的下标
    // Ajax 获取音乐数据
    $.ajax({
      type: "GET",
      url: "./music.json",
      success: function (data) {
        musicList = data;
        render(musicList[currentIndex]);  // 渲染当前音乐
        renderMusicList(musicList);       // 渲染音乐列表
      }
    });
 2.页面渲染信息函数:

 获得jQuery包装级对象包装级对象,并且通过text()方法,在对象中添加数据

    // 渲染音乐详情
    function render(data) {
      $(".name h4").text(data.name);
      $(".time").text(data.time);
      $(".singer-album").text(`${data.singer} - ${data.album}`);
      $(".cover img").attr("src", data.cover);
      $("audio").attr("src", data.audio_url);
      $('.bg').css({
        background: `url("${data.cover}") no-repeat center center`,
        "background-size": "cover"
      });
    }
3.播放和暂停音乐:

 设置点击播放按钮,将暂停按钮变成播放按钮,并且显示歌曲信息,大家可以通过上面视频了解


    // 绑定播放按钮事件
    $("#playBtn").on("click", togglePlay);    

    // 播放与暂停音乐
    function togglePlay() {
      //返回dom对象
      let audio = $("audio").get(0);
      if (audio.paused) {
        $("#playBtn").removeClass("paused").addClass("running").html('&#xe847;');
        $(".player-info").animate({ top: '-95%' }, 'slow');
        $(".cover").css({ "animation-play-state": "running" });
        audio.play();
      } else {
        $("#playBtn").removeClass("running").addClass("paused").html('&#xe848;');
        $(".player-info").animate({ top: '0%' }, 'slow');
        $(".cover").css({ "animation-play-state": "paused" });
        audio.pause();
      }
    }
4.渲染音乐列表:

通过js动态添加歌曲列表 

    // 渲染音乐列表
    function renderMusicList(list) {
      $(".song-list").empty();
      $.each(list, function (index, item) {
        let isPlaying = (index == currentIndex && !$("audio").get(0).paused);
        let $li = $(`
      <li id="${index}" class="${index == currentIndex ? 'playing' : ''}">
        <span>${index + 1}.${item.name} - ${item.singer}</span> 
        <span class="iconfont">${isPlaying ? '&#xe784;' : '&#xe781;'}</span>
      </li>
    `);
        $(".song-list").append($li);
      });
    }
5.更新播放函数:

这个方法会被重复利用,所以封装起来 ,更新当前音乐信息,更新列表

    // 更新并播放音乐
    function updateAndPlay() {
      render(musicList[currentIndex]);
      $("#playBtn").trigger("click");  
      renderMusicList(musicList);    
    }
6.上下按钮点击事件:

点击前进和后退按钮更换歌曲事件,通过currentIndex变化更换当前歌词(因为当前歌词是通过currentIndex下标进行控制的) 

    // 绑定上一首、下一首按钮事件
    $("#prevBtn").on("click", playPrev);
    // 播放上一首音乐
    function playPrev() {
      currentIndex = (currentIndex > 0) ? currentIndex - 1 : musicList.length - 1;
      updateAndPlay();
    }
    $("#nextBtn").on("click", playNext);
    // 播放下一首音乐
    function playNext() {
      currentIndex = (currentIndex < musicList.length - 1) ? currentIndex + 1 : 0;
      updateAndPlay();
    }
7.更新音乐条的进度:

根据当前音乐的时间,获得值的百分比赋值给进度表的宽度 

    // 格式化时间
    function formatTime(time) {
      let min = Math.floor(time / 60);
      let sec = Math.floor(time % 60);
      return `${min < 10 ? '0' : ''}${min}:${sec < 10 ? '0' : ''}${sec}`;
    }
    // 更新播放时间和进度条
    $("audio").on("timeupdate", function () {
      let audio = $("audio").get(0);
      let currentTime = audio.currentTime || 0;
      let duration = audio.duration || 0;

      $(".current-time").text(formatTime(currentTime));
      $(".time").text(formatTime(duration));

      let value = (currentTime / duration) * 100;
      $(".music-progress-line").css({ width: value + "%" });
    });
8.显示模块列表:

点击两个小图标点开音乐列表和关闭音乐列表 

    // 打开和关闭音乐列表弹窗
    $("#openModal").on("click", function () {
      $(".modal").css({ display: "block" });
      renderMusicList(musicList);  // 渲染音乐列表
    });
    $(".modal-close").on("click", function () {
      $(".modal").css({ display: "none" });
    });
9.点击音乐列表播放音乐事件:

 点击列表相应歌曲播放点击歌曲

 
    // 点击音乐列表播放对应歌曲
    $(".song-list").on("click", "li", function () {
      currentIndex = parseInt($(this).attr("id"));
      updateAndPlay();  // 播放选择的音乐
    });
10.音乐结束事件:

这个我设置的是 playNext ()  播放下一个歌曲,大家还可以自己进行其他操作

    // 监听音乐播放完毕的事件,自动播放下一首
    $("audio").on("ended", function () {
      playNext();
    });

源代码:

上面HTML代码和JavaScript代码都是完整的,大家可以直接取上面的

CSS:
* {
  margin: 0;
  padding: 0;
}

body {
  user-select: none;
  background-color: #dadada;
}

/* 动画 */
@keyframes circle {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.wrapper {
  width: 360px;
  height: 80px;
  margin: auto;
  margin-top: 200px;
}

.player-warp {
  position: relative;
}

.player-info {
  width: 90%;
  height: 100%;
  position: absolute;
  /* top: -95%; */
  top: 0;
  left: 5%;
  z-index: -1;
  background-color: rgba(255, 255, 255, 0.15);
  box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
  backdrop-filter: blur(3.5px);
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.17);
  display: flex;
  justify-content: flex-end;
}

.player-info .info {
  padding: 5px;
  width: 60%;
  font-size: 15px;
}

/* 进度条%比 */
.info .music-progress {
  width: 100%;
}

.music-progress .music-progress-top {
  display: flex;
  color: #ff668c;
  justify-content: space-between;
}

/* 绘制歌曲进程背景 */
.music-progress .music-progress-bar {
  width: 100%;
  height: 3px;
  background-color: #b8b8b8;
  border-radius: 10px;
  margin-top: 3px;
}

/* 绘制覆盖线 */
.music-progress .music-progress-line {
  width: 0%;
  height: 90%;
  background-color: #ff5a94;
}

.player-warp .player-control {
  width: 360px;
  height: 80px;
  background-color: #ffffff;
  border-radius: 15px;
  display: flex;
  z-index: 10;
}

.player-control .cover {
  position: relative;
  /* margin-left: 20px; */
  left: 30px;
  width: 104px;
  height: 100px;
  border-radius: 50px;
  background-color: #ffffff;
  margin-top: -60px;
  animation: circle 5s infinite linear;
  animation-play-state: paused;
}

.player-control img {
  position: absolute;
  top: 5%;
  left: 5%;
  width: 90%;
  height: 90px;
  border-radius: 50%;
}

.player-control .cover::before {
  content: "";
  display: inline-block;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #fff;
}

.player-control .control {
  margin-left: 20px;
  width: 70%;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.player-control .control i {
  display: block;
  color: #b05757;
  font-size: 45px;
  margin-right: 6px;
  cursor: pointer;
  transition: all 0.4s;
}

.control i:hover {
  color: #e2a3a3 !important;
}

.bg {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  background: url("http://p2.music.126.net/34YW1QtKxJ_3YnX9ZzKhzw==/2946691234868155.jpg") no-repeat center center;
  transform: scale(2);
  /* 模糊 */
  filter: blur(50px);
  transition: all 1s;
}

li {
  list-style: none;
}

.modal {
  width: 100%;
  height: 100%;
  background-color: rgba(128, 128, 128, 0.25);
  /* 设置固定定位 */
  position: fixed;
  top: 0;
  right: 0;
  display: none;
}

.modal .modal-box {
  width: 30%;
  height: 100%;
  background-color: #fff;
  position: absolute;
  top: 0;
  right: 0;
  padding: 5px;
}

.modal-box .modal-close .iconfont {
  font-size: 23px;
}

.modal-box .modal-box-top {
  width: 100%;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 5px;
}

.modal-box .modal-wrapper li {
  cursor: pointer;
  display: block;
  height: 30px;
  line-height: 30px;
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
  background-color: rgba(230, 230, 230, 0.37);
  border-bottom: 1px solid rgb(83, 83, 83);
}

.modal-box .modal-wrapper li span {
  display: block;
  font-size: 18px;
}

.modal-box .modal-wrapper li .iconfont {
  font-size: 28px;
}

.modal-box .modal-wrapper li .iconfont:hover {
  font-size: 30px;
}

.playing span {
  color: #00ddc3;
}
music.json:

[

  {

    "name": "勇敢爱",

    "audio_url": "./audios/Mi2 - 勇敢爱 [mqms2].mp3",

    "singer": "Mi2",

    "album": "吴少华",

    "cover": "./img/7.png",

    "time": "04:16"

  },

  {

    "name": "一人饮酒醉(柔情版)",

    "audio_url": "./audios/程嘉敏 - 一人饮酒醉 (柔情版) [mqms].mp3",

    "singer": "程嘉敏",

    "album": "吴少华",

    "cover": "./img/1.png",

    "time": "01:20"

  },

  {

    "name": "明月天涯",

    "audio_url": "./audios/等什么君 - 明月天涯 [mqms2].mp3",

    "singer": "等什么君",

    "album": "吴少华",

    "cover": "./img/2.png",

    "time": "04:14"

  },

  {

    "name": "生僻字",

    "audio_url": "./audios/陈柯宇 - 生僻字.mp3",

    "singer": "陈柯宇",

    "album": "吴少华",

    "cover": "./img/3.png",

    "time": "03:36"

  },

  {

    "name": "依存症",

    "audio_url": "./audios/东京塔子 - 依存症 [mqms2].mp3",

    "singer": "东京塔子",

    "album": "吴少华",

    "cover": "./img/4.png",

    "time": "04:39"

  },

  {

    "name": "恶魔的爱",

    "audio_url": "./audios/李宏毅&李明霖 - 恶魔的爱 [mqms2].mp3",

    "singer": "李宏毅&李明霖",

    "album": "吴少华",

    "cover": "./img/5.png",

    "time": "04:12"

  },

  {

    "name": "梦回还",

    "audio_url": "./audios/呦猫UNEKO - 梦回还 [mqms2].mp3",

    "singer": "呦猫UNEKO",

    "album": "吴少华",

    "cover": "./img/6.png",

    "time": "04:10"

  },

  {

    "name": "当归",

    "audio_url": "./audios/宿雨涵 - 当归.ogg",

    "singer": "宿雨涵",

    "album": "吴少华",

    "cover": "./img/8.png",

    "time": "03:54"

  },

  {

    "name": "时光笔墨",

    "audio_url": "./audios/张碧晨 - 时光笔墨.ogg",

    "singer": "张碧晨",

    "album": "吴少华",

    "cover": "./img/9.png",

    "time": "05:01"

  },

  {

    "name": "勾指起誓",

    "audio_url": "./audios/泠鸢yousa - 勾指起誓.ogg",

    "singer": "泠鸢yousa",

    "album": "吴少华",

    "cover": "./img/10.png",

    "time": "03:03"

  },

  {

    "name": "散仙如烟",

    "audio_url": "./audios/醋醋 - 散仙如烟.ogg",

    "singer": "醋醋",

    "album": "吴少华",

    "cover": "./img/11.png",

    "time": "03:43"

  },

  {

    "name": "爱情女神",

    "audio_url": "./audios/郭美美 - 爱情女神.ogg",

    "singer": "郭美美",

    "album": "吴少华",

    "cover": "./img/12.png",

    "time": "03:36"

  }

]

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2193296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

精准选择大模型:消费品行业的营销与体验创新之路

在消费品行业&#xff0c;大模型技术的引入正逐渐从一个新兴趋势转变为行业标配。随着人工智能的快速发展&#xff0c;特别是OpenAI等领军企业推出的创新技术&#xff0c;如Sora&#xff0c;大模型在市场营销、消费者行为分析、个性化推荐等方面展现出巨大潜力。然而&#xff0…

基础算法(5)——位运算

1. 常见位运算总结 1) 基础位运算 2) 给一个数 n&#xff0c;确定它的二进制表示中的第 x 位是 0 还是 1 3) 将一个数 n 的二进制表示的第 x 位修改成 1 4) 将一个数 n 的二进制表示的第 x 位修改成 0 5) 位图的思想 位图的本质就是 哈希表 6) 提取一个数 n 二进制表示中最右…

如 有 任 何 问 题 ,请 及 时 联 系 我 们 反 馈 !

如有任何问题&#xff0c; 请及时联系我们反馈 !https://support.qq.com/products/671606 如有任何问题&#xff0c; 请及时联系我们反馈 !

Bluetooth Channel Sounding中关于CS Procedure的详细介绍

目录 BLE CS 过程定义&#xff1a; BLE CS 过程的组成部分 开始一个BLE CS 过程 与BLE CS过程相关的参数设置 BLE CS 过程定义&#xff1a; BLE 的CS特性包含一组LL层和空口协议的组合过程&#xff0c;该过程可以使得两个BLE 设备以紧密互锁的方式&#xff0c;在多个信道上…

Ubuntu 上安装 MySQL 并且实现远程登录

目录 1. 安装MySQL 2. 安全配置MySQL 3. 配置MySQL远程登录 3.1. 允许远程连接 3.2. 重启MySQL服务 3.3. 为用户分配远程访问权限 进入MySQL后&#xff0c;执行以下命令&#xff1a; 3.4. 创建新用户 3.5. 授予权限 3.6. 刷新权限 3.7. 退出 MySQL 控制台 4. 配置防火…

2024.9月29日~10月6日 SSM框架项目-《电信资费管理系统》

一、数据库介绍&#xff1a; 1、account&#xff1a;帐务信息表 2、admin_info&#xff1a;管理员信息表 3、admin_role&#xff1a;管理员角色信息表 4、cost&#xff1a;资费信息表 5、privilege_info&#xff1a;权限信息表 6、role_info&#xff1a;角色信息表 7、role_pri…

在CentOS7上安装mysql

目录 1.下载安装文件 2.上传到CentOS7上 3.解压MySQL文件 4.清理系统中残留的MySQL 5.安装MySQL 6.启动MySQL 并 设置开机自启动 7.查找临时密码&#xff0c;并修改密码 注意&#xff1a; 教程&#xff1a;在Linux上安装mysql&#xff08;超详细版&#xff09;_哔哩哔哩…

人工智能新闻和发展 (24001)- By 10/4/2024

1. 谷歌增强了搜索中的人工智能&#xff0c;允许对图像进行语音提问。 Google adding AI to answer voiced questions about images | AP NewsGoogle is pumping more artificial intelligence into its search engine. New features will enable people to voice questions a…

[C#]使用onnxruntime部署yolov11-onnx实例分割模型

【官方框架地址】 https://github.com/ultralytics/ultralytics.git 【算法介绍】 在C#中使用ONNX Runtime部署YOLOv11-ONNX实例分割模型&#xff0c;涉及到模型的加载、数据预处理、模型推理和后处理几个关键步骤。 首先&#xff0c;需要确保已经安装了ONNX Runtime的NuGe…

【数据结构】【链表代码】随机链表的复制

/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/typedef struct Node Node; struct Node* copyRandomList(struct Node* head) {if(headNULL)return NULL;//1.拷贝结点&#xff0c;连接到原结点的后面Node…

[Linux] 进程创建、退出和等待

标题&#xff1a;[Linux] 进程创建、退出和等待 个人主页水墨不写bug &#xff08;图片来源于AI&#xff09; 目录 一、进程创建fork&#xff08;&#xff09; 1&#xff09; fork的返回值&#xff1a; 2&#xff09;写时拷贝 ​编辑3&#xff09;fork常规用法 4&#xff…

目标侦测划分数据集代码--->voc

代码如下&#xff1a; import glob import os import random import shutil # 划分比例 p3/4#训练集 xmlpathE:\\shujuji\\MASK\\Annotations\\* imgpathE:\\shujuji\\MASK\\JPEGImages\\* xmlpathsglob.glob(xmlpath) imgpathsglob.glob(imgpath) my_list[i for i in range(l…

MATLAB图像去雾系统

应用背景 现在工业发展迅速&#xff0c;产生的废气很严重&#xff0c;导致雾霾厉害&#xff0c;现在虽然有硬件来拍摄&#xff0c;可以清晰化视野&#xff0c;但是硬件成本昂贵&#xff0c;急需寻求一种算法来帮助雾霾的清晰处理。显得经济。 采用算法原理 本文采用全局直方…

走进异常类的世界,自定义业务异常类实现指南

接下来这篇文章&#xff0c;小编将带领大家走进异常类的世界&#xff0c;探索异常类的奥秘。 引言 学习Java异常类&#xff0c;需掌握其基础概念&#xff0c;如try-catch语句、throw与throws关键字。通过实例理解异常层次结构&#xff0c;区分已检查与未检查异常。实践编写自定…

springboot文件上传(阿里云oss)

本地存储 使用uuid是为了避免文件名的重复&#xff0c;防止覆盖 RestController public class FIleUploadController {PostMapping("/upload")public Result<String> upload(MultipartFile file) throws IOException {//把文件的内容存储到本地磁盘上String …

基于SpringBoot+Vue的在线投票系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

C++的STL标准模版库容器--list类

前言 list(双向链表)类属于STL标准模版库容器模块&#xff0c;它的迭代器是双向迭代器&#xff0c;也比较好理解&#xff0c;它申请空间不是一次申请一块空间而是每一个节点各自独立的空间&#xff0c;它不再能够支持随机访问和[]&#xff0c;如果想要和string类容器或者vecto…

集合源码1

一、List接口分析 1、list接口的特点 ①List集合的所有元素是由一种线性方式进行存储的。 ②它是一个元素存储有序的集合。即元素的存入顺序和取出顺序有保证。 ③他是一个带有索引的集合&#xff0c;通过索引就可以精确的操作集合中的元素 ④集合中可以有重复的元素&#xff0…

二分查找算法——寻找旋转排序数组中的最小值点名

1.题目解析 题目来源&#xff1a;LCR173.点名——力扣 原名&#xff1a;剑指offer——0~n-1中消失的数字 测试用例 题目来源&#xff1a;153.寻找旋转排序数组中的最小值——力扣 测试用例 2.算法原理 点名 如果要寻找消失的数字&#xff0c;可以判断对应下标的数字是否和下标对…

视觉定位Revisit Anything

Revisit Anything: Visual Place Recognition via Image Segment Retrieval 项目地址 摘要&#xff1a; 准确识别重游地点对于嵌入代理的定位和导航至关重要。这要求视觉表现清晰&#xff0c;尽管摄像机视点和场景外观有很大变化。现有的视觉地点识别管道对“整个”图像进行编码…