做一個網易云音樂可視化工具

前言

最近在Github上看到了一個音樂可視化前端庫:vudio.js https://github.com/alex2wong/vudio.js

效果有點炫酷:



本人是非常喜歡將音頻可視化的效果听系,聯想到之前的網易云地址解析API钉疫,決定將兩者結合绘闷,做個簡單的網易云音樂可視化小工具节值。

今天將制作過程記錄一下璧瞬。

以下是演示效果:
https://static.cdnjs.cloud/2020104_box/6f27a474b6a546c71ea3b6951a16e813_2020-10-04-16-55-23.mp4_2020-10-04-16-55-23.mp4

除此之外嗅绸,我也將它推送到了Gitee Page上,你可以通過以下地址體驗(受限于網易云地址解析API断国,無法播放VIP音樂贤姆,有點遺憾):
https://txb582.gitee.io/%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90%E5%8F%AF%E8%A7%86%E5%8C%96/index.html

思路

大體思路是:
1、可視化工具獲取用戶輸入的網易云分享鏈接稳衬。
2霞捡、調用解析API將分享地址解析為音樂真實地址實現播放。
3薄疚、調用vudio.js將音樂可視化碧信。
解析API和可視化庫都準備好了,主要的開發(fā)工作就只有可視化工具頁面的開發(fā)
在該工具中街夭,用到了以下東西:

  • axios網絡請求庫
  • 網易云地址解析API
  • 音頻可視化庫vudio.js

開發(fā)

1砰碴、建立常用的目錄結構

2、頁面結構

頁面主要分為兩大塊
1板丽、可視化動畫區(qū)域
2呈枉、懸浮于右側的可收拉菜單



頁面布局代碼

<body id="body">
    <div id="box-show">
    </div>
    <div id="box-menu">
    </div>
</body>

然后在可視化區(qū)域添加
<audio>和<canvas>元素,用于音樂的播放和可視化動畫的繪制檐什。

<body id="body">
    <div id="box-show">
        <audio id="audio" src=""></audio>
        <canvas id="canvas">
            你的瀏覽器不支持Canvas
        </canvas>
    </div>
    <div id="box-menu">
    </div>
</body>

在菜單中添加
兩個<div>用于放置收放按鈕和菜單主體

<body id="body">
    <div id="box-show">
        <audio id="audio" src=""></audio>
        <canvas id="canvas">
            你的瀏覽器不支持Canvas
        </canvas>
    </div>
    <div id="box-menu">
        <div id="box-menu-pull">
        </div>
        <div id="box-menu-list">
        </div>
    </div>
</body>

在按鈕區(qū)域放置一個<button>作為菜單收放按鈕
在菜單主體區(qū)域放置
<img>用于顯示關照二維碼
<span>用于顯示提示
兩個用div包裹起來的<input>實現搜索欄
還有兩個嵌套的<div>用于顯示播放的歷史記錄碴卧,用兩個<div>嵌套是因為后續(xù)為了不讓滾動條影響頁面美觀,使用嵌套的方式通過位移來隱藏滾動條乃正。

<body id="body">
    <div id="box-show">
        <audio id="audio" src=""></audio>
        <canvas id="canvas">
            你的瀏覽器不支持Canvas
        </canvas>
    </div>
    <div id="box-menu">
        <div id="box-menu-pull">
            <button>></button>
        </div>
        <div id="box-menu-list">
            <img src="./images/微信公眾號二維碼.jpg">
            <span> 掃碼關注我們 | MF工作室 </span>
            <div>
                <input id="search-input" type="text" placeholder="網易云音樂鏈接">
                <input id="search-button" type="button" value="GO">
            </div>
            <div>
                <div id="box-menu-list-historical"></div>
            </div>
        </div>
    </div>
</body>

然后引入必要的文件

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>網易云音樂可視化工具 | MF工作室</title>
    <link rel="shortcut icon" href="./images/logo.ico" type="image/x-icon">
    <meta http-equiv="Access-Control-Allow-Origin" content="viapi.cn/wyy">
    <link rel="stylesheet" href="./css/index.css">
    <script src="./js/vudio.js"></script>
    <script src="./js/axios.min.js"></script>
    <script src="./js/index.js"></script>
