MassageRobot_Dobot/UI_next/templates/full_music_player.html
2025-05-27 15:46:31 +08:00

1638 lines
52 KiB
HTML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> -->
<!-- <script src="https://ajax.lug.ustc.edu.cn/ajax/libs/jquery/3.5.1/jquery.min.js"></script> -->
<script src="{{ url_for('static', filename='js/jquery/jquery.min.js') }}"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.1/socket.io.js"></script> -->
<!-- <script src="https://cdn.socket.io/4.3.1/socket.io.min.js"></script> -->
<script src="{{ url_for('static', filename='js/socketio/socket.io.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/i18n/jquery-3.7.1.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/i18n/jquery.i18n.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/i18n/setting-lang.js') }}"></script>
<title>Music Player UI</title>
<style>
/* 禁用用户选择 */
* {
-webkit-user-select: none;
/* Chrome, Opera, Safari */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
/* Internet Explorer/Edge */
user-select: none;
/* Non-prefixed version, currently supported by Chrome, Opera and Firefox */
-webkit-tap-highlight-color: transparent;
/* 禁用触控点击的蓝色叠加层 */
}
body,
html {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background-color: transparent;
display: flex;
justify-content: center;
align-items: center;
/* height: 100vh; */
height: 100%;
width: 100%;
}
.search-container {
position: fixed;
top: 10px;
right: 2.5%;
left: 2.5%;
z-index: 1000;
}
.button-box {
display: flex;
align-items: center;
justify-content: right;
position: fixed;
top: 1%;
right: 5%;
}
.refresh-button,
.search-button {
height: 36px;
width: 50px;
box-sizing: border-box;
color: #fff;
border: none;
background-color: #ffe1f448;
border-radius: 8px;
box-shadow: 0 0.5px 2px rgba(0, 0, 0, 0.1);
cursor: pointer;
overflow: hidden;
transform: scale(0.9);
display: flex;
justify-content: center;
align-items: center;
}
.refresh-button img,
.search-button img {
height: 18px;
width: 18px;
opacity: 0.85;
}
.search-box {
display: none;
position: absolute;
top: 40px;
background-color: #ffffffcb;
border: 0px solid #ccc;
border-radius: 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
height: 50px;
width: 100%;
}
.search-input {
position: absolute;
left: 10px;
right: 10px;
top: 10px;
height: 30px;
border: 0px solid #ffa1f293;
background-color: transparent;
border-radius: 10px;
outline: none;
/* width: 100%; */
/* margin: 0 5px; */
}
.start-search {
position: absolute;
right: 0px;
top: 8px;
background: linear-gradient(
to right bottom,
rgb(212, 96, 241),
rgba(145, 66, 197, 0.5)
);
color: white;
border: none;
border-radius: 10px;
padding: 8px 12px;
margin-right: 10px;
font-weight: bold;
cursor: pointer;
opacity: 0.85;
}
.container {
width: 100%;
height: 100%;
display: flex;
gap: 20px;
}
.player {
width: 90%;
background-color: transparent;
border-radius: 15px;
margin-top: 50px;
/* padding: 20px; */
/* box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); */
transform: translateX(calc(5%));
overflow-y: auto;
}
/* 隐藏滚动条 */
.player::-webkit-scrollbar {
display: none;
}
.player {
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
}
.main-image {
width: 100%;
height: 150px;
object-fit: cover;
border-radius: 15px;
overflow: hidden;
}
.playlist-container {
margin-top: 15px;
}
.playlist-container-title {
display: flex;
justify-content: space-between;
align-items: center;
}
.playlist-btn-box {
display: flex;
gap: 10px;
}
.edit-playlist-btn,
.add-playlist-btn {
background: linear-gradient(
to right bottom,
rgb(212, 96, 241),
rgba(145, 66, 197, 0.5)
);
border: none;
border-radius: 50%;
width: 25px;
height: 25px;
cursor: pointer;
color: white;
}
.playlist-btn-icon {
width: 14px;
height: 14px;
}
.playlist-images {
display: flex;
gap: 10px;
padding-top: 15px;
overflow-x: auto;
overflow-y: hidden;
justify-content: flex-start;
}
/* 隐藏滚动条 */
.playlist-images::-webkit-scrollbar {
display: none;
}
.playlist-images {
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
}
.playlist-image-wrapper {
position: relative;
width: 80px;
height: 80px;
flex-shrink: 0;
}
.playlist-image {
width: 80px;
height: 80px;
/* object-fit: cover; */
border-radius: 10px;
}
.playlist-title {
position: absolute;
width: 75px;
bottom: 0;
background-color: rgba(0, 0, 0, 0);
color: white;
font-size: 0.8em;
font-weight: bold;
text-align: left;
border-radius: 10px;
/* 圆角仅在底部 */
padding-left: 5px;
white-space: normal;
/* 允许换行 */
overflow: hidden;
/* 隐藏溢出内容 */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
/* 限制为两行 */
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8); /* 文本阴影 */
}
.songs-list {
margin: 10px 0 0;
padding-bottom: 80px;
}
.song {
display: flex;
align-items: center;
/* margin-bottom: 10px; */
margin-top: 10px;
}
.song-image {
width: 40px;
height: 40px;
object-fit: cover;
border-radius: 5px;
margin-right: 10px;
}
.song-info {
flex-grow: 1;
}
.song-title {
font-weight: bold;
white-space: normal;
/* 允许换行 */
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.song-artist {
font-size: 0.8em;
color: #888;
}
/* */
/* */
/* */
.playlist-page {
position: fixed;
top: 0;
right: -100%;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(5px);
/* box-shadow: -4px 0 6px rgba(0, 0, 0, 0.1); */
display: flex;
flex-direction: column;
/* align-items: center; */
/* justify-content: center; */
border-radius: 15px;
transition: right 0.5s ease-out;
z-index: 999;
}
.playlist-page.show {
right: 0;
}
#play-all-btn {
width: 100%;
height: 40px;
border-radius: 15px;
background-color: #e9e9e942;
display: flex; /* 使用 Flexbox 布局 */
align-items: center; /* 垂直居中图片和文本 */
}
#play-all-btn img {
width: 25px;
height: 25px;
margin-left: 10px; /* 左侧边距 */
opacity: 0.75;
}
#play-all-btn div {
margin-left: 15px;
}
.back-to-player-button {
position: absolute;
top: 2.5%;
left: 5%;
height: 25px;
width: 50px;
box-sizing: border-box;
color: #fff;
border: none;
background-color: #ffe1f448;
border-radius: 15px;
box-shadow: 0 0.5px 2px rgba(0, 0, 0, 0.1);
cursor: pointer;
overflow: hidden;
transform: scale(0.9);
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
}
.back-to-player-button img {
width: 15px;
height: 15px;
opacity: 0.85;
}
.playlist-page-container {
/* position: absolute; */
/* left: 0; */
width: 90%;
background-color: transparent;
border-radius: 15px;
margin-top: 50px;
/* padding: 20px; */
/* box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); */
transform: translateX(calc(5%));
overflow-y: auto;
}
/* 隐藏滚动条 */
.playlist-page-container::-webkit-scrollbar {
display: none;
}
.playlist-page-container {
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
}
/* */
/* */
/* */
.mini-player {
position: absolute;
bottom: 0;
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
background-color: #f8f8f8;
border-radius: 10px;
padding: 10px;
margin-top: 20px;
cursor: pointer;
z-index: 1000;
}
.mini-player-image {
width: 40px;
height: 40px;
object-fit: cover;
border-radius: 5px;
margin-right: 10px;
}
.mini-player-controls {
display: flex;
align-items: center;
}
.mini-player-button {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
}
.mini-player-button img {
margin-top: 5px;
width: 35px;
height: 35px;
opacity: 0.4;
}
.full-player {
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(5px);
position: fixed;
bottom: -100%;
left: 0;
border-radius: 15px 15px 0 0;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transition: bottom 0.5s ease-out;
/* transition: bottom 1s cubic-bezier(.19,1,.22,1); */
z-index: 1001;
overflow: hidden;
}
.full-player.show {
bottom: 0;
}
.full-player-image {
width: 30vw;
height: 30vw;
object-fit: cover;
border-radius: 10px;
}
.full-player-info {
text-align: center;
margin-top: 20px;
}
.full-player-title {
font-weight: bold;
font-size: 1.2em;
}
.full-player-artist {
color: #888;
}
.progress-bar {
width: 80%;
height: 4px;
background-color: #e0e0e0;
margin-top: 20px;
border-radius: 2px;
cursor: pointer;
}
.progress {
width: 0%;
height: 100%;
/* background-color: #000000; */
background: linear-gradient(
to right bottom,
rgb(212, 96, 241),
rgba(145, 66, 197, 0.5)
);
border-radius: 2px;
}
.time-info {
width: 80%;
display: flex;
justify-content: space-between;
margin-top: 5px;
font-size: 0.8em;
color: #888;
}
.full-player-controls {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
}
.full-player-button {
background: none;
border: none;
font-size: 32px;
margin: 0 10px;
cursor: pointer;
justify-content: center;
align-items: center;
}
.full-player-button img {
width: 40px;
height: 40px;
opacity: 0.4;
}
.back-button {
position: absolute;
top: 2.5%;
left: 5%;
height: 25px;
width: 50px;
box-sizing: border-box;
color: #fff;
border: none;
background-color: #ffe1f448;
border-radius: 15px;
box-shadow: 0 0.5px 2px rgba(0, 0, 0, 0.1);
cursor: pointer;
overflow: hidden;
transform: scale(0.9);
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
}
.back-button img {
width: 20px;
height: 20px;
opacity: 0.85;
}
/* Add popup styles */
.popup {
display: block;
position: fixed;
top: -50px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(5px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 10px 14px;
color: rgba(252, 74, 252, 0.7);
border-radius: 17.5px;
z-index: 1000;
font-size: 14px;
align-items: center;
justify-content: center;
text-align: center;
opacity: 0;
transition: all 0.15s ease-in-out;
}
.popup.show {
display: flex;
opacity: 0.8;
top: calc(2.5% + 40px);
}
.popup.hide {
opacity: 0;
top: -50px;
}
.playlist-image-wrapper {
position: relative;
}
.delete-playlist-btn {
position: absolute;
top: -8px;
right: -8px;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.9);
border: none;
border-radius: 50%;
display: none;
justify-content: center;
align-items: center;
cursor: pointer;
z-index: 2;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
font-size: 14px;
color: rgba(0, 0, 0, 0.5);
line-height: 1;
padding: 0;
}
.delete-playlist-btn::before {
content: "×";
font-size: 16px;
font-weight: bold;
}
.editing .delete-playlist-btn {
display: flex;
}
.playlist-image-wrapper.deleting {
animation: fadeOut 0.3s ease-out forwards;
}
@keyframes fadeOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.8);
}
}
</style>
</head>
<body>
<div class="search-container">
<div class="button-box">
<!-- <button class="refresh-button">
<img
src="{{ url_for('static', filename='images/music/refresh.svg') }}"
alt="刷新"
/>
</button> -->
<button class="search-button">
<img
src="{{ url_for('static', filename='images/music/search.svg') }}"
alt="搜索"
/>
</button>
</div>
<div class="search-box">
<input type="text" class="search-input" placeholder="Search..." />
<button type="button" class="start-search" i18n="control.music.search">
搜索
</button>
</div>
</div>
<div id="popup" class="popup"></div>
<div class="container">
<div class="player">
<img
src="{{ url_for('static', filename='images/StormX.svg') }}"
alt="Main Image"
class="main-image"
/>
<div class="playlist-container">
<div class="playlist-container-title">
<div i18n="control.music.title">收藏歌单</div>
<div class="playlist-btn-box">
<button class="edit-playlist-btn">
<img
src="{{ url_for('static', filename='images/music/edit.svg') }}"
alt=""
class="playlist-btn-icon"
/>
</button>
<button class="add-playlist-btn">
<img
src="{{ url_for('static', filename='images/music/add.svg') }}"
alt=""
class="playlist-btn-icon"
/>
</button>
</div>
</div>
<input
type="file"
id="playlist-image-upload"
accept="image/*"
style="display: none"
/>
<div class="playlist-images" id="playlists">
<!-- <div class="playlist-image-wrapper">
<img src="https://via.placeholder.com/80x80" alt="The Wave" class="playlist-image">
<div class="playlist-title">The Wave</div>
</div>
<div class="playlist-image-wrapper">
<img src="https://via.placeholder.com/80x80" alt="Let's Run" class="playlist-image">
<div class="playlist-title">Let's Run</div>
</div>
<div class="playlist-image-wrapper">
<img src="https://via.placeholder.com/80x80" alt="Two Super" class="playlist-image">
<div class="playlist-title">Two Super</div>
</div> -->
<!-- 添加更多图片及标题 -->
</div>
</div>
<div class="songs-list" id="music-list">
<div i18n="control.music.title2">
热门
<!-- <span style="float: right;">View All</span> -->
</div>
</div>
</div>
<div class="playlist-page">
<button class="back-to-player-button">
<img
src="{{ url_for('static', filename='images/music/back-line-free.png') }}"
alt="返回"
/>
</button>
<div class="playlist-page-container">
<!-- 播放全部按钮将会在这里插入,默认隐藏 -->
<div id="play-all-btn" style="display: none">
<img
src="{{ url_for('static', filename='images/music/播放.svg') }}"
alt="播放全部"
/>
<div>播放全部</div>
</div>
<div class="songs-list" id="playlist-music-list">
<div class="song">
<img
src="{{ url_for('static', filename='images/music/cover.png') }}"
alt="Another Smack"
class="song-image"
/>
<div class="song-info">
<div class="song-title">Another Smack</div>
<div class="song-artist">Joiane Swift</div>
</div>
</div>
</div>
</div>
</div>
<div class="mini-player">
<img
src="{{ url_for('static', filename='images/music/cover.png') }}"
alt="Another Smack"
class="mini-player-image"
/>
<div class="song-info">
<div class="song-title">Another Smack</div>
<div class="song-artist">Joiane Swift</div>
</div>
<div class="mini-player-controls">
<button class="mini-player-button" id="mini_play_stop_btn">
<img
src="{{ url_for('static', filename='images/music/开始.svg') }}"
alt="开始"
/>
</button>
</div>
</div>
<div class="full-player">
<button class="back-button">
<img
src="{{ url_for('static', filename='images/music/down-line-free.png') }}"
alt="返回"
/>
</button>
<img
src="{{ url_for('static', filename='images/music/cover.png') }}"
alt="Let Me Go"
class="full-player-image"
/>
<div class="full-player-info">
<div class="full-player-title">Let Me Go</div>
<div class="full-player-artist">Rokice</div>
</div>
<div class="progress-bar">
<div class="progress"></div>
</div>
<div class="time-info">
<span id="current-time">0:00</span>
<span id="total-time">0:00</span>
</div>
<div class="full-player-controls">
<button class="full-player-button" id="full_play_last_btn">
<img
src="{{ url_for('static', filename='images/music/上一项.svg') }}"
alt="上一首"
style="transform: scale(0.8)"
/>
</button>
<button class="full-player-button" id="full_play_stop_btn">
<img
src="{{ url_for('static', filename='images/music/开始.svg') }}"
alt="开始"
/>
</button>
<button class="full-player-button" id="full_play_next_btn">
<img
src="{{ url_for('static', filename='images/music/下一项.svg') }}"
alt="下一首"
style="transform: scale(0.8)"
/>
</button>
</div>
</div>
</div>
<script>
document
.querySelector(".mini-player")
.addEventListener("click", function (event) {
if (!event.target.closest("#mini_play_stop_btn")) {
document.querySelector(".full-player").classList.add("show");
}
});
function togglePlayStop(isPlaying) {
const buttons = document.querySelectorAll(
"#mini_play_stop_btn, #full_play_stop_btn"
);
buttons.forEach((button) => {
const img = button.querySelector("img");
if (isPlaying) {
img.src = "/static/images/music/暂停.svg";
img.alt = "暂停";
} else {
img.src = "/static/images/music/开始.svg";
img.alt = "开始";
}
});
}
document
.querySelectorAll("#mini_play_stop_btn, #full_play_stop_btn")
.forEach((button) => {
button.addEventListener("click", function (event) {
event.stopPropagation(); // 阻止事件冒泡,如果有必要
const img = button.querySelector("img");
const isPlaying = img.alt === "暂停"; // 判断当前状态是不是"暂停"(即正在播放)
// 根据当前的播放状态,发送相应的请求
const url = isPlaying ? "/pause_music" : "/resume_music";
// togglePlayStop(!isPlaying);
// 发送 AJAX 请求
$.post(url, {}, function (response) {
if (response.status === "success") {
// 成功响应后,切换图标状态
togglePlayStop(!isPlaying);
// updatePlayStatus()
} else {
// 如果出错,弹窗提示错误消息
alert("Error: " + response.message);
}
});
});
});
const playLastBtn = document.getElementById("full_play_last_btn");
const playNextBtn = document.getElementById("full_play_next_btn");
// 点击上一首按钮事件
playLastBtn.addEventListener("click", async () => {
try {
const response = await fetch("/play_last_song", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const data = await response.json();
} catch (error) {
console.error("Error:", error);
}
});
// 点击下一首按钮事件
playNextBtn.addEventListener("click", async () => {
try {
const response = await fetch("/play_next_song", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const data = await response.json();
} catch (error) {
console.error("Error:", error);
}
});
document
.querySelector(".back-button")
.addEventListener("click", function () {
document.querySelector(".full-player").classList.remove("show");
});
// document
// .querySelector(".refresh-button")
// .addEventListener("click", function () {
// getMusicData();
// fetchPlaylists();
// });
// 搜索按钮和搜索框的显示与隐藏
document
.querySelector(".search-button")
.addEventListener("click", function () {
const searchBox = document.querySelector(".search-box");
if (
searchBox.style.display === "none" ||
searchBox.style.display === ""
) {
searchBox.style.display = "block";
} else {
searchBox.style.display = "none";
}
});
// document.querySelectorAll('.playlist-image-wrapper').forEach(wrapper => {
// wrapper.addEventListener('click', function() {
// document.querySelector('.playlist-page').classList.add('show');
// });
// });
document
.querySelector(".back-to-player-button")
.addEventListener("click", function () {
document.querySelector(".playlist-page").classList.remove("show");
});
function updatePlayStatus() {
fetch("/get_current_song")
.then((response) => response.json())
.then((data) => {
// console.log(data, "updatePlayStatus");
if (data.status === "success" && data.data) {
const { album_img_url, music_name, singer_name, is_playing } =
data.data;
// 更新播放器
const miniPlayerImage = document.querySelector(
".mini-player .mini-player-image"
);
const miniPlayerTitle = document.querySelector(
".mini-player .song-title"
);
const miniPlayerArtist = document.querySelector(
".mini-player .song-artist"
);
const fullPlayerImage = document.querySelector(
".full-player .full-player-image"
);
const fullPlayerTitle = document.querySelector(
".full-player .full-player-title"
);
const fullPlayerArtist = document.querySelector(
".full-player .full-player-artist"
);
miniPlayerImage.src = album_img_url;
miniPlayerImage.alt = music_name;
miniPlayerTitle.textContent = music_name;
miniPlayerArtist.textContent = singer_name;
// fullPlayerImage.src = album_img_url.replace("T002R180x180M000", "T002R300x300M000");
fullPlayerImage.alt = music_name;
fullPlayerTitle.textContent = music_name;
fullPlayerArtist.textContent = singer_name;
// 根据播放状态更新播放/暂停按钮
togglePlayStop(is_playing);
} else {
console.log("No current song information available.");
}
})
.catch((error) => console.error("Error fetching data:", error));
}
// function createSongElements(music_info_list,musicList) {
// music_info_list.forEach(song => {
// // console.log(song)
// const [music_name, singer_name, songmid, albummid] = song;
// let album_img_url = ""
// if (albummid){
// album_img_url = "http://y.gtimg.cn/music/photo_new/T002R180x180M000" + albummid + ".jpg";
// createSongElement(music_name, singer_name, album_img_url, songmid);
// }
// else{
// fetch('/get_album_image', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({ singer_name }),
// })
// .then(response => response.json())
// .then(data => {
// if (data.album_img_url) {
// album_img_url = data.album_img_url;
// // console.log(album_img_url)
// createSongElement(music_name, singer_name, album_img_url, songmid);
// } else {
// console.log('Error fetching album image:', data.error);
// // Handle error scenario if needed
// }
// })
// .catch(error => {
// console.error('Error fetching album image:', error);
// // Handle fetch error
// });
// }
// // console.log(album_img_url)
// function createSongElement(music_name, singer_name, album_img_url, songmid) {
// const songDiv = document.createElement('div');
// songDiv.classList.add('song');
// songDiv.innerHTML = `
// <img src="${album_img_url}" alt="${music_name}" class="song-image">
// <div class="song-info">
// <div class="song-title">${music_name}</div>
// <div class="song-artist">${singer_name}</div>
// </div>
// `;
// songDiv.addEventListener('click', () => {
// fetch('/song_clicked', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({ music_name, singer_name, album_img_url, songmid }),
// })
// .then(response => response.json())
// .then(data => {
// if (data.status === 'success') {
// // Update current song in the backend
// fetch('/set_current_song', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({
// album_img_url: album_img_url,
// music_name: music_name,
// singer_name: singer_name,
// is_playing: true
// }),
// })
// .then(response => response.json())
// .then(updateResponse => {
// console.log('Current song updated:', updateResponse);
// });
// // Toggle play/stop button to show "playing" status
// togglePlayStop(true);
// // Update mini player
// const miniPlayerImage = document.querySelector('.mini-player .mini-player-image');
// const miniPlayerTitle = document.querySelector('.mini-player .song-title');
// const miniPlayerArtist = document.querySelector('.mini-player .song-artist');
// miniPlayerImage.src = album_img_url;
// miniPlayerImage.alt = music_name;
// miniPlayerTitle.textContent = music_name;
// miniPlayerArtist.textContent = singer_name;
// // Update full player
// const fullPlayerImage = document.querySelector('.full-player .full-player-image');
// const fullPlayerTitle = document.querySelector('.full-player .full-player-title');
// const fullPlayerArtist = document.querySelector('.full-player .full-player-artist');
// fullPlayerImage.src = album_img_url.replace("T002R180x180M000", "T002R300x300M000");
// fullPlayerImage.alt = music_name;
// fullPlayerTitle.textContent = music_name;
// fullPlayerArtist.textContent = singer_name;
// } else {
// console.log(data.message); // Handle error or unsuccessful attempt
// }
// });
// });
// musicList.appendChild(songDiv);
// }
// });
// }
function createSongElements(
music_info_list,
musicList,
showPlayAll = false
) {
// console.log(music_info_list, "music_info_list");
// console.log(musicList, "musicList");
// 找到播放全部按钮的容器
const playAllButton = document.getElementById("play-all-btn");
// 如果 showPlayAll 为 true则显示 "播放全部" 按钮
if (showPlayAll) {
playAllButton.style.display = "flex"; // 显示按钮
// 监听按钮点击事件,将整个播放列表发送到后端
playAllButton.addEventListener("click", () => {
// const playlist = music_info_list.map((song) => ({
// music_name: song[0],
// singer_name: song[1],
// songmid: song[2],
// album_img_url: song[3]
// ? `http://y.gtimg.cn/music/photo_new/T002R180x180M000${song[3]}.jpg`
// : "", // 使用默认格式生成封面
// }));
const playlist = music_info_list.map((song) => ({
music_name: song[0],
singer_name: song[1],
songmid: song[2],
album_img_url: song[3]
? `https://robotstorm.tech/ygtimg/music/photo_new/T002R180x180M000${song[3]}.jpg`
: "", // 使用默认格式生成封面
}));
// 向后端发送请求更新播放列表
fetch("/playlist_update", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ playlist }),
})
.then((response) => response.json())
.then((data) => {
// console.log("更新播放列表Playlist updated:", data);
// if (data.status === "success") {
// console.log("Playlist updated and playing first song");
// } else {
// console.log("Error updating playlist:", data.message);
// }
})
.catch((error) => {
console.error("Error updating playlist:", error);
});
});
} else {
playAllButton.style.display = "none"; // 隐藏按钮
}
// 创建每个歌曲元素
music_info_list.forEach((song) => {
const [music_name, singer_name, songmid, albummid] = song;
let album_img_url = "";
if (albummid) {
// album_img_url =
// "http://y.gtimg.cn/music/photo_new/T002R180x180M000" +
// albummid +
// ".jpg";
album_img_url =
"https://robotstorm.tech/ygtimg/music/photo_new/T002R180x180M000" +
albummid +
".jpg";
createSongElement(music_name, singer_name, album_img_url, songmid);
} else {
fetch("/get_album_image", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ singer_name }),
})
.then((response) => response.json())
.then((data) => {
if (data.album_img_url) {
album_img_url = data.album_img_url;
createSongElement(
music_name,
singer_name,
album_img_url,
songmid
);
} else {
console.log("Error fetching album image:", data.error);
}
})
.catch((error) => {
console.error("Error fetching album image:", error);
});
}
function createSongElement(
music_name,
singer_name,
album_img_url,
songmid
) {
const songDiv = document.createElement("div");
songDiv.classList.add("song");
songDiv.innerHTML = `
<img src="${album_img_url}" alt="${music_name}" class="song-image">
<div class="song-info">
<div class="song-title">${music_name}</div>
<div class="song-artist">${singer_name}</div>
</div>
`;
songDiv.addEventListener("click", () => {
fetch("/song_clicked", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
music_name,
singer_name,
album_img_url,
songmid,
}),
})
.then((response) => response.json())
.then((data) => {
if (data.status === "success") {
fetch("/set_current_song", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
album_img_url: album_img_url,
music_name: music_name,
singer_name: singer_name,
is_playing: true,
}),
})
.then((response) => response.json())
.then((updateResponse) => {
// console.log("Current song updated:", updateResponse);
});
togglePlayStop(true);
const miniPlayerImage = document.querySelector(
".mini-player .mini-player-image"
);
const miniPlayerTitle = document.querySelector(
".mini-player .song-title"
);
const miniPlayerArtist = document.querySelector(
".mini-player .song-artist"
);
miniPlayerImage.src = album_img_url;
miniPlayerImage.alt = music_name;
miniPlayerTitle.textContent = music_name;
miniPlayerArtist.textContent = singer_name;
const fullPlayerImage = document.querySelector(
".full-player .full-player-image"
);
const fullPlayerTitle = document.querySelector(
".full-player .full-player-title"
);
const fullPlayerArtist = document.querySelector(
".full-player .full-player-artist"
);
fullPlayerImage.src = album_img_url.replace(
"T002R180x180M000",
"T002R300x300M000"
);
fullPlayerImage.alt = music_name;
fullPlayerTitle.textContent = music_name;
fullPlayerArtist.textContent = singer_name;
} else {
// console.log(data.message);
}
});
});
musicList.appendChild(songDiv);
}
});
}
async function getMusicData() {
try {
const response = await fetch("/get_music_data");
const data = await response.json();
const musicList = document.getElementById("music-list");
const miniPlayerImage = document.querySelector(
".mini-player .mini-player-image"
);
const miniPlayerTitle = document.querySelector(
".mini-player .song-title"
);
const miniPlayerArtist = document.querySelector(
".mini-player .song-artist"
);
const fullPlayerImage = document.querySelector(
".full-player .full-player-image"
);
const fullPlayerTitle = document.querySelector(
".full-player .full-player-title"
);
const fullPlayerArtist = document.querySelector(
".full-player .full-player-artist"
);
createSongElements(data, musicList);
} catch (error) {
console.error("Error fetching music data:", error);
}
}
async function fetchPlaylists() {
try {
const response = await fetch("/get_playlists");
const playlists = await response.json();
// console.log(playlists);
const playlistImages = document.getElementById("playlists");
playlistImages.innerHTML = ""; // Clear existing playlists
playlists.forEach((playlist) => {
const playlistDiv = document.createElement("div");
playlistDiv.classList.add("playlist-image-wrapper");
// 从playlist的diss_info中获取dissname和logo的URL
const { dissname, logo } = playlist.diss_info;
const music_info_list = playlist.music_info_list;
const categoryId = playlist.diss_info.categoryId; // 添加获取categoryId
playlistDiv.innerHTML = `
<img src="${logo}" alt="${dissname}" class="playlist-image">
<div class="playlist-title">${dissname}</div>
<button class="delete-playlist-btn" data-category-id="${categoryId}"></button>
`;
playlistDiv.addEventListener("click", function (e) {
// 如果点击的是删除按钮,不触发歌单点击事件
if (e.target.closest(".delete-playlist-btn")) {
return;
}
document.querySelector(".playlist-page").classList.add("show");
// 清空当前音乐列表
const musicList = document.getElementById("playlist-music-list");
musicList.innerHTML = "";
// 加载新的音乐列表
createSongElements(music_info_list, musicList, true);
});
// 添加删除按钮的点击事件
const deleteBtn = playlistDiv.querySelector(".delete-playlist-btn");
deleteBtn.addEventListener("click", async function (e) {
e.stopPropagation();
const categoryId = this.dataset.categoryId;
try {
const response = await fetch("/delete_playlist", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ categoryId }),
});
const result = await response.json();
if (result.status === "success") {
playlistDiv.classList.add("deleting");
setTimeout(() => {
playlistDiv.remove();
}, 300);
let songListDeleteSuccessText = await getPopupText(
songListDeleteSuccessText
);
showPopup(songListDeleteSuccessText);
} else {
let songListDeleteFailText = await getPopupText(
songListDeleteFailText
);
showPopup(songListDeleteFailText + result.message);
}
} catch (error) {
console.error("Error deleting playlist:", error);
let songListDeleteFailText = await getPopupText(
songListDeleteFailText
);
showPopup(songListDeleteFailText);
}
});
playlistImages.appendChild(playlistDiv);
});
} catch (error) {
console.error("Error fetching playlists:", error);
let getSongListFailText = await getPopupText(getSongListFailText);
showPopup(getSongListFailText);
}
}
// 执行搜索函数
function performSearch() {
const searchInput = document.querySelector(".search-input");
const searchTerm = searchInput.value.trim();
document.querySelector(".search-box").style.display = "none";
fetch("/search", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ term: searchTerm }),
})
.then((response) => response.json())
.then((data) => {
// console.log("搜索结果:", data);
document.querySelector(".playlist-page").classList.add("show");
// 清空当前音乐列表
const musicList = document.getElementById("playlist-music-list");
musicList.innerHTML = "";
// 加载新的音乐列表
createSongElements(data, musicList);
})
.catch((error) => {
console.error("请求出错:", error);
});
}
document.addEventListener("DOMContentLoaded", function () {
let isEditing = false;
// 编辑按钮点击事件
document
.querySelector(".edit-playlist-btn")
.addEventListener("click", async function () {
isEditing = !isEditing;
const playlistsContainer = document.getElementById("playlists");
if (isEditing) {
playlistsContainer.classList.add("editing");
let closeHintText = await getPopupText(closeHintText);
showPopup(closeHintText);
} else {
playlistsContainer.classList.remove("editing");
}
});
// Add playlist button click handler
document
.querySelector(".add-playlist-btn")
.addEventListener("click", function () {
document.getElementById("playlist-image-upload").click();
});
// Handle file upload
document
.getElementById("playlist-image-upload")
.addEventListener("change", function (e) {
const file = e.target.files[0];
if (file) {
const formData = new FormData();
formData.append("image", file);
fetch("/upload_playlist_image", {
method: "POST",
body: formData,
})
.then((response) => response.json())
.then(async (data) => {
if (data.status === "success") {
// Refresh playlists
document.getElementById("playlists").innerHTML = "";
fetchPlaylists();
let addSongListSuccessText = await getPopupText(
addSongListSuccessText
);
showPopup(addSongListSuccessText);
} else {
let addSongListFailText = await getPopupText(
addSongListFailText
);
showPopup(addSongListFailText + data.message);
}
})
.catch(async (error) => {
console.error("Error:", error);
let uploadImgFailText = await getPopupText(
"uploadImgFailText"
);
showPopup(uploadImgFailText);
});
}
});
getMusicData();
fetchPlaylists();
const searchButton = document.querySelector(".start-search");
const searchInput = document.querySelector(".search-input");
// 点击按钮执行搜索
searchButton.addEventListener("click", performSearch);
// 按下 Enter 键执行搜索
searchInput.addEventListener("keypress", function (e) {
if (e.key === "Enter") {
performSearch();
}
});
// 监听输入框的输入事件,在移动端可能点击搜索按钮时触发
searchInput.addEventListener("input", function (e) {
// 检查输入框的输入值是否以搜索按钮触发的方式完成
if (e.inputType === "insertText" && e.data === null) {
performSearch();
}
});
const socket = io();
// 监听来自服务器的 current_song 事件
socket.on("current_song", function (data) {
const { album_img_url, music_name, singer_name, is_playing } = data;
// 更新播放器界面
const miniPlayerImage = document.querySelector(
".mini-player .mini-player-image"
);
const miniPlayerTitle = document.querySelector(
".mini-player .song-title"
);
const miniPlayerArtist = document.querySelector(
".mini-player .song-artist"
);
const fullPlayerImage = document.querySelector(
".full-player .full-player-image"
);
const fullPlayerTitle = document.querySelector(
".full-player .full-player-title"
);
const fullPlayerArtist = document.querySelector(
".full-player .full-player-artist"
);
miniPlayerImage.src = album_img_url;
miniPlayerImage.alt = music_name;
miniPlayerTitle.textContent = music_name;
miniPlayerArtist.textContent = singer_name;
fullPlayerImage.src = album_img_url;
// fullPlayerImage.src = album_img_url.replace("T002R180x180M000", "T002R300x300M000");
fullPlayerImage.alt = music_name;
fullPlayerTitle.textContent = music_name;
fullPlayerArtist.textContent = singer_name;
// 根据播放状态更新播放/暂停按钮
togglePlayStop(is_playing);
});
var musicLength = 0;
socket.on("music_status", function (data) {
musicLength = data.length;
position = data.position;
if (position < 0) {
position = 0;
}
if (position > musicLength) {
position = musicLength;
}
// console.log(data.position,musicLength)
var progress = (position / musicLength) * 100;
$(".progress").css("width", progress + "%");
var currentMinutes = Math.floor(position / 60);
var currentSeconds = Math.floor(position % 60);
$("#current-time").text(
currentMinutes +
":" +
(currentSeconds < 10 ? "0" : "") +
currentSeconds
);
var totalMinutes = Math.floor(musicLength / 60);
var totalSeconds = Math.floor(musicLength % 60);
$("#total-time").text(
totalMinutes + ":" + (totalSeconds < 10 ? "0" : "") + totalSeconds
);
});
$(".progress-bar").click(function (e) {
var offset = $(this).offset();
var width = $(this).width();
var clickX = e.pageX - offset.left;
var percentage = clickX / width;
var newPosition = percentage * musicLength;
socket.emit("seek_music", newPosition);
});
updatePlayStatus();
});
// Add popup function
function showPopup(message) {
const popupElement = document.getElementById("popup");
popupElement.textContent = message;
popupElement.classList.add("show");
popupElement.classList.remove("hide");
setTimeout(() => {
popupElement.classList.add("hide");
setTimeout(() => {
popupElement.classList.remove("show");
}, 300);
}, 2000);
}
</script>
</body>
</html>