├── README.md
├── README_EN.md
├── music.css
├── music.js
└── MusicPlayer.vue
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 🎵 HTML-Music-Player
4 | ### **简体中文** /
English
5 |
6 | 一个基于HTML编写的简洁音乐播放器
7 |
8 | A simple music player written in HTML
9 |
10 |     
11 |
12 |
13 |
14 | ## 🗄 效果展示
15 |
16 | 
17 |
18 |
19 |
20 | ## ⭐ 特性
21 | 1. 通过遵循指定格式,您可以轻松调用此播放器。
22 | 2. 将鼠标悬停在封面上并单击,即可切换播放状态。
23 | 3. 您也可以使用空格键来切换播放状态。
24 | 4. 在拖动进度条时,将显示进度预览,松手时伴有跟进效果。
25 |
26 |
27 | ## 💻 使用
28 |
29 | 首先在 HTML 文件中调用外部文件
30 | ```html
31 |
32 | ```
33 |
34 | ```html
35 |
36 | ```
37 |
38 | 在需要调用的位置按照以下格式输入您的音乐信息
39 |
40 | ```html
41 |
42 | ```
43 |
44 | ### 使用案例
45 | 请根据您的使用场景来选择调用的方式
46 | #### HTML
47 | ```html
48 |
49 | ```
50 |
51 | 您也可以通过该方式在静态博客所使用的 Markdown 文件中进行调用,目前已在 Hugo 测试通过。
52 |
53 | #### VUE
54 | ```vue
55 |
56 | ```
57 | 将 VUE 文件保存在对应路径后,您也可以使用该方式在支持 VUE 调用的程序中使用该播放器。
58 |
59 |
60 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 🎵 HTML-Music-Player
4 | ###
简体中文 / English
5 |
6 | A simple music player written in HTML
7 |
8 |     
9 |
10 |
11 |
12 | ## 🗄 Music Player Demo
13 |
14 | 
15 |
16 |
17 |
18 | ## ⭐ Features
19 | 1. Easily invoke this player by following the specified format.
20 | 2. Hover the mouse over the cover and click to toggle the play status.
21 | 3. You can also use the spacebar to toggle the play status.
22 | 4. While dragging the progress bar, a progress preview will be displayed, and when released, it is accompanied by a follow-up effect.
23 |
24 |
25 | ## 💻 Usage
26 | First, call external files in your HTML file:
27 | ```html
28 |
29 | ```
30 |
31 | ```html
32 |
33 | ```
34 |
35 | Enter your music information in the following format where you want to invoke it:
36 |
37 | ```html
38 |
39 | ```
40 |
41 | ### Usage Example
42 | Choose the method of invocation according to your use case.
43 | #### HTML
44 | ```html
45 |
46 | ```
47 | You can also invoke it in this way in Markdown files used in static blogs, already tested and working with Hugo.
48 | #### VUE
49 | ```vue
50 |
51 | ```
52 | After saving the VUE file in the corresponding path, you can use this player in programs that support VUE invocation.
53 |
54 |
55 |
--------------------------------------------------------------------------------
/music.css:
--------------------------------------------------------------------------------
1 | .player {
2 | display: flex;
3 | align-items: center;
4 | background-color: #ffffff;
5 | border-radius: 10px;
6 | box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
7 | padding: 10px;
8 | max-width: 350px;
9 | font-family: Arial, sans-serif;
10 | }
11 |
12 | .cover {
13 | position: relative;
14 | width: 60px;
15 | height: 60px;
16 | background-size: cover;
17 | background-position: center;
18 | border-radius: 30px;
19 | margin-right: 15px;
20 | overflow: hidden;
21 | cursor: pointer;
22 | }
23 |
24 | .cover::after, .playBtn {
25 | opacity: 0;
26 | transition: opacity 0.3s ease;
27 | }
28 |
29 | .cover:hover::after, .cover:hover .playBtn {
30 | opacity: 1;
31 | }
32 |
33 | .cover::after {
34 | content: '';
35 | position: absolute;
36 | top: 0;
37 | left: 0;
38 | right: 0;
39 | bottom: 0;
40 | background-color: rgba(0, 0, 0, 0.3);
41 | z-index: 1;
42 | }
43 |
44 | .playBtn {
45 | position: absolute;
46 | top: 50%;
47 | left: 50%;
48 | transform: translate(-50%, -50%);
49 | background: none;
50 | border: none;
51 | font-size: 1.5em;
52 | color: #ffffff;
53 | cursor: pointer;
54 | z-index: 2;
55 | }
56 |
57 | .song-info {
58 | flex-grow: 1;
59 | display: flex;
60 | flex-direction: column;
61 | justify-content: center;
62 | }
63 |
64 | .song-title {
65 | font-size: 0.9em;
66 | font-weight: 600;
67 | color: #333;
68 | margin-bottom: 6px;
69 | }
70 |
71 | .progress-container {
72 | width: 100%;
73 | height: 3px;
74 | background: #ddd;
75 | border-radius: 1.5px;
76 | cursor: pointer;
77 | position: relative;
78 | }
79 |
80 | .progress, .preview-progress {
81 | height: 100%;
82 | border-radius: 1.5px;
83 | position: absolute;
84 | left: 0;
85 | top: 0;
86 | }
87 |
88 | .progress {
89 | background: #007bff;
90 | width: 0%;
91 | transition: width 0.3s ease;
92 | }
93 |
94 | .preview-progress {
95 | background: rgba(0, 123, 255, 0.5);
96 | width: 0%;
97 | }
98 |
99 | .time {
100 | font-size: 0.75em;
101 | color: #666;
102 | margin-top: 8px;
103 | }
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/music.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', function () {
2 | var musicBlocks = document.querySelectorAll('div[music]');
3 |
4 | musicBlocks.forEach(function (block) {
5 | var title = block.getAttribute('Title');
6 | var imgSrc = block.getAttribute('Img');
7 | var audioSrc = block.getAttribute('File');
8 |
9 | var playerHTML = `
10 |
11 |
12 |
13 |
14 |
15 |
${title}
16 |
20 |
0:00 / 0:00
21 |
22 |
23 |
24 | `;
25 |
26 | block.innerHTML = playerHTML;
27 |
28 | var audioPlayer = block.querySelector('.audio-player');
29 | var playBtn = block.querySelector('.playBtn');
30 | var progressContainer = block.querySelector('.progress-container');
31 | var progress = block.querySelector('.progress');
32 | var previewProgress = block.querySelector('.preview-progress');
33 | var time = block.querySelector('.time');
34 | var isDragging = false;
35 |
36 | playBtn.addEventListener('click', function () {
37 | togglePlayPause();
38 | });
39 |
40 | progressContainer.addEventListener('mousedown', function (e) {
41 | isDragging = true;
42 | updatePreviewProgress(e);
43 | });
44 |
45 | progressContainer.addEventListener('mousemove', function (e) {
46 | if (isDragging) {
47 | updatePreviewProgress(e);
48 | }
49 | });
50 |
51 | window.addEventListener('mouseup', function (e) {
52 | if (isDragging) {
53 | isDragging = false;
54 | setProgress(e);
55 | }
56 | });
57 |
58 | window.addEventListener('keydown', function (e) {
59 | if (e.code === 'Space') {
60 | e.preventDefault();
61 | togglePlayPause();
62 | }
63 | });
64 |
65 | function togglePlayPause() {
66 | if (audioPlayer.paused) {
67 | audioPlayer.play();
68 | playBtn.innerHTML = '❚❚';
69 | } else {
70 | audioPlayer.pause();
71 | playBtn.innerHTML = '►';
72 | }
73 | }
74 |
75 | function updatePreviewProgress(e) {
76 | var width = progressContainer.clientWidth;
77 | var clickX = e.offsetX;
78 | var previewPercent = (clickX / width) * 100;
79 | previewProgress.style.width = previewPercent + '%';
80 | }
81 |
82 | function setProgress(e) {
83 | var width = progressContainer.clientWidth;
84 | var clickX = e.offsetX;
85 | var duration = audioPlayer.duration;
86 | audioPlayer.currentTime = (clickX / width) * duration;
87 | updateProgress();
88 | }
89 |
90 | function updateProgress() {
91 | var currentTime = audioPlayer.currentTime;
92 | var duration = audioPlayer.duration;
93 | var progressPercent = (currentTime / duration) * 100;
94 | progress.style.width = progressPercent + '%';
95 | updateTimeDisplay(currentTime, duration);
96 | }
97 |
98 | function updateTimeDisplay(currentTime, duration) {
99 | var currentMinutes = Math.floor(currentTime / 60);
100 | var currentSeconds = Math.floor(currentTime % 60);
101 | if (currentSeconds < 10) currentSeconds = '0' + currentSeconds;
102 |
103 | var durationMinutes = Math.floor(duration / 60);
104 | var durationSeconds = Math.floor(duration % 60);
105 | if (durationSeconds < 10) durationSeconds = '0' + durationSeconds;
106 |
107 | time.textContent = currentMinutes + ':' + currentSeconds + ' / ' + durationMinutes + ':' + durationSeconds;
108 | }
109 |
110 | audioPlayer.addEventListener('timeupdate', updateProgress);
111 | });
112 | });
113 |
--------------------------------------------------------------------------------
/MusicPlayer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
{{ title }}
8 |
13 |
{{ timeText }}
14 |
15 |
16 |
17 |
18 |
19 |
123 |
124 |
--------------------------------------------------------------------------------