</head>

3、頁面樣式

/* 清空所有邊距并禁止用戶復制選擇頁面內容 */
* {
    margin: 0px;
    border: 0px;
    padding: 0px;
    user-select: none;
    box-sizing: border-box;
}
/* 將html,body 設置與窗口一致, 方便高度使用百分比 */
html, body {
    width: 100%;
    height: 100%;
}
/* 設置頁面背景漸變, 如果你想, 也可以用圖片替代 */
body {
    background-image: linear-gradient(#f28fb2, #6cbffd);
    background-repeat: no-repeat;
    background-size: cover;
}
/* 可視化區(qū)域設置為充滿body元素 */
#box-show {
    width: 100%;
    height: 100%;
    display: flex;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
#box-show>canvas {
    max-width: 100%;
}
#box-show>audio {
    display: none;
}
/* 將菜單設置為絕對定位, 固定在頁面右側 */
#box-menu {
    width: 350px;
    height: 100%;
    position: fixed;
    top: 0px;
    right: 0px;
    opacity: 0.6;
    transition: right 0.5s;
    display: flex;
}
/* 收拉按鈕區(qū)域使用flex布局, 建按鈕居中顯示 */
#box-menu-pull {
    width: 50px;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}
/* 設置收拉按鈕樣式 */
#box-menu-pull>button {
    width: 50px;
    height: 50px;
    font-size: 30px;
    border-radius: 50% 0% 0% 50%;
    outline: none;
    background-color: rgba(142, 194, 243, 0.8);
    color: #FFFFFF;
}
/* 使用flex布局, 將菜單主體中的內容垂直居中顯示 */
#box-menu-list {
    width: 300px;
    height: 100%;
    padding-top: 20px;
    padding-bottom: 20px;
    margin-bottom: 20px;
    background-color: rgba(142, 194, 243, 0.8);
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow-y: auto;
}
/* 公眾號二維碼樣式 */
#box-menu-list>img {
    width: 85%;
    border: 5px solid rgba(151, 199, 231, 0.8);
    border-radius: 10px;
}
/* 提示語樣式 */
#box-menu-list>span:nth-of-type(1) {
    color: #ffffff;
}
/* 搜索欄樣式 */
#box-menu-list>div:nth-of-type(1) {
    width: 90%;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 10px;
    border-radius: 5px;
}
/* 搜索欄輸入框樣式 */
#search-input {
    height: 100%;
    width: calc(100% - 40px);
    background-color: rgba(151, 199, 231, 0.8);
    outline: none;
    padding-left: 5px;
    padding-right: 5px;
    color: #FFFFFF;
}
#search-input::-webkit-input-placeholder { color: #FFFFFF; }
#search-input::-moz-placeholder { color: #FFFFFF; }
#search-input:-moz-placeholder { color: #FFFFFF; }
#search-input:-ms-input-placeholder { color: #FFFFFF; }
/* 搜索欄提交按鈕樣式 */
#search-button {
    width: 40px;
    height: 100%;
    background-color: rgba(151, 199, 231, 0.8);
    outline: none;
    border-left: 1px solid #c8d5dd;
    color: #FFFF;
}
/* 歷史播放記錄顯示區(qū)域樣式 */
#box-menu-list>div:nth-of-type(2) {
    width: 100%;
    height: 55%;
    overflow: hidden;
}
#box-menu-list-historical{
    width: 100%;
    height: 100%;
    overflow: auto;
    /* 相對于正常位置右移15像素, 這樣就可以使用上層元素遮蓋掉滾動條了 */
    position: relative;
    right: -15px;
}
#box-menu-list-historical>button {
    display: block;
    padding: 10px;
    width: 95%;
    border-radius: 5px;
    margin-top: 10px;
    color: #FFFFFF;
    background-color: rgba(151, 199, 231, 0.8);
    position: relative;
    right: 15px;
    outline: none;
}

4婶博、頁面邏輯

