一步一步实战HTML音乐播放器
来源:互联网 发布:大数据工程师面试题 编辑:程序博客网 时间:2024/05/22 02:01
在这里我用HTML5从头开始一步一步来制作一个简约的音乐播放器,大家可以参考一下,接下来正式开始。
音乐播放器效果
播放器分析
这里将播放器分两块来做:
- 视图层(html + css)
- 逻辑层 ( js )
视图层分析
视图中包含:
- 播放器容器
- 播放器名称
- 音乐专辑图
- 音乐信息
- 歌曲名
- 歌手
- 专辑名
- 控制区
- 上一曲
- 播放
- 下一曲
- 播放进度条
- 播放时间
- 当前时间
- 歌曲总时间
- 音频控件
- 页面背景
逻辑层分析
逻辑层处理包括:
- 加载歌单
- 渲染歌曲信息
- 专辑图
- 歌曲名
- 歌手
- 专辑名
- 歌曲时长
- 歌曲音频地址
- 监听控制按钮
- 播放按钮 (修改播放状态)
- 上一曲(判断歌单边界,重新渲染歌曲信息)
- 下一曲(判断歌单边界,重新渲染歌曲信息)
- 定时器
- 同步歌曲当前时间和播放进度条
- 歌曲播放完,自动切换下一曲
好了,播放器基本分析完成,接下来开始编码了,先进行视图层的编写。
视图层结构编写
根据我在上面的视图层分析,来构建HTML结构。
建立index.html
,结构编码如下:
<!-- 页面背景 --><body> <!-- 播放器容器 --> <div class="player"> <!-- 播放器名称 --> <div class="header">音乐播放器</div> <!-- 音乐专辑图 --> <div class="albumPic"></div> <!-- 音乐信息 --> <div class="trackInfo"> <!-- 歌曲名 --> <div class="name"></div> <!-- 歌手 --> <div class="artist"></div> <!-- 专辑名 --> <div class="album"></div> </div> <!-- 播放进度条 --> <div class="progress"></div> <!-- 控制区 --> <div class="controls"> <!-- 播放 --> <div class="play"> <i class="icon-play"></i> </div> <!-- 上一曲 --> <div class="previous"> <i class="icon-previous"></i> </div> <!-- 下一曲 --> <div class="next"> <i class="icon-next"></i> </div> </div> <!-- 播放时间 --> <div class="time"> <!-- 当前时间 --> <div class="current"></div> <!-- 歌曲总时间 --> <div class="total"></div> </div> <!-- 音频控件 --> <audio id="audio"><source src=""></audio> </div></body>
好了,结构编写完毕,接下来编写视图层样式。
视图层样式编写
注:这里我是用LESS写的CSS,后面我会贴出完整代码,或者到 CSDN CODE 下载源码
先重置标记样式:
html, body, div, span, applet, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, u, i, center,dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td,article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;}/* HTML5 display-role reset for older browsers */article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block;}body { line-height: 1;}ol, ul { list-style: none;}blockquote, q { quotes: none;}blockquote:before, blockquote:after,q:before, q:after { content: ''; content: none;}table { border-collapse: collapse; border-spacing: 0;}
设置body
:
//这里主要设置背景和flex布局,用于播放器垂直居中@body-bg: #111;html,body{ height: 100%;}body{ background-color: @body-bg; display: flex; align-items: center; justify-content: center; color: #fff; font: 16px "微软雅黑";}
设置播放器容器 .player
:
//主要设置播放器的大小、背景颜色、定位等信息@player-bg: lighten(@body-bg, 10%);@player-w: 375px;@player-h: 550px;.player{ width: @player-w; height: @player-h; background-color: @player-bg; border-radius: 10px; position: relative;}
设置播放器名称.header
样式:
.player{ .header{ padding: 15px 0; text-align: center; }}
专辑图.albumPic
样式:
.player{ .albumPic{ background-image: url(http://p3.music.126.net/SR9eFEjRB0NsscxN7-fHMw==/3344714372906000.jpg); //这里先放一张临时图片,用于看效果,编写完成后,把这条属性删除即可 background-size: cover; //背景模式 width: @player-w * 0.72; //通过计算设置宽高,可直接用百分比 height: @player-w * 0.72; margin: auto; //居中 border-radius: 10px; }}
专辑信息区域样式:
.player{ .trackInfo{ text-align: center; padding: 20px 0 15px; font-size: 14px; white-space: nowrap; //单独将歌曲名设置一下大小 .name{ font-size: 24px; margin-bottom: 10px; font-weight: bold; } }}
播放进度条样式:
.player{ .progress{ width: 30%; //这里用于看效果,制作完成后,设置为0 height: 20%; position: absolute; //用绝对定位放到播放器容器最下面和最左面 bottom: 0; left: 0; background-image: linear-gradient(top, rgba(255, 255, 255, 0), #0099FF); //背景采用从上到下的线性渐变 border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; opacity: .4; }}
按钮控制区域样式设置:
.player{ .controls{ //位置方面不用再额外设置了,按照对上面的设置,当前控制区的位置正好 position: relative; //播放按钮同样采用flex布局,用于对内部的网络字体按钮垂直居中 .play{ cursor: pointer; width: 75px; height: 75px; border: 2px solid #ccc; border-radius: 50%; //加个圆框 margin: auto; display: flex; align-items:center; justify-content:center; color: #fff; font-size: 35px; &:hover{ font-size: 40px; //鼠标经过变大字体 } } //上、下一曲 共用样式 .btn(){ cursor: pointer; position: absolute; top: 25px; font-size: 30px; &:hover{ font-size: 32px; } } //设置一下按钮位置 .previous{ .btn; left: 60px; } .next{ .btn; right: 60px; } }}
播放时间区域设置:
.player{ .time{ width: @player-w - 40px; //计算pdding后的宽度,可自行计算 display: flex; position: absolute; bottom: 0; padding: 20px; align-items: center; justify-content: space-between; //两端分布 }}
好了,通过上面的样式设置,播放器的视图层已完毕,看下效果(三个播放控制按钮是引用的字体):
接下来开始编写逻辑层。
逻辑层编写
逻辑层用到了Jquery
和歌曲清单数据playlist.js
,先引用一下:
<script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/playlist.js"></script>
playlist.js
就是一堆json
的歌单数据,数据是从网易云音乐上获取的,基本内容如下:
//因为做静态页有跨域问题,所以就直接把数据拿出来赋值给`playlist`这个对象上了,下面只保留了需要用到的数据对象var playlist = { "result": { "tracks": [ { "name": "歌曲名", "artists": [ { "name": "演唱者", } ], "album": { "name": "专辑名", "picUrl":专辑图", "duration": 时长(ms), "mp3Url": "音乐地址" }, ...//等等等 ], },};
网易云音乐歌单json数据接口:
http://music.163.com/api/playlist/detail?id=xxx
建立index.js
,开始编码:
先定义一个播放状态对象playStatus
:
//当前播放器状态var playStatus = { currentTrackLen: playlist.result.tracks.length, //歌单歌曲数 currentTrackIndex: 0, //当前播放的歌曲索引,默认加载第一首歌 currentTime: 0, //当前歌曲播放的时间 currentTotalTime: 0, //当前歌曲的总时间 playStatus: true, //true为播放状态,false为暂停状态};
因为要用到时间的转换,所以编写一个时间转换函数:
var timeConvert = function(timestamp){ var minutes = Math.floor(timestamp / 60); var seconds = Math.floor(timestamp - (minutes * 60)); if(seconds < 10) { seconds = '0' + seconds; } timestamp = minutes + ':' + seconds; return timestamp;};
接下来编写一个对象,内部方法是控制播放器的:
//播放器控制方法对象var playerControls = { //歌曲基本信息设置 trackInfo: function(args){ //playerlist是playlist.js中的歌单数据,根据需求进行数据读取即可 var obj = playlist.result.tracks[playStatus.currentTrackIndex]; args = args || { name:obj.name, artist:obj.artists[0].name, album:obj.album.name, albumPic:obj.album.picUrl + '?param=270y270', total:obj.duration, src: obj.mp3Url, }; $('.player .trackInfo .name').text(args.name); $('.player .trackInfo .artist').text(args.artist); $('.player .trackInfo .album').text(args.album); $('.player .albumPic').css('background','url(' + args.albumPic + ')'); $('.player .time .total').text(timeConvert(args.total / 1000)); //因为歌单数据中的播放长度用ms表示的,所以这里 / 1000 playStatus.currentTotalTime = Math.floor(args.total / 1000); $('#audio source').attr('src',args.src); //切换音乐通过修改<source>中的src }, //播放、暂停状态处理 playStatus: function(){ $('.player .controls .play i').attr('class', 'icon-' + (playStatus.playStatus?'pause':'play')); if(playStatus.playStatus){ //用jquery获取<audio>对象,必须加上[0] $('#audio')[0].play(); }else{ $('#audio')[0].pause(); } }, //当前时间和进度处理 playTime: function(){ $('.player .time .current').text(timeConvert(playStatus.currentTime)); $('.player .progress').css('width', playStatus.currentTime / playStatus.currentTotalTime * 100 + '%'); //同步进度条 }};
还剩下一个初始化方法了:
var init = function(){ //置一下歌曲信息和播放状态 playerControls.trackInfo(); playerControls.playStatus(); //播放按钮事件监听 $('.player .controls .play').click(function(){ //修改播放状态 playStatus.playStatus = !playStatus.playStatus; //置播放信息 playerControls.playStatus(); }); //上一曲按钮事件监听 $('.player .controls .previous').click(function(){ //边界判断 if(playStatus.currentTrackIndex - 1 < 0){ alert('已经没有上一首了'); }else{ playStatus.currentTrackIndex --; } //此处切换歌曲功能,原来打算采用直接修改src的方法实现,但是修改src后,之前播放的音乐还继续播放着,切换后的音乐却不播放,所以最终采用移除<audio>,再加入<audio>的方式来切换音乐 $('#audio').remove(); $('.player').append('<audio id="audio"><source src=""></audio>'); //更新音轨信息和播放状态 playerControls.trackInfo(); playerControls.playStatus(); }); //下一曲按钮事件监听 $('.player .controls .next').click(function(){ if(playStatus.currentTrackIndex + 1 >= playStatus.currentTrackLen){ alert('已经没有下一首了'); }else{ playStatus.currentTrackIndex ++; } //换src的方法没法切换声音,试了好几种方法都不行,只能删了再重建了 $('#audio').remove(); $('.player').append('<audio id="audio"><source src=""></audio>'); playerControls.trackInfo(); playerControls.playStatus(); }); //用时钟来实时修改当前播放时间及播放完当前曲目自动下一曲 setInterval(function(){ playStatus.currentTime = $('#audio')[0].currentTime; playerControls.playTime(); if(playStatus.currentTime >= playStatus.currentTotalTime){ $('.player .controls .next').click(); } }, 300);};
其后,再加入init()
执行一下就OK了。
完整代码
index.html
:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>H5音乐播放器</title> <link rel="stylesheet" type="text/css" href="css/index.css"> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript" src="js/playlist.js"></script> <script type="text/javascript" src="js/index.js"></script></head><body> <div class="player"> <div class="header">音乐播放器</div> <div class="albumPic"></div> <div class="trackInfo"> <div class="name"></div> <div class="artist"></div> <div class="album"></div> </div> <div class="progress"></div> <div class="controls"> <div class="play"> <i class="icon-play"></i> </div> <div class="previous"> <i class="icon-previous"></i> </div> <div class="next"> <i class="icon-next"></i> </div> </div> <div class="time"> <div class="current"></div> <div class="total"></div> </div> <audio id="audio"><source src=""></audio> </div></body></html>
index.css
:
@import 'reset.css';@import 'fonts.css';html,body { height: 100%;}body { background-color: #111111; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; color: #fff; font: 16px "微软雅黑";}.player { width: 375px; height: 550px; background-color: #2b2b2b; border-radius: 10px; position: relative;}.player .header { padding: 15px 0; text-align: center;}.player .albumPic { background-size: cover; width: 270px; height: 270px; margin: auto; border-radius: 10px;}.player .trackInfo { text-align: center; padding: 20px 0 15px; font-size: 14px; white-space: nowrap;}.player .trackInfo .name { font-size: 24px; margin-bottom: 10px; font-weight: bold;}.player .progress { width: 0; height: 20%; position: absolute; bottom: 0; left: 0; background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0), #0099ff); background-image: linear-gradient(top, rgba(255, 255, 255, 0), #0099ff); border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; opacity: .4;}.player .controls { position: relative;}.player .controls .play { cursor: pointer; width: 75px; height: 75px; border: 2px solid #ccc; border-radius: 50%; margin: auto; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; color: #fff; font-size: 35px;}.player .controls .play:hover { font-size: 40px;}.player .controls .previous { cursor: pointer; position: absolute; top: 25px; font-size: 30px; left: 60px;}.player .controls .previous:hover { font-size: 32px;}.player .controls .next { cursor: pointer; position: absolute; top: 25px; font-size: 30px; right: 60px;}.player .controls .next:hover { font-size: 32px;}.player .time { width: 335px; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; position: absolute; bottom: 0; padding: 20px; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: justify; -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between;}
index.js
:
$().ready(function(){ //当前播放器状态 var playStatus = { currentTrackLen: playlist.result.tracks.length, currentTrackIndex: 0, currentTime: 0, currentTotalTime: 0, playStatus: true, }; //播放器控制方法 var playerControls = { //歌曲基本信息 trackInfo: function(args){ var obj = playlist.result.tracks[playStatus.currentTrackIndex]; args = args || { name:obj.name, artist:obj.artists[0].name, album:obj.album.name, albumPic:obj.album.picUrl + '?param=270y270', total:obj.duration, src: obj.mp3Url, }; $('.player .trackInfo .name').text(args.name); $('.player .trackInfo .artist').text(args.artist); $('.player .trackInfo .album').text(args.album); $('.player .albumPic').css('background','url(' + args.albumPic + ')'); $('.player .time .total').text(timeConvert(args.total / 1000)); playStatus.currentTotalTime = Math.floor(args.total / 1000); $('#audio source').attr('src',args.src); }, //播放、暂停状态处理 playStatus: function(){ $('.player .controls .play i').attr('class', 'icon-' + (playStatus.playStatus?'pause':'play')); if(playStatus.playStatus){ $('#audio')[0].play(); }else{ $('#audio')[0].pause(); } }, //当前时间和进度处理 playTime: function(){ $('.player .time .current').text(timeConvert(playStatus.currentTime)); $('.player .progress').css('width', playStatus.currentTime / playStatus.currentTotalTime * 100 + '%'); } }; var timeConvert = function(timestamp){ var minutes = Math.floor(timestamp / 60); var seconds = Math.floor(timestamp - (minutes * 60)); if(seconds < 10) { seconds = '0' + seconds; } timestamp = minutes + ':' + seconds; return timestamp; }; (function(){ playerControls.trackInfo(); playerControls.playStatus(); $('.player .controls .play').click(function(){ playStatus.playStatus = !playStatus.playStatus; playerControls.playStatus(); }); $('.player .controls .previous').click(function(){ if(playStatus.currentTrackIndex - 1 < 0){ alert('已经没有上一首了'); }else{ playStatus.currentTrackIndex --; } $('#audio').remove(); $('.player').append('<audio id="audio"><source src=""></audio>'); playerControls.trackInfo(); playerControls.playStatus(); }); $('.player .controls .next').click(function(){ if(playStatus.currentTrackIndex + 1 >= playStatus.currentTrackLen){ alert('已经没有下一首了'); }else{ playStatus.currentTrackIndex ++; } //换src的方法没法切换声音,试了好几种方法都不行,只能删了再重建了 $('#audio').remove(); $('.player').append('<audio id="audio"><source src=""></audio>'); playerControls.trackInfo(); playerControls.playStatus(); }); setInterval(function(){ playStatus.currentTime = $('#audio')[0].currentTime; playerControls.playTime(); if(playStatus.currentTime >= playStatus.currentTotalTime){ $('.player .controls .next').click(); } }, 300); })();});
代码下载
下载完整源码
博客名称:王乐平博客
博客地址:http://blog.lepingde.com
CSDN博客地址:http://blog.csdn.net/lecepin
- 一步一步实战HTML音乐播放器
- 一步一步实现音乐播放器
- 实战React音乐播放器
- 简单html音乐播放器
- html之音乐播放器
- Flash MX实战精选:音乐播放器
- html页面音乐播放器_embed代码
- 网页背景音乐播放器html代码
- HTML中播放音乐
- HTML中播放音乐
- HTML中播放音乐
- HTML中播放音乐
- HTML 播放音乐
- html播放音乐代码
- HTML5之audio实战,网页音乐播放器开发
- Android Fragment应用实战(音乐播放器界面)
- Android Fragment应用实战(音乐播放器界面)
- Android AIDL技术实战项目-音乐播放器(一)
- 群辉与远程迅雷下载
- 算法之路三:HDU OJ:2017
- 什么是Build Path
- PLSQL 异常处理
- poj 2029 Get Many Persimmon Trees
- 一步一步实战HTML音乐播放器
- “角”与“毛”
- opencv 配置环境变量
- Jmeter 安装配置
- CSS3学习随记1⃣️
- PLSQL 明示Cursor
- 访问tomcat7 java.lang.ClassCastException: org.apache.jasper.el.ELContextImpl
- kafka之五 kafkaAdmin API
- ubuntu14.04设置开机自动挂载硬盘分区-wd