简述
结构简单,功能简单,支持播放、暂停、播放进度控制。
每个音频单独播放,互不影响,且与控制中心的 Aplayer 相互独立。
如果喜欢该音频,可以点击右侧加号按钮添加至 Aplayer 歌单列表,实现全局播放,同时可使用 Aplayer 的桌面歌词功能。
格式 1 {% music 标题,作者,链接,封面,歌词 %}
【注】参数两端不可使用引号;各参数间以英文逗号为分割,故参数不可携带英文逗号。
预览
音源 我主要使用网易云的音乐资源,在音乐单曲界面按F12可获取封面链接,页面网址则包含了该歌曲的id,而音频链接格式如下:
1 `https://music.163.com/song/media/outer/url?id=${id} .mp3`
除此之外也可以通过 Meting API 获取相关资源。
实现 新建 themes\butterfly\scripts\tag\music.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 'use strict' function music (args ) { args = args.join (' ' ).split (',' ) let title = (args[0 ] || '未知' ).trim () let author = (args[1 ] || '未知' ).trim () let url = (args[2 ] || '' ).trim () let pic = (args[3 ] || '' ).trim () let lrc = (args[4 ] || '' ).trim () return `<center><figure id="mc-${title} " class="music-card"> <div class="player"> <audio class="audio" preload="metadata"></audio> </div> <div class="content"> <div class="mc-progress" onclick="setProgress(event, 'mc-${title} ')"> <div class="mc-progressbar"></div> </div> <div class="cover"> <img src="${pic} "> <div class="play" onclick="ctrl.mcToggleMusic('mc-${title} ', '${url} ')"> <i class="blogfont icon-play-circle"></i> </div> </div> <div class="text-info"> <span class="title">${title} </span> <span class="author">${author} </span> <span class="time">--:-- / --:--</span> </div> <div class="add" onclick="ctrl.addMusicToList('${title} ','${author} ','${url} ','${pic} ','${lrc} ')"> <i class="blogfont icon-add"></i> </div> </div> <script> function mcAddListener(id) { const mc = document.getElementById(id) if (mc) { const mc_audio = mc.querySelector('.audio') const mc_play = mc.querySelector(".play i") let intervalId; mc_audio.addEventListener('play', function() { mc_play.classList.remove("icon-play-circle") mc_play.classList.add("icon-pause-circle") intervalId = setInterval(function() { ctrl.mcRefreshTime(id) }, 500); }) mc_audio.addEventListener('pause', function() { mc_play.classList.remove("icon-pause-circle") mc_play.classList.add("icon-play-circle") clearInterval(intervalId) }) } } function setProgress(e, id) { const mc = document.getElementById(id) if (mc && mc.querySelector(".content").classList.contains("canplay")) { const progressBar = mc.querySelector('.mc-progressbar') const audio = mc.querySelector('.audio') const clickX = e.clientX - mc.getBoundingClientRect().left const width = clickX / mc.offsetWidth progressBar.style.transform = 'translateX(-' + (1 - width) * 100 + '%)' audio.currentTime = width * audio.duration ctrl.mcRefreshTime(id) } } mcAddListener('mc-${title} ') </script> </figure></center>` } hexo.extend .tag .register ('music' , music, { ends : false })
新建 themes\butterfly\source\css\/_tags\music.styl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 .music-card border-radius : 21px border : 1px solid var (--gavin-border-color) background-color : var (--gavin-widget-bg1) box-shadow : var (--gavin-shadow-1 ) height : 80px width : 100% max-width : 350px margin : 1em 0 overflow : hidden .content position : relative display : flex align-items : center width : 100% height : 100% .mc-progress width : 100% height : 100% z-index : 10 display : flex justify-content : left .mc-progressbar height : 100% width : 100% transform : translateX (-100% ) background-color : var (--gavin-highlight-op-1 ) .cover position : absolute left : 10px top : 10px width : 60px height : 60px background-color : var (--gavin-secondbg) border : 1px solid var (--gavin-border-color) border-radius : 10px overflow : hidden z-index : 11 .play position : absolute top : 0 width : 100% height : 100% display : flex align-items : center justify-content : center cursor : pointer opacity : 0 i display : flex align-items : center justify-content : center font-size : 35px color : rgba (255 ,255 ,255 ,.8 ) &:hover .play opacity : 1 &.canplay a img filter : brightness (0.8 ) !important .play opacity : 1 .text-info position : absolute left : 80px max-width : calc (100% - 150px ) display : flex flex-direction : column text-align : left z-index : 9 .title font-size : 16px line-height : 1.3 display : -webkit-box overflow : hidden -webkit-box-orient: vertical -webkit-line-clamp: 1 .author font-size : 13px line-height : 1.3 opacity : .8 display : -webkit-box overflow : hidden -webkit-box-orient: vertical -webkit-line-clamp: 1 .time font-size : 10px line-height : 1.4 display : -webkit-box overflow : hidden -webkit-box-orient: vertical -webkit-line-clamp: 1 opacity : .6 .add position : absolute right : 20px top : 20px width : 40px height : 40px border-radius : 50% background-color : var (--gavin-op-dis-05 ) display : flex align-items : center justify-content : center cursor : pointer z-index : 11 &:hover background-color : var (--gavin-op-dis-1 ) i display : flex align-items : center justify-content : center font-size : 21px
自定义 custom.js 中加入以下代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 var ctrl = { clearConsoleMusicList ( ) { document .getElementById ("console-music-list" ).innerHTML = '' }, addMusicToList (title, author, url, pic, lrc ) { var ap = document .querySelector ("meting-js.global-music" ).aplayer ; ctrl.clearConsoleMusicList (); ap.list .add ([{"title" : title, "author" : author, "url" : url, "pic" : pic, "lrc" : lrc}]); ap.list .switch (ap.list .audios .length - 1 ) }, mcToggleMusic (id, url ) { const mc = document .getElementById (id) if (mc) { const c = mc.querySelector (".content" ) if (!c.classList .contains ("canplay" )) { const a = mc.querySelector (".audio" ) a.src = url a.addEventListener ('loadeddata' , function f ( ) { c.classList .add ("canplay" ) a.removeEventListener ('loadeddata' , f) }); } const mc_audio = mc.querySelector (".audio" ) if (mc_audio.paused ) { mc_audio.play () } else { mc_audio.pause () } } }, mcRefreshTime (id ) { var mc = document .getElementById (id) if (mc) { var mc_audio = mc.querySelector (".audio" ) var t0 = mc_audio.currentTime + 0.5 var t1 = mc_audio.duration var _t0 = tools.secToTime (t0) var _t1 = tools.secToTime (t1) mc.querySelector (".time" ).innerHTML = `${_t0} / ${_t1} ` mc.querySelector (".mc-progressbar" ).style .transform = "translateX(-" + ((1 - (t0 / t1)) * 100 ) + "%)" } } } var tools = { secToTime (s ) { if (isNaN (s)) s = 0 ; var min = Math .floor (s / 60 ); var sec = Math .floor (s % 60 ); var t = min.toString ().padStart (2 , '0' ) + ":" + sec.toString ().padStart (2 , '0' ); return t; } }