window.onload = function () {
    var menu = document.getElementById("box-menu");
    var menu_pull_button = document.querySelector("#box-menu-pull > button");
    var box_menu_list_historical = document.getElementById("box-menu-list-historical");
    var audio_object = document.getElementById("audio");
    // 允許跨域讀取音頻, 如果不設置, 在調用API時瀏覽器會因為同源策略阻止音樂拉取
    audio_object.crossOrigin = "anonymous";
    var canvas_object = document.getElementById("canvas");
    var search_button = document.getElementById("search-button");
    var search_input = document.getElementById("search-input");
    // 側邊菜單點擊 拉出/隱藏
    var is_pull = true;
    menu_pull_button.onclick = function () {
        if (is_pull) {
            menu.style.right = "-300px";
            menu_pull_button.innerText = "<";
            is_pull = false;
        } else {
            menu.style.right = "0px";
            menu_pull_button.innerText = ">";
            is_pull = true;
        }
    }
    // 提交按鈕點擊處理
    search_button.onclick = function () {
        // 從網易云分享鏈接中提取音樂ID
        source_music_url = search_input.value;
        source_musid_id = ((source_music_url.split("?")[1]).split("&")[0]).split("=")[1];
        // 調用API解析音樂真實地址, API具體使用方法參考: https://api.565.ink/docs#/Lan%E5%B7%A5%E5%85%B7%E7%AE%B1/wangyiyunmc_163mc_get
        axios.get(`https://api.565.ink/163mc?id=${source_musid_id}`).then(function (response) {
            console.log(response.data);
            music_url = response.data["resulturl"];
            audio_object.setAttribute("src", music_url);
            audio_object.play();
            // 向菜單列表插入歷史播放記錄按鈕
            let button = document.createElement("button");
            button.setAttribute("data-music-url", response.data["resulturl"]);
            button.innerText = source_musid_id;
            button.onclick = function () {
                audio_object.setAttribute("src", this.getAttribute("data-music-url"));
                audio_object.play();
            }
            box_menu_list_historical.appendChild(button)
        })
    }
    // 音頻可視化, 具體使用方法參考: https://github.com/alex2wong/vudio
    var vudio = new Vudio(audio_object, canvas_object, {
        effect: 'circlebar',
        accuracy: 128, 
        width: 400,
        height: 400, 
        waveform: {
            maxHeight: 80,
            minHeight: 1,
            spacing: 1,
            shadowBlur: 0, 
            fadeSide: true, 
            horizontalAlign: 'center', 
            verticalAlign: 'middle' 
        }
    });
    vudio.dance();
}

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末瓮具,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子凡人,更是在濱河造成了極大的恐慌名党,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挠轴,死亡現場離奇詭異传睹,居然都是意外死亡,警方通過查閱死者的電腦和手機岸晦,發(fā)現死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門欧啤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睛藻,“玉大人,你說我怎么就攤上這事邢隧〉暧。” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵倒慧,是天一觀的道長按摘。 經常有香客問我,道長纫谅,這世上最難降的妖魔是什么炫贤? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮付秕,結果婚禮上照激,老公的妹妹穿的比我還像新娘。我一直安慰自己盹牧,他們只是感情好俩垃,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汰寓,像睡著了一般口柳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上有滑,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天跃闹,我揣著相機與錄音,去河邊找鬼毛好。 笑死望艺,一個胖子當著我的面吹牛,可吹牛的內容都是我干的肌访。 我是一名探鬼主播找默,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吼驶!你這毒婦竟也來了惩激?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蟹演,失蹤者是張志新(化名)和其女友劉穎风钻,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體酒请,經...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡骡技,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了羞反。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片布朦。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡囤萤,死狀恐怖,靈堂內的尸體忽然破棺而出喝滞,到底是詐尸還是另有隱情阁将,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布右遭,位于F島的核電站做盅,受9級特大地震影響,放射性物質發(fā)生泄漏窘哈。R本人自食惡果不足惜吹榴,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望滚婉。 院中可真熱鬧图筹,春花似錦、人聲如沸让腹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骇窍。三九已至瓜晤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腹纳,已是汗流浹背痢掠。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嘲恍,地道東北人足画。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像佃牛,于是被迫代替她去往敵國和親淹辞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355