迷你播放器1.播放器组件会在各个页面的情况下会打开。 首先在vuex state.js 中定义全局的播放器状态import {playMode} from \'common/js/config.js\
顺晟科技
2022-09-13 11:17:27
22
参考:
https://www.bilibili.com/video/BV12J411m7MG
github 下载完整项目:
https://github.com/VicentWYS/Vue_MusicPlayer
核心:
Vue + axios 联合使用,axios用于发起get请求,从接口获取数据。
Vue框架使用,对从接口返回的数据(类似于DOM树的集合)进行选择,然后渲染到页面上。
项目启动方法:
1.启动IDEA
2.打开项目 - 已存在的项目
3.选择项目文件夹,点击确定

效果:
播放器页面:

MV播放页面:


vueMusicPlayer.html:
1 <!DOCTYPE html>
2 <html lang="en">
3
4 <head>
5 <meta charset="UTF-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <meta http-equiv="X-UA-Compatible" content="ie=edge" />
8 <title>悦听player</title>
9 <!-- 样式 -->
10 <link rel="stylesheet" href="./css/index.css">
11 </head>
12
13 <body>
14 <div class="wrap">
15 <!-- 播放器主体区域 -->
16 <div class="play_wrap" id="player">
17 <div class="search_bar">
18 <img src="images/player_title.png" alt="" />
19 <!-- 搜索歌曲 -->
20 <input type="text" autocomplete="off" v-model="query" @keyup.enter="searchMusic" />
21 </div>
22 <div class="center_con">
23 <!-- 搜索歌曲列表 -->
24 <div class=\'song_wrapper\'>
25 <ul class="song_list">
26 <li v-for="item in musicList">
27 <a href="javascript:;" @click="playMusic(item.id)"></a>
28 <b>{{item.name}}</b>
29 <span v-if="item.mvid!=0" @click="playMV(item.mvid)"><i></i></span>
30 </li>
31 </ul>
32 <img src="images/line.png" class="switch_btn" alt="">
33 </div>
34 <!-- 歌曲信息容器 -->
35 <div class="player_con" :class="{playing:isPlaying}">
36 <img src="images/player_bar.png" class="play_bar" />
37 <!-- 黑胶碟片 -->
38 <img src="images/disc.png" class="disc autoRotate" />
39 <img class="cover autoRotate" :src="musicCover" />
40 </div>
41 <!-- 评论容器 -->
42 <div class="comment_wrapper">
43 <h5 class=\'title\'>热门留言</h5>
44 <div class=\'comment_list\'>
45 <dl v-for="item in hotComments">
46 <dt><img :src="item.user.avatarUrl" alt=""></dt>
47 <dd class="name">{{item.user.nickname}}</dd>
48 <dd class="detail">{{item.content}}</dd>
49 </dl>
50 </div>
51 <img src="images/line.png" class="right_line">
52 </div>
53 </div>
54 <!--播放面板-->
55 <div class="audio_con">
56 <audio ref=\'audio\' @play="play" @pause="pause" :src="musicUrl" controls autoplay loop class="myaudio"></audio>
57 </div>
58 <div class="video_con" v-show="isShow" style="display: none;">
59 <video :src="mvUrl" controls="controls"></video>
60 <div class="mask" @click="hide"></div>
61 </div>
62 </div>
63 </div>
64 <!-- 开发环境版本,包含了有帮助的命令行警告 -->
65 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
66 <!-- 官网提供的 axios 在线地址 -->
67 <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
68 <script src="./js/main.js"></script>
69 </body>
70
71 </html>
View Code
main.js:
1 /*
2 歌曲搜索接口:
3 请求地址:https://autumnfish.cn/search
4 请求方法:get
5 请求参数:keywords(查询关键字)
6 响应内容:歌曲搜索结果
7 */
8
9 /*
10 歌曲url获取接口
11 请求地址:https://autumnfish.cn/song/url
12 请求方法:get
13 请求参数:id(查询关键字)
14 响应内容:歌曲url地址
15 */
16
17 /*
18 歌曲详情获取
19 请求地址:https://autumnfish.cn/song/detail
20 请求方法:get
21 请求参数:ids(歌曲id)
22 响应内容:歌曲详情(包括封面信息)
23 */
24
25 /*
26 热门评论获取
27 请求地址:https://autumnfish.cn/comment/hot?type=0
28 请求方法:get
29 请求参数:id(歌曲id,地址中的type固定为0)
30 响应内容:歌曲的热门评论
31 */
32
33 /*
34 mv地址获取
35 请求地址:https://autumnfish.cn/mv/url
36 请求方法:get
37 请求参数:id(mvid,为0表示没有mv)
38 响应内容:mv的地址
39 */
40
41 var app = new Vue({
42 el:\'#player\',
43 data:{
44 // 查询关键字
45 query:"",
46 // 歌曲数组
47 musicList:[],
48 // 歌曲地址
49 musicUrl:"",
50 // 歌曲封面
51 musicCover:"",
52 // 歌曲评论
53 hotComments:[],
54 // 动画播放状态
55 isPlaying:false,
56 // 遮罩层的显示状态
57 isShow:false,
58 // mv地址
59 mvUrl:""
60 },
61 methods:{
62 // 歌曲搜索
63 searchMusic:function () {
64 var that = this;
65 axios.get("https://autumnfish.cn/search?keywords=" + this.query)
66 .then(function (res) {
67 // console.log(res);
68 that.musicList = res.data.result.songs;
69 }, function (err) {
70 })
71 },
72 // 歌曲播放
73 playMusic:function (musicId) {
74 var that = this;
75 // 获取歌曲地址
76 axios.get("https://autumnfish.cn/song/url?id=" + musicId)
77 .then(function (res) {
78 that.musicUrl = res.data.data[0].url;
79 }, function (err) {});
80
81 // 歌曲详情获取
82 axios.get("https://autumnfish.cn/song/detail?ids=" + musicId)
83 .then(
84 function (res) {
85 // console.log(res);
86 // console.log(res.data.songs[0].al.picUrl);
87 that.musicCover = res.data.songs[0].al.picUrl;
88 }, function (err) { }
89 );
90
91 // 歌曲评论获取
92 axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
93 .then(
94 function (res) {
95 // console.log(res);
96 // console.log(res.data.hotComments);
97 that.hotComments = res.data.hotComments;
98 }, function (err) { }
99 )
100
101 },
102 // 歌曲播放
103 play:function () {
104 // console.log("play");
105 this.isPlaying = true;
106 },
107 // 歌曲暂停
108 pause:function () {
109 // console.log("pause");
110 this.isPlaying = false;
111 },
112 // 播放mv
113 playMV:function (mvid) {
114 var that = this;
115 // 获取MV地址
116 axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
117 .then(function (res) {
118 // console.log(res.data.data.url);
119 // 显示遮罩层
120 that.isShow = true;
121 that.mvUrl = res.data.data.url;
122 }, function (err) {});
123 },
124 //隐藏遮罩层
125 hide:function () {
126 this.isShow = false;
127 }
128 }
129 });
View Code
index.css:
1 body,
2 ul,
3 dl,
4 dd {
5 margin: 0px;
6 padding: 0px;
7 }
8
9 .wrap {
10 position: fixed;
11 left: 0;
12 top: 0;
13 width: 100%;
14 height: 100%;
15 background: url("../images/bg.jpg") no-repeat;
16 background-size: 100% 100%;
17 }
18
19 .play_wrap {
20 width: 800px;
21 height: 544px;
22 position: fixed;
23 left: 50%;
24 top: 50%;
25 margin-left: -400px;
26 margin-top: -272px;
27 /* background-color: #f9f9f9; */
28 }
29
30 .search_bar {
31 height: 60px;
32 background-color: #1eacda;
33 border-top-left-radius: 4px;
34 border-top-right-radius: 4px;
35 display: flex;
36 align-items: center;
37 justify-content: space-between;
38 position: relative;
39 z-index: 11;
40 }
41
42 .search_bar img {
43 margin-left: 23px;
44 }
45
46 .search_bar input {
47 margin-right: 23px;
48 width: 296px;
49 height: 34px;
50 border-radius: 17px;
51 border: 0px;
52 background: url("../images/zoom.png") 265px center no-repeat
53 rgba(255, 255, 255, 0.45);
54 text-indent: 15px;
55 outline: none;
56 }
57
58 .center_con {
59 height: 435px;
60 background-color: rgba(255, 255, 255, 0.5);
61 display: flex;
62 position: relative;
63 }
64
65 .song_wrapper {
66 width: 200px;
67 height: 435px;
68 box-sizing: border-box;
69 padding: 10px;
70 list-style: none;
71 position: absolute;
72 left: 0px;
73 top: 0px;
74 z-index: 1;
75 }
76
77 .song_stretch {
78 width: 600px;
79 }
80
81 .song_list {
82 width: 100%;
83 overflow-y: auto;
84 overflow-x: hidden;
85 height: 100%;
86 }
87 .song_list::-webkit-scrollbar {
88 display: none;
89 }
90
91 .song_list li {
92 font-size: 12px;
93 color: #333;
94 height: 40px;
95 display: flex;
96 flex-wrap: wrap;
97 align-items: center;
98 width: 580px;
99 padding-left: 10px;
100 }
101
102 .song_list li:nth-child(odd) {
103 background-color: rgba(240, 240, 240, 0.3);
104 }
105
106 .song_list li a {
107 display: block;
108 width: 17px;
109 height: 17px;
110 background-image: url("../images/play.png");
111 background-size: 100%;
112 margin-right: 5px;
113 box-sizing: border-box;
114 }
115
116 .song_list li b {
117 font-weight: normal;
118 width: 122px;
119 overflow: hidden;
120 text-overflow: ellipsis;
121 white-space: nowrap;
122 }
123
124 .song_stretch .song_list li b {
125 width: 200px;
126 }
127
128 .song_stretch .song_list li em {
129 width: 150px;
130 }
131
132 .song_list li span {
133 width: 23px;
134 height: 17px;
135 margin-right: 50px;
136 }
137 .song_list li span i {
138 display: block;
139 width: 100%;
140 height: 100%;
141 cursor: pointer;
142 background: url("../images/table.png") left -48px no-repeat;
143 }
144
145 .song_list li em,
146 .song_list li i {
147 font-style: normal;
148 width: 100px;
149 }
150
151 .player_con {
152 width: 400px;
153 height: 435px;
154 position: absolute;
155 left: 200px;
156 top: 0px;
157 }
158
159 .player_con2 {
160 width: 400px;
161 height: 435px;
162 position: absolute;
163 left: 200px;
164 top: 0px;
165 }
166
167 .player_con2 video {
168 position: absolute;
169 left: 20px;
170 top: 30px;
171 width: 355px;
172 height: 265px;
173 }
174
175 .disc {
176 position: absolute;
177 left: 73px;
178 top: 60px;
179 z-index: 9;
180 }
181 .cover {
182 position: absolute;
183 left: 125px;
184 top: 112px;
185 width: 150px;
186 height: 150px;
187 border-radius: 75px;
188 z-index: 8;
189 }
190 .comment_wrapper {
191 width: 180px;
192 height: 435px;
193 list-style: none;
194 position: absolute;
195 left: 600px;
196 top: 0px;
197 padding: 25px 10px;
198 }
199 .comment_wrapper .title {
200 position: absolute;
201 top: 0;
202 margin-top: 10px;
203 }
204 .comment_wrapper .comment_list {
205 overflow: auto;
206 height: 410px;
207 }
208 .comment_wrapper .comment_list::-webkit-scrollbar {
209 display: none;
210 }
211 .comment_wrapper dl {
212 padding-top: 10px;
213 padding-left: 55px;
214 position: relative;
215 margin-bottom: 20px;
216 }
217
218 .comment_wrapper dt {
219 position: absolute;
220 left: 4px;
221 top: 10px;
222 }
223
224 .comment_wrapper dt img {
225 width: 40px;
226 height: 40px;
227 border-radius: 20px;
228 }
229
230 .comment_wrapper dd {
231 font-size: 12px;
232 }
233
234 .comment_wrapper .name {
235 font-weight: bold;
236 color: #333;
237 padding-top: 5px;
238 }
239
240 .comment_wrapper .detail {
241 color: #666;
242 margin-top: 5px;
243 line-height: 18px;
244 }
245 .audio_con {
246 height: 50px;
247 background-color: #f1f3f4;
248 border-bottom-left-radius: 4px;
249 border-bottom-right-radius: 4px;
250 }
251 .myaudio {
252 width: 800px;
253 height: 40px;
254 margin-top: 5px;
255 outline: none;
256 background-color: #f1f3f4;
257 }
258 /* 旋转的动画 */
259 @keyframes Rotate {
260 from {
261 transform: rotateZ(0);
262 }
263 to {
264 transform: rotateZ(360deg);
265 }
266 }
267 /* 旋转的类名 */
268 .autoRotate {
269 animation-name: Rotate;
270 animation-iteration-count: infinite;
271 animation-play-state: paused;
272 animation-timing-function: linear;
273 animation-duration: 5s;
274 }
275 /* 是否正在播放 */
276 .player_con.playing .disc,
277 .player_con.playing .cover {
278 animation-play-state: running;
279 }
280
281 .play_bar {
282 position: absolute;
283 left: 200px;
284 top: -10px;
285 z-index: 10;
286 transform: rotate(-25deg);
287 transform-origin: 12px 12px;
288 transition: 1s;
289 }
290 /* 播放杆 转回去 */
291 .player_con.playing .play_bar {
292 transform: rotate(0);
293 }
294 /* 搜索历史列表 */
295 .search_history {
296 position: absolute;
297 width: 296px;
298 overflow: hidden;
299 background-color: rgba(255, 255, 255, 0.3);
300 list-style: none;
301 right: 23px;
302 top: 50px;
303 box-sizing: border-box;
304 padding: 10px 20px;
305 border-radius: 17px;
306 }
307 .search_history li {
308 line-height: 24px;
309 font-size: 12px;
310 cursor: pointer;
311 }
312 .switch_btn {
313 position: absolute;
314 right: 0;
315 top: 0;
316 cursor: pointer;
317 }
318 .right_line {
319 position: absolute;
320 left: 0;
321 top: 0;
322 }
323 .video_con video {
324 position: fixed;
325 width: 800px;
326 height: 546px;
327 left: 50%;
328 top: 50%;
329 margin-top: -273px;
330 transform: translateX(-50%);
331 z-index: 990;
332 }
333 .video_con .mask {
334 position: fixed;
335 width: 100%;
336 height: 100%;
337 left: 0;
338 top: 0;
339 z-index: 980;
340 background-color: rgba(0, 0, 0, 0.8);
341 }
342 .video_con .shutoff {
343 position: fixed;
344 width: 40px;
345 height: 40px;
346 background: url("../images/shutoff.png") no-repeat;
347 left: 50%;
348 margin-left: 400px;
349 margin-top: -273px;
350 top: 50%;
351 z-index: 995;
352 }
View Code
13
2022-09
13
2022-09
02
2021-09
23
2021-07
03
2021-07