实战教程:如何用JavaScript构建一个功能强大的音乐播放器,兼容本地与在线资源

项目地址:Music Player App

作者:Reza Mehdikhanlou

视频地址:youtube

我将向您展示如何使用 javascript 编写音乐播放器。我们创建一个项目,您可以使用 javascript 从本地文件夹或任何 url 播放音频文件。

项目目录

  • assets
    • 1.jpg
    • 1.mp3
    • 2.jpg
    • 2.mp3
    • 3.jpg
    • 3.mp3
  • index.html
  • index.js
  • style.css

代码

index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"><link rel="stylesheet" href="style.css"><title>Music Player App</title>
</head><body><div class="background"><img src="" id="bg-img"></div><div class="container"><div class="player-img"><img src="" class="active" id="cover"></div><h2 id="music-title"></h2><h3 id="music-artist"></h3><div class="player-progress" id="player-progress"><div class="progress" id="progress"></div><div class="music-duration"><span id="current-time">0:00</span><span id="duration">0:00</span></div></div><div class="player-controls"><i class="fa-solid fa-backward" title="Previous" id="prev"></i><i class="fa-solid fa-play play-button" title="Play" id="play"></i><i class="fa-solid fa-forward" title="Next" id="next"></i></div></div><script src="index.js"></script>
</body></html>

index.js

const image = document.getElementById('cover'),title = document.getElementById('music-title'),artist = document.getElementById('music-artist'),currentTimeEl = document.getElementById('current-time'),durationEl = document.getElementById('duration'),progress = document.getElementById('progress'),playerProgress = document.getElementById('player-progress'),prevBtn = document.getElementById('prev'),nextBtn = document.getElementById('next'),playBtn = document.getElementById('play'),background = document.getElementById('bg-img');const music = new Audio();const songs = [{path: 'assets/1.mp3',// path:'https://childish.oss-cn-hangzhou.aliyuncs.com/songs/Peel%20Back%20the%20Heart.mp3'displayName: 'The Charmer\'s Call',cover: 'assets/1.jpg',artist: 'Hanu Dixit',},{path: 'assets/2.mp3',displayName: 'You Will Never See Me Coming',cover: 'assets/2.jpg',artist: 'NEFFEX',},{path: 'assets/3.mp3',displayName: 'Intellect',cover: 'assets/3.jpg',artist: 'Yung Logos',}
];let musicIndex = 0;
let isPlaying = false;function togglePlay() {if (isPlaying) {pauseMusic();} else {playMusic();}
}function playMusic() {isPlaying = true;// Change play button iconplayBtn.classList.replace('fa-play', 'fa-pause');// Set button hover titleplayBtn.setAttribute('title', 'Pause');music.play();
}function pauseMusic() {isPlaying = false;// Change pause button iconplayBtn.classList.replace('fa-pause', 'fa-play');// Set button hover titleplayBtn.setAttribute('title', 'Play');music.pause();
}function loadMusic(song) {music.src = song.path;title.textContent = song.displayName;artist.textContent = song.artist;image.src = song.cover;background.src = song.cover;
}function changeMusic(direction) {musicIndex = (musicIndex + direction + songs.length) % songs.length;loadMusic(songs[musicIndex]);playMusic();
}function updateProgressBar() {const { duration, currentTime } = music;const progressPercent = (currentTime / duration) * 100;progress.style.width = `${progressPercent}%`;const formatTime = (time) => String(Math.floor(time)).padStart(2, '0');durationEl.textContent = `${formatTime(duration / 60)}:${formatTime(duration % 60)}`;currentTimeEl.textContent = `${formatTime(currentTime / 60)}:${formatTime(currentTime % 60)}`;
}function setProgressBar(e) {const width = playerProgress.clientWidth;const clickX = e.offsetX;music.currentTime = (clickX / width) * music.duration;
}playBtn.addEventListener('click', togglePlay);
prevBtn.addEventListener('click', () => changeMusic(-1));
nextBtn.addEventListener('click', () => changeMusic(1));
music.addEventListener('ended', () => changeMusic(1));
music.addEventListener('timeupdate', updateProgressBar);
playerProgress.addEventListener('click', setProgressBar);loadMusic(songs[musicIndex]);

style.css

@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap');html{box-sizing: border-box;
}body{margin: 0;font-family: 'Ubuntu', sans-serif;font-size: 12px;min-height: 100vh;display: flex;align-items: center;justify-content: center;
}.background{position: fixed;width: 200%;height: 200%;top: -50%;left: -50%;z-index: -1;
}.background img{position: absolute;margin: auto;top: 0;left: 0;bottom: 0;right: 0;min-width: 50%;min-height: 50%;filter: blur(15px);-webkit-filter: blur(50px);transform: scale(1.1);
}.container{background-color: #e7e7e7;height: 500px;width: 400px;border-radius: 20px;box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);transition: all 0.5s ease;
}.container:hover{box-shadow: 0 15px 30px rgba(0, 0, 0, 0.6);
}.player-img{width: 300px;height: 300px;position: relative;top: -50px;left: 50px;
}.player-img img{object-fit: cover;border-radius: 20px;height: 0;width: 0;opacity: 0;box-shadow: 0 5px 30px 5px rgba(0, 0, 0, 0.5);
}.player-img:hover img{box-shadow: 0 5px 30px 5px rgba(0, 0, 0, 0.8);
}.player-img img.active{width: 100%;height: 100%;transition: all 0.5s;opacity: 1;
}h2{font-size: 25px;text-align: center;font-weight: 500;margin: 10px 0 0;
}h3{font-size: 18px;text-align: center;font-weight: 500;margin: 10px 0 0;
}.player-progress{background-color: #fff;border-radius: 5px;cursor: pointer;margin: 40px 20px 35px;height: 6px;width: 90%;
}.progress{background-color: #212121;border-radius: 5px;height: 100%;width: 0%;transition: width 0.1s linear;
}.music-duration{position: relative;top: -25px;display: flex;justify-content: space-between;
}.player-controls{position: relative;top: -15px;left: 120px;width: 200px;
}.fa-solid{font-size: 30px;color: #666;margin-right: 30px;cursor: pointer;user-select: none;transition: all 0.3s ease;
}.fa-solid:hover{filter: brightness(40%);
}.play-button{font-size: 44px;position: relative;top: 3px;
}

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

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

