一步一步实战HTML音乐播放器
在這里我用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%; //這里用于看效果,制作完成后,設置為0height: 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表示的,所以這里 / 1000playStatus.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音乐播放器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 神经网络:全连接神经网络
- 下一篇: 易语言 精易WEB浏览器拦截并且显示验证