近,我們在教學生使用JavaScript,今天就帶大家開發一款簡單的音樂播放器。首先,最終效果如圖所示:
首先,我們來編寫html界面index.html,代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="css/style.css"/>
<script src="js/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!--播放器-->
<audio id="song" autoplay="autoplay"></audio>
<!--整體結構-->
<div id="boxDiv">
<!--歌詞展示區域-->
<div id="contentDiv">
<!--歌詞顯示-->
<div id="lrcDiv"></div>
<!--上部陰影-->
<span id="bgTopSpan"></span>
<!--下部陰影-->
<span id="bgBottomSpan"></span>
</div>
<!--控制區域-->
<div id="controlDiv">
<!--進度條-->
<div id="progressDiv"></div>
<!--進度條圓點-->
<img id="pointerImg" src="img/audio/progress_pointer@2x.png"/>
<!--播放時間-->
<span id="playTimeSpan">00:00</span>
<!--歌曲標題-->
<span id="titleSpan"></span>
<!--總時間-->
<span id="totalTimeSpan">00:00</span>
<!--按鈕區域-->
<div id="buttonDiv">
<!--上一首按鈕-->
<img id="prevImg" src="img/audio/play_above_song@2x.png"/>
<!--播放暫停按鈕-->
<img id="playOrPauseImg" src="img/audio/play@2x.png"/>
<!--下一首按鈕-->
<img id="nextImg" src="img/audio/play_next_song@2x.png"/>
</div>
</div>
</div>
</body>
</html>
接下來,編寫style.css,代碼如下:
body{
margin: 0px;
background-color: #ccc;
}
#boxDiv{
width: 375px;
height: 568px;
margin: 10px auto;
position: relative;
}
#contentDiv{
width: 375px;
height: 460px;
background-image: url(../img/audio/play_bg@2x.png);
overflow: hidden;
}
#lrcDiv{
margin-top: 260px;
}
#lrcDiv span{
display: block;
line-height: 40px;
text-align: center;
color: white;
font-size: 20px;
}
#bgTopSpan{
position: absolute;
display: block;
width: 375px;
height: 30px;
top: 0px;
background-image: url(../img/audio/play_top_shadow@2x.png);
}
#bgBottomSpan{
top: 430px;
position: absolute;
background-image: url(../img/audio/play_bottom_shadow@2x.png);
display: block;
width: 375px;
height: 30px;
}
#controlDiv{
width: 375px;
height: 180px;
position: relative;
background-color: white;
}
#progressDiv{
background-color: red;
height: 1.5px;
width: 0px;
}
#pointerImg{
width: 18px;
height: 18px;
position: absolute;
top: -8.5px;
left: -3px;
}
#playTimeSpan{
display: block;
position: absolute;
font-size: 14px;
width: 35px;
top: 5px;
left: 5px;
}
#totalTimeSpan{
display: block;
position: absolute;
font-size: 14px;
width: 35px;
top: 5px;
left: 335px;
}
#titleSpan{
display: block;
position: absolute;
height: 30px;
width: 295px;
font-size: 20px;
text-align: center;
left: 40px;
top: 5px;
}
#buttonDiv{
margin-top: 40px;
position: relative;
}
#prevImg{
width: 40px;
height: 40px;
position: absolute;
top: 20px;
left: 60px;
}
#playOrPauseImg{
width: 70px;
height: 70px;
position: absolute;
top: 5px;
left: 152px;
}
#nextImg{
width: 40px;
height: 40px;
position: absolute;
top: 20px;
left: 275px;
}
最后,編寫common.js,代碼如下:
$(function(){
// 歌曲列表
var playList = ["紅日", "狼的誘惑", "漂洋過海來看你"];
// 當前播放的歌曲序號
var currentIndex = 0;
// 播放器的原生對象
var audio = $("#song")[0];
// 播放時間數組
var timeArr = [];
// 歌詞數組
var lrcArr = [];
// 調用播放前設置
setup();
// 播放歌曲
playMusic();
// 播放歌曲
function playMusic(){
// 播放歌曲
audio.play();
// 設置為暫停的圖片
$("#playOrPauseImg").attr("src", "img/audio/pause@2x.png");
}
// 歌曲播放前設置
function setup(){
// 設置播放哪一首歌曲
// img/audio/紅日.mp3
audio.src = "img/audio/" + playList[currentIndex] + ".mp3";
// 設置歌曲的名字
$("#titleSpan").text(playList[currentIndex]);
// 設置歌詞
setLrc();
}
// 設置歌詞
function setLrc(){
// 清空上一首的歌詞
$("#lrcDiv span").remove();
// 清空數組
timeArr = [];
lrcArr = [];
// 加載歌詞文件
$.get("img/audio/" + playList[currentIndex] + ".lrc", {}, function(data){
if(data){
// 按行切割字符串
var arr = data.split("\n");
// 分割歌詞
for (var i = 0; i < arr.length; i++) {
// 分割時間和歌詞
var tempArr = arr[i].split("]");
if (tempArr.length > 1){
// 添加時間和歌詞到數組
timeArr.push(tempArr[0]);
lrcArr.push(tempArr[1]);
}
}
// 顯示歌詞
for (var i = 0; i < lrcArr.length; i++) {
$("#lrcDiv").append("<span>"+lrcArr[i]+"</span>");
}
}
});
}
// 播放暫停事件
$("#playOrPauseImg").click(function(){
// 如果播放器是暫停狀態
if(audio.paused){
// 繼續播放
playMusic();
}else{
// 暫停
audio.pause();
// 變成播放的圖片
$("#playOrPauseImg").attr("src", "img/audio/play@2x.png");
}
});
// 上一首
$("#prevImg").click(function(){
// 如果是第一首,那么跳到最后一首
if(currentIndex == 0){
currentIndex = playList.length - 1;
}else{
currentIndex--;
}
// 播放前設置
setup();
// 播放
playMusic();
});
// 下一首
$("#nextImg").click(function(){
// 如果是最后一首,就跳到第一首
if(currentIndex == playList.length - 1){
currentIndex = 0;
}else{
currentIndex++;
}
// 播放前設置
setup();
// 播放
playMusic();
});
// 監聽播放器播放時間改變事件
audio.addEventListener("timeupdate", function(){
// 當前播放時間
var currentTime = audio.currentTime;
// 總時間
var totalTime = audio.duration;
// 當是數字的時候
if(!isNaN(totalTime)){
// 得到播放時間與總時長的比值
var rate = currentTime / totalTime;
// 設置時間顯示
// 播放時間
$("#playTimeSpan").text(getFormatterDate(currentTime));
// 總時長
$("#totalTimeSpan").text(getFormatterDate(totalTime));
// 設置進度條
$("#progressDiv").css("width", rate * 375 + "px");
// 設置進度圓點
$("#pointerImg").css("left", (375 - 15) * rate - 3 + "px");
// 設置歌詞的顏色和內容的滾動
for (var i = 0; i < timeArr.length - 1; i++) {
if(!isNaN(getTime(timeArr[i]))){
// 當前播放時間大于等于i行的時間,并且小于下一行的時間
if (currentTime >= getTime(timeArr[i]) && currentTime < getTime(timeArr[i+1])){
// 當前行歌詞變紅色
$("#lrcDiv span:eq("+i+")").css("color", "#FF0000");
// 其他行歌詞變白色
$("#lrcDiv span:not(:eq("+i+"))").css("color", "#FFFFFF");
// 當前行歌詞滾動
$("#lrcDiv").stop(false, true).animate({"margin-top": 260 - 40 * i + "px"}, 1000);
}
}
}
}
});
function getTime(timeStr){
// 去掉左邊的[
var arr = timeStr.split("[");
if(arr.length > 1){
// 得到右邊的時間
var str = arr[1];
// 分割分、秒
var tempArr = str.split(":");
// 分
var m = parseInt(tempArr[0]);
// 秒
var s = parseFloat(tempArr[1]);
return m * 60 + s;
}
return 0;
}
// 格式化時間(00:00)
function getFormatterDate(time){
// 分
var m = parseInt(time / 60);
// 秒
var s = parseInt(time % 60);
// 補零
m = m > 9 ? m : "0" + m;
s = s > 9 ? s : "0" + s;
return m + ":" + s;
}
});
圖片和歌曲、歌詞請自行下載,最后,可以運行試試了。是不是很有趣呢?想要學習更多的Java技術開發知識,關注“重慶千鋒”獲取更多的視頻教程,千鋒重慶IT培訓機構還提供兩周免費試聽課程,歡迎各位小伙伴申請試聽。
天前端學習分享
播放器的音樂通過豆瓣FM的API獲取到的
我們可以隨機的聽到豆瓣FM任何音樂
DEMO
http://book.jirengu.com/jirengu-inc/jrg-vip8/members/Zegendary/大設計/simple%20music%20player/Random%20music%20player/Random-music.html
html+js源代碼
https://github.com/Zegendary/Garbage/blob/master/大設計/simple%20music%20player/Random%20music%20player/Random-music.html
css源代碼
https://github.com/Zegendary/Garbage/blob/master/大設計/simple%20music%20player/Random%20music%20player/musicindex.css
html 代碼
<div class="wrapper">
<!-- 背景圖片 -->
<div class="background"></div>
<div class="content">
<audio src=""></audio>
<div class="music-massage">
<p class="musicname"></p>
<p class="musicer"></p>
</div>
<!-- 分享,收藏,喜歡按鈕 -->
<div class="music-icon">
<a class="m-icon m-fenxiang colored" target="new"></a>
<span class="m-icon m-star colored"></span>
<span class="m-icon m-heart colored"></span>
</div>
</div>
<!-- 進度條 -->
<span class="basebar">
<span class="progressbar"></span>
</span>
<div class="controls">
<!-- 音樂播放。換頻道,下一曲按鈕 -->
<div class="play-control">
<span class="m-icon m-play btn1" title="播放/暫停"></span>
<span class="m-icon m-change btn2" title="換頻道"></span>
<span class="m-icon m-next btn3" title="換曲"></span>
</div>
<!-- 循環播放,隨機播放按鈕 -->
<div class="music-control">
<span class="m-icon m-xunhuan colored"></span>
<span class="m-icon m-radom colored"></span>
</div>
</div>
</div>
js部分
一(播放控制)
//播放控制
var myAudio = $("audio")[0];
// 播放/暫停控制
$(".btn1").click(function(){
if (myAudio.paused) {
play()
} else {
pause()
}
});
// 頻道切換
$(".btn2").click(function(){
getChannel();
});
// 播放下一曲音樂
$(".btn3").click(function(){
getmusic();
});
function play(){
myAudio.play();
$('.btn1').removeClass('m-play').addClass('m-pause');
}
function pause(){
myAudio.pause();
$('.btn1').removeClass('m-pause').addClass('m-play');
}
二(ajax獲取豆瓣fm音樂)
//獲取隨機頻道信息
function getChannel(){
$.ajax({
url: 'http://api.jirengu.com/fm/getChannels.php',
dataType: 'json',
Method: 'get',
success: function(response){
var channels = response.channels;
var num = Math.floor(Math.random()*channels.length);
var channelname = channels[num].name;//獲取隨機頻道的名稱
var channelId = channels[num].channel_id;//獲取隨機頻道ID
$('.record').text(channelname);
$('.record').attr('title',channelname);
$('.record').attr('data-id',channelId);//將頻道ID計入data-id中
getmusic();
}
})
}
// 通過ajax獲取歌曲
function getmusic(){
$.ajax({
url: 'http://api.jirengu.com/fm/getSong.php',
dataType: 'json',
Method: 'get',
data:{
'channel': $('.record').attr('data-id')
},
success: function (ret) {
var resource = ret.song[0],
url = resource.url,
bgPic = resource.picture,
sid = resource.sid,//獲取歌詞的參數
ssid = resource.ssid,//獲取歌詞的參數
title = resource.title,
author = resource.artist;
$('audio').attr('src',url);
$('.musicname').text(title);
$('.musicname').attr('title',title)
$('.musicer').text(author);
$('.musicer').attr('title',author)
$(".background").css({
'background':'url('+bgPic+')',
'background-repeat': 'no-repeat',
'background-position': 'center',
'background-size': 'cover',
});
play();//播放
}
})
};
注意
豆瓣可能會限制我們的訪問,在<head>標簽下要添加<meta name="referrer" content="no-referrer">
三(進度條控制)
setInterval(present,500) //每0.5秒計算進度條長度
$(".basebar").mousedown(function(ev){ //拖拽進度條控制進度
var posX = ev.clientX;
var targetLeft = $(this).offset().left;
var percentage = (posX - targetLeft)/400*100;
myAudio.currentTime = myAudio.duration * percentage/100;
});
function present(){
var length = myAudio.currentTime/myAudio.duration*100;
$('.progressbar').width(length+'%');//設置進度條長度
//自動下一曲
if(myAudio.currentTime == myAudio.duration){
getmusic()
}
}
歌詞獲取方式:
http://jirenguapi.applinzi.com/fm/getLyric.php?ssid=4f86&sid=1451876
學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入學習交流群
343599877,我們一起學Web
節概覽:
這一章主要分享兩個東西,分別是進度條和音軌。進度條相對來說比較簡單,于是先講。
這是上一次繪制好的音樂播放器,本節也在它的基礎上進行完善。
對于進度條,它可以實時地展示音樂的進度,相信大家都不陌生。
1.繪制進度條
我們在按鈕區的上面,也就是屏幕底部的區域繪制進度條。
上代碼:
<body> <div id='music' class='music'> <div class='screen'> <i id='music-icon' class="iconfont icon-yinle"></i> <div class='progress'> <div class='time'></div> <div class='bar'></div> </div> </div> <div class='buttons'> <i id='prev' class="iconfont icon-icon"></i> <i id='play' class="iconfont icon-bofanganniu"></i> <i id='pause' class="iconfont icon-zanting" style="display:none"></i> <i id='next' class="iconfont icon-icon1"></i> </div> <span id='info' class='info'></span> </div> </body>
代碼中progress的部分就是我們需要添加的進度條區域。
給它寬度、高度和背景色:
.music .screen .progress { width:100%; height:40px; background:#ccc; }
我們希望讓它緊挨著播放器屏幕的底部,只需要給它一個定位就行了。關于元素的定位,在之前的章節中我已經詳細地講過,所以在這里就不再贅述了。
position: absolute; bottom:0;
下來了。
我們將該區域分為上下兩塊
.music .screen .progress .time { border-bottom:1px solid #fff; /*演示用,為了看清楚上下元素塊的界限*/ height:20px; /*高度為父盒子的一半*/ line-height:20px; /*為了讓文字垂直居中*/ text-align: right; /*文字右對齊*/ }
加上一個測試的時間數據:
<div class='time'>1:30</div>
確認沒問題后,把背景色和邊框都去掉。同時調色和優化一下:
.music .screen .progress { width:100%; height:40px; position: absolute; bottom:0; } .music .screen .progress .time { color: #fff; height:20px; line-height:20px; /*為了讓時間垂直居中*/ text-align: right; /*文字右對齊*/ padding-right: 10px; }
這樣就好看多了吧。
2.動態獲取變化的時間
一步一步來,接下來我們先拿到正在播放的時間:
/** * 當音頻時間正常更新的時候 */ musicBox.musicDom.ontimeupdate = function(){ var currentTime = Math.floor(this.currentTime); //獲取當前時間 var m = parseInt(currentTime / 60);//分鐘 var s = parseInt(currentTime % 60);//秒鐘 var time = (m<10?("0"+m):m)+":"+(s<10?("0"+s):s); //格式化 console.log(time); //打印出來看看 }
ontimeupdate你可以理解為一個監聽事件,每次時間更新的時候,就會自動進入里面的邏輯。
在圖中可以很清晰地看到,我們已經能拿到正在播放的時間了。
接下來,我們將這個動態變化的時間在屏幕上顯示出來。
document.getElementsByClassName('time')[0].innerHTML = time;
嗯,這樣就行了。
2.計算百分比
// 百分比 = 當前時長 ÷ 總時長 × 100% var total = this.duration;//總時長 console.log(currentTime + '=======' + total); document.getElementsByClassName('time')[0].innerHTML = Math.floor(currentTime / total * 100) + "%";
有了百分比,進度條其實也就有了。我們現在將bar的樣式加上,寬度默認0%
.music .screen .progress .bar { height:20px; background: #eee; width:0%; opacity: 0.6; }
然后動態改變寬度:
var total = this.duration; document.getElementsByClassName('bar')[0].style.width = Math.floor(currentTime / total * 100) + "%";
成功了,進度條就這么產生了。其中最關鍵的一點就是audio標簽元素自帶的ontimeupdate 事件,我們可以在里面獲取總時長和當前時長,然后就可以計算出百分比,通過給div動態設置寬度來實現進度條的效果。
考慮到篇幅,我本章就不單獨封裝插件了,將進度條集成到我們的musicBox里面,還需要用到回調函數等一系列的知識點。
1. 繪制音軌盒子
<div id='music' class='music'> <div id='trackBox' class="trackBox"></div> <div class='screen'> <i id='music-icon' class="iconfont icon-yinle"></i> <div class='progress'> <div class='time'></div> <div class='bar'></div> </div> </div> <div class='buttons'> <i id='prev' class="iconfont icon-icon"></i> <i id='play' class="iconfont icon-bofanganniu"></i> <i id='pause' class="iconfont icon-zanting" style="display:none"></i> <i id='next' class="iconfont icon-icon1"></i> </div> <span id='info' class='info'></span> </div>
為了方便定位,我們將 trackBox 畫在music盒子里面。
.trackBox { position:absolute; width:400px; height:220px; border: 1px solid #ccc; z-index: 3; background: #333; left:210px; top : -2px; border-radius: 6px; }
2. 畫第一條音軌
<div id='trackBox' class="trackBox"> <i class='items'></i> </div> .trackBox .items { position: absolute; width:10px; height:100px; background:#eee; }
我們希望音軌靠著下方,并且它們之間能有一個區分,于是添加這兩個屬性:
bottom:0px; border: 1px solid #ccc;
OK,下來了。
2. 畫所有的音軌
一個音軌肯定不夠,我們需要根據音軌盒子的寬度和每一條音軌的寬度,來計算出一共需要多少條音軌:
/*獲取音軌盒子*/ var trackBox = utils.dom('#trackBox'); /*音軌盒子的寬度*/ var maxWidth = trackBox.clientWidth; /*音軌的單個寬度*/ var singleWidth = 10; /*計算音軌的最大數量*/ var len = Math.floor(maxWidth / singleWidth) ; alert('音軌盒子最多盛放' + len + '條音軌');
//拼接音軌 var tracks = ""; for(var i = 0;i < len; i++){ /*計算位置*/ var left = 10 * i + 'px'; tracks += "<i class='items' style='left:"+left+"'></i>"; } trackBox.innerHTML = tracks;
拼接后的效果:
2. 通過隨機數讓音軌動起來
之前的章節 js常用方法和一些封裝(2) -- 隨機數生成 中,正好有一個隨機數的方法,所謂養兵千日,用兵一時啊。
我們把那個隨機數的方法添加到工具包:
util.js
randomNum : function (num){ return Math.floor(Math.random()*(num+1)); }
測試:
//模擬音軌動畫 setInterval(function(){ for(var i = 0;i < len; i++){ console.info(i); document.getElementsByClassName('items')[i].style.height = utils.randomNum(110) + 'px'; } },200);
效果:
原理就是用了一個js定時器,每隔200毫秒就改變所有音軌的高度,當然,高度是一個隨機數值。
至于音軌和播放器的對接,雖然我已經寫好,并且已經集成到musicBox里面,但是里面牽扯到比較多的知識點,寫起來需要很多時間,所以暫且先放一放吧。
音樂播放器至此算是完成了一個1.0版本,以后看情況我會繼續將這個案例更新下去,甚至還可能對接后臺,連數據庫等等。
在工作的日子里,我曾經迷茫過,尤其是剛開始做編程的工作時,非常迷茫。
每天都是增刪改查,增刪改查,就覺得很沒意思。
一段時間下來,我開始迷茫了,不知道自己該學一些什么東西。
感覺技術太多,什么都想學,卻又怕沒時間。
在這個信息爆炸、日新月異的時代,技術更新得非常快,很多人都在各種新技術的浪潮下變得不知所措。我就有這樣的體會,于是看各種書,各種視頻,生怕自己跟不上時代的節奏。
可是,我一直以來都忽略了一個重點,那就是——我是否真的對這個行業感興趣?
如果在幾年前,我會說是的,正因為對計算機的興趣,我才會放棄之前所學的專業,踏入 Java 、JavaScript 的坑中。
再后來,我發現一個道理,不論你現在的工作是什么,都請盡可能地去愛上他。不要為了生計而去做一份工作,如果實在辦不到的話,就給自己撒一個美麗的謊言吧。
不然的話,軟件開發到了后期你會很迷茫的。
給自己一個溫馨的微笑,學著熱愛這個行業,這個工作,就是對自己最大的獎賞。
享受編程的樂趣,懷著感恩的心去體會每一天生活中的細節。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。