相关文章

顶级10大AI测试工具

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

JWT入门

JWT与TOKEN JWT&#xff08;JSON Web Token&#xff09;是一种基于 JSON 格式的轻量级安全令牌&#xff0c;通常用于在网络应用间安全地传递信息。而“token”一词则是一个更广泛的术语&#xff0c;用来指代任何形式的令牌&#xff0c;用于在计算机系统中进行身份验证或授权。J…

【️讲解下Laravel为什么会成为最优雅的PHP框架?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

cloudreve 设置开机服务

创建一个Systemd服务文件&#xff1a; 打开终端并创建一个新的服务文件&#xff1a; sudo nano /etc/systemd/system/cloudreve.service 在服务文件中添加以下内容&#xff1a; 根据你的设置调整路径和参数&#xff0c;然后将以下配置粘贴到文件中&#xff1a; [Unit] Descri…

Django学习第四天

启动项目命令 python manage.py runserver 分页功能封装到类中去 封装的类的代码 """ 自定义的分页组件,以后如果想要使用这个分页组件&#xff0c;你需要做&#xff1a; def pretty_list(request):# 靓号列表data_dict {}search_data request.GET.get(q, &…

Excel为数据绘制拆线图,并将均值线叠加在图上,以及整个过程的区域录屏python脚本

Excel为数据绘制拆线图,并将均值线叠加在图上,以及整个过程的区域录屏python脚本 1.演示动画A.视频B.gif动画 2.跟踪鼠标区域的录屏脚本 Excel中有一组数据,希望画出曲线,并且能把均值线也绘制在图上,以下动画演示了整个过程,并且提供了区域录屏脚本,原理如下: 为节约空间,避免…

从华为和特斯拉之争,看智能驾驶的未来

“一旦特斯拉完全解决自动驾驶问题并量产Optimus&#xff0c;任何空头都将被消灭&#xff0c;即使是比尔-盖茨也不例外。”7月2日&#xff0c;马斯克再次在社交媒体X上画下了这样的“大饼”。 与此同时&#xff0c;特斯拉的股价在最近的三个交易日也迎来了24%的涨幅&#xff0c…

中俄汽车产业链合作前景广阔,东方经济论坛助力双边合作与创新

随着中国汽车零部件企业的竞争力和创新能力不断增强&#xff0c;中国汽车及零部件行业在俄罗斯的市场份额和品牌影响力显著提升&#xff0c;中俄两国在汽车产业链上的合作展现出巨大的潜力和广阔的前景。2024年5月&#xff0c;俄罗斯乘用车新车销量达到12.8万辆&#xff0c;同比…

7.基于SpringBoot的SSMP整合案例-表现层开发

目录 1.基于Restfu1进行表现层接口开发 1.1创建功能类 1.2基于Restful制作表现层接口 2.接收参数 2使用Apifox测试表现层接口功能 保存接口&#xff1a; 分页接口&#xff1a; 3.表现层一致性处理 3.1先创建一个工具类&#xff0c;用作后端返回格式统一类&#xff1a;…

SpringMVC 的工作流程和详细解释

Spring MVC&#xff08;Model-View-Controller&#xff09;框架是基于经典的 MVC 设计模式构建的&#xff0c;用于开发 Web 应用程序。下面是 Spring Boot MVC 的工作流程和详细解释&#xff1a; 1.客户端发起请求 1.客户端&#xff08;通常是浏览器&#xff09;发起 HTTP 请求…

Python学习篇:Python基础知识(三)

目录 1 Python保留字 2 注释 3 行与缩进 ​编辑4 多行语句 5 输入和输出 6 变量 7 数据类型 8 类型转换 9 表达式 10 运算符 1 Python保留字 Python保留字&#xff08;也称为关键字&#xff09;是Python编程语言中预定义的、具有特殊含义的标识符。这些保留字不能用作…

代码随想录算法训练营第70天图论9[1]

代码随想录算法训练营第70天:图论9 ‍ 拓扑排序精讲 卡码网&#xff1a;117. 软件构建(opens new window) 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的…

5款软件让电脑更方便,更快,更好看

​ 你有没有想过&#xff0c;有些软件能让你的电脑用起来更方便&#xff0c;更快&#xff0c;更好看&#xff1f; 1. 屏幕动画创作——Screen To Gif ​ Screen To Gif是一款功能强大的屏幕录制软件&#xff0c;专注于将屏幕上的动态内容转换为高质量的GIF动画。它不仅支持自…

《ClipCap》论文笔记(下)

原文出处 [2111.09734] ClipCap: CLIP Prefix for Image Captioning (arxiv.org) 原文翻译 接上篇 《ClipCap》论文笔记&#xff08;上&#xff09;-CSDN博客 4. Results Datasets.我们使用 COCO-captions [7,22]、nocaps [1] 和 Conceptual Captions [33] 数据集。我们根…

自动化设备上位机设计 一

目录 一 设计原型 二 后台代码 一 设计原型 二 后台代码 namespace 自动化上位机设计 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){}} }namespace 自动化上位机设计 {partial class Fo…

Pyqt5中如何让label里面的图片进行更换,避免出现黑图

在Pyqt5的界面开发过程中&#xff0c;发现一个label的图片怎么都添加不上&#xff0c;而且出现黑色&#xff0c;主要原因就是在进行显示的时候需要加一行清除的代码&#xff1a; label.clear()如果不加这行代码&#xff0c;当里面的图片发生变化时&#xff0c;显示出来的就是黑…

miniprogram-to-uniapp-微信小程序转换成uniapp项目

文章目录 参考:miniprogram-to-uniapp使用指南第一步第二步第三步第四步【miniprogram-to-uniapp】转换微信小程序”项目为uni-app项目(新版本工具已经支持各种小程序转换) 参考: 小程序技能树 uni-app基础知识总结 miniprogram-to-uniapp使用指南 第一步 win + R 输入…

Openwrt路由器部分ipv6公网地址无法访问的问题

路由器是Openwrt&#xff0c;终端访问ipv6地址经常有些能访问&#xff0c;有些不能访问&#xff0c;一开始以为是运营商问题&#xff0c;后面ssh到openwrt发现所有访问都正常。 查阅资料后才知道是MTU设置问题&#xff0c;Openwrt 默认MTU是1492&#xff0c;使用IPV6应减少60个…

微信小程序遮罩层显示

效果展示&#xff1a; wxml页面&#xff1a; <view classmodal-mask wx:if{{showModal}}><view class"modal-container"><view classmodal-content></view><view classmodal-footer bindtap"closeImage">//这个/images/ind…

Nettyの网络聊天室扩展序列化算法

1、网络聊天室综合案例 客户端初始代码&#xff1a; Slf4j public class ChatClient {public static void main(String[] args) {NioEventLoopGroup group new NioEventLoopGroup();LoggingHandler LOGGING_HANDLER new LoggingHandler(LogLevel.DEBUG);MessageCodecSharabl…