修改圆形图,修改对话框标题内容。
This commit is contained in:
parent
62de130228
commit
146a96c6a6
@ -29,7 +29,6 @@ export class AudioPlayerComponent {
|
|||||||
this.createPlayerHTML();
|
this.createPlayerHTML();
|
||||||
this.initializeElements();
|
this.initializeElements();
|
||||||
this.setupEventListeners();
|
this.setupEventListeners();
|
||||||
this.setupCanvas();
|
|
||||||
this.initializeAudioContext();
|
this.initializeAudioContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ export class AudioPlayerComponent {
|
|||||||
|
|
||||||
<!-- 可视化效果 -->
|
<!-- 可视化效果 -->
|
||||||
<div class="visualization-section" style="display: ${this.options.showVisualization ? 'block' : 'none'};">
|
<div class="visualization-section" style="display: ${this.options.showVisualization ? 'block' : 'none'};">
|
||||||
<canvas id="visualizer" width="100%" height="100%"></canvas>
|
<canvas id="visualizer"></canvas>
|
||||||
<div class="visualization-controls">
|
<div class="visualization-controls">
|
||||||
<button class="viz-btn active" data-mode="bars">条形图</button>
|
<button class="viz-btn active" data-mode="bars">条形图</button>
|
||||||
<button class="viz-btn" data-mode="wave">波形图</button>
|
<button class="viz-btn" data-mode="wave">波形图</button>
|
||||||
@ -171,20 +170,6 @@ export class AudioPlayerComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setupCanvas() {
|
|
||||||
if (!this.canvas) return;
|
|
||||||
|
|
||||||
const resizeCanvas = () => {
|
|
||||||
const container = this.canvas.parentElement;
|
|
||||||
const rect = container.getBoundingClientRect();
|
|
||||||
this.canvas.width = Math.min(600, rect.width - 40);
|
|
||||||
this.canvas.height = 300;
|
|
||||||
};
|
|
||||||
|
|
||||||
resizeCanvas();
|
|
||||||
window.addEventListener('resize', resizeCanvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeAudioContext() {
|
initializeAudioContext() {
|
||||||
try {
|
try {
|
||||||
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
@ -655,11 +640,38 @@ export class AudioPlayerComponent {
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新歌曲标题的方法
|
// 更新歌曲标题的方法 - 从媒体信息获取
|
||||||
updateSongTitle() {
|
updateSongTitle() {
|
||||||
if (!this.currentAudioUrl) return;
|
if (!this.currentAudioUrl) return;
|
||||||
|
|
||||||
// 从URL中提取歌曲信息
|
// 尝试从音频文件的媒体信息中获取歌曲信息
|
||||||
|
this.extractAudioMetadata(this.currentAudioUrl).then(metadata => {
|
||||||
|
// 触发自定义事件,通知外部更新标题
|
||||||
|
const event = new CustomEvent('songLoaded', {
|
||||||
|
detail: {
|
||||||
|
title: metadata.title || '未知歌曲',
|
||||||
|
artist: metadata.artist || '未知艺术家',
|
||||||
|
album: metadata.album || '',
|
||||||
|
url: this.currentAudioUrl
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 从播放器容器向上冒泡事件
|
||||||
|
if (this.container && this.container.parentNode) {
|
||||||
|
this.container.parentNode.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Failed to extract audio metadata:', error);
|
||||||
|
// 失败时回退到从URL提取
|
||||||
|
this.extractTitleFromUrl();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从URL提取歌曲信息的回退方法
|
||||||
|
extractTitleFromUrl() {
|
||||||
|
if (!this.currentAudioUrl) return;
|
||||||
|
|
||||||
|
// 从URL中提取歌曲信息作为回退
|
||||||
let title = '未知歌曲';
|
let title = '未知歌曲';
|
||||||
try {
|
try {
|
||||||
const urlParts = this.currentAudioUrl.split('/');
|
const urlParts = this.currentAudioUrl.split('/');
|
||||||
@ -668,13 +680,15 @@ export class AudioPlayerComponent {
|
|||||||
const nameWithoutQuery = decodedFilename.split('?')[0];
|
const nameWithoutQuery = decodedFilename.split('?')[0];
|
||||||
title = nameWithoutQuery.split('.')[0].replace(/[-_]/g, ' ').trim();
|
title = nameWithoutQuery.split('.')[0].replace(/[-_]/g, ' ').trim();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to extract song title:', e);
|
console.error('Failed to extract song title from URL:', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触发自定义事件,通知外部更新标题
|
// 触发自定义事件,通知外部更新标题
|
||||||
const event = new CustomEvent('songLoaded', {
|
const event = new CustomEvent('songLoaded', {
|
||||||
detail: {
|
detail: {
|
||||||
title: title,
|
title: title,
|
||||||
|
artist: '',
|
||||||
|
album: '',
|
||||||
url: this.currentAudioUrl
|
url: this.currentAudioUrl
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -685,6 +699,133 @@ export class AudioPlayerComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从音频文件提取元数据
|
||||||
|
async extractAudioMetadata(url) {
|
||||||
|
try {
|
||||||
|
// 创建AudioContext
|
||||||
|
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
|
||||||
|
// 获取音频文件
|
||||||
|
const response = await fetch(url, { mode: 'cors' });
|
||||||
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
|
|
||||||
|
// 解码音频数据
|
||||||
|
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
||||||
|
|
||||||
|
// 尝试提取ID3标签信息
|
||||||
|
const metadata = this.parseID3Tags(arrayBuffer);
|
||||||
|
|
||||||
|
// 关闭AudioContext
|
||||||
|
audioContext.close();
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error extracting audio metadata:', error);
|
||||||
|
return { title: '', artist: '', album: '' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析ID3标签
|
||||||
|
parseID3Tags(arrayBuffer) {
|
||||||
|
const metadata = { title: '', artist: '', album: '' };
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dv = new DataView(arrayBuffer);
|
||||||
|
let offset = 0;
|
||||||
|
let header = '';
|
||||||
|
|
||||||
|
// 检查是否有ID3标签
|
||||||
|
if (dv.getUint8(0) === 0x49 && dv.getUint8(1) === 0x44 && dv.getUint8(2) === 0x33) {
|
||||||
|
// 跳过ID3头
|
||||||
|
offset += 10;
|
||||||
|
|
||||||
|
// 读取帧
|
||||||
|
while (offset < arrayBuffer.byteLength) {
|
||||||
|
// 读取帧头
|
||||||
|
const frameId = String.fromCharCode(
|
||||||
|
dv.getUint8(offset),
|
||||||
|
dv.getUint8(offset + 1),
|
||||||
|
dv.getUint8(offset + 2),
|
||||||
|
dv.getUint8(offset + 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 读取帧大小
|
||||||
|
const frameSize =
|
||||||
|
(dv.getUint8(offset + 4) << 21) +
|
||||||
|
(dv.getUint8(offset + 5) << 14) +
|
||||||
|
(dv.getUint8(offset + 6) << 7) +
|
||||||
|
dv.getUint8(offset + 7);
|
||||||
|
|
||||||
|
// 读取帧标志
|
||||||
|
offset += 10;
|
||||||
|
|
||||||
|
// 读取帧内容
|
||||||
|
if (frameId === 'TIT2') {
|
||||||
|
metadata.title = this.decodeID3Text(dv, offset, frameSize);
|
||||||
|
} else if (frameId === 'TPE1') {
|
||||||
|
metadata.artist = this.decodeID3Text(dv, offset, frameSize);
|
||||||
|
} else if (frameId === 'TALB') {
|
||||||
|
metadata.album = this.decodeID3Text(dv, offset, frameSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += frameSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing ID3 tags:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解码ID3文本
|
||||||
|
decodeID3Text(dv, offset, length) {
|
||||||
|
try {
|
||||||
|
// 检查编码方式 (0: ISO-8859-1, 1: UTF-16 with BOM, 2: UTF-16BE, 3: UTF-8)
|
||||||
|
const encoding = dv.getUint8(offset);
|
||||||
|
offset += 1;
|
||||||
|
length -= 1;
|
||||||
|
|
||||||
|
let text = '';
|
||||||
|
|
||||||
|
if (encoding === 0) {
|
||||||
|
// ISO-8859-1
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
const charCode = dv.getUint8(offset + i);
|
||||||
|
if (charCode === 0) break; // 结束符
|
||||||
|
text += String.fromCharCode(charCode);
|
||||||
|
}
|
||||||
|
} else if (encoding === 1 || encoding === 2) {
|
||||||
|
// UTF-16
|
||||||
|
const littleEndian = encoding === 1;
|
||||||
|
if (littleEndian) {
|
||||||
|
// 跳过BOM
|
||||||
|
offset += 2;
|
||||||
|
length -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i += 2) {
|
||||||
|
const charCode = littleEndian ?
|
||||||
|
(dv.getUint8(offset + i + 1) << 8) + dv.getUint8(offset + i) :
|
||||||
|
(dv.getUint8(offset + i) << 8) + dv.getUint8(offset + i + 1);
|
||||||
|
if (charCode === 0) break; // 结束符
|
||||||
|
text += String.fromCharCode(charCode);
|
||||||
|
}
|
||||||
|
} else if (encoding === 3) {
|
||||||
|
// UTF-8
|
||||||
|
const uint8Array = new Uint8Array(dv.buffer, offset, length);
|
||||||
|
text = new TextDecoder('utf-8').decode(uint8Array);
|
||||||
|
// 移除可能的结束符
|
||||||
|
text = text.replace(/\u0000.*$/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return text.trim();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error decoding ID3 text:', error);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleAudioError(error) {
|
handleAudioError(error) {
|
||||||
console.error('音频加载错误详情:', {
|
console.error('音频加载错误详情:', {
|
||||||
error: error,
|
error: error,
|
||||||
@ -872,33 +1013,63 @@ export class AudioPlayerComponent {
|
|||||||
drawCircle() {
|
drawCircle() {
|
||||||
if (!this.ctx || !this.canvas) return;
|
if (!this.ctx || !this.canvas) return;
|
||||||
|
|
||||||
this.ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
|
this.ctx.fillStyle = 'rgb(0, 0, 0)';
|
||||||
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
||||||
|
|
||||||
const centerX = this.canvas.width / 2;
|
// 获取画布的实际显示尺寸(考虑设备像素比)
|
||||||
const centerY = this.canvas.height / 2;
|
const displayWidth = this.canvas.width / window.devicePixelRatio;
|
||||||
const radius = Math.min(centerX, centerY) - 50;
|
const displayHeight = this.canvas.height / window.devicePixelRatio;
|
||||||
|
|
||||||
for (let i = 0; i < this.bufferLength; i++) {
|
// 圆心位置在画布中央
|
||||||
|
const centerX = displayWidth / 2 + Math.min(displayWidth,displayHeight) / 4; //增加一点偏移量
|
||||||
|
const centerY = displayHeight / 2;
|
||||||
|
|
||||||
|
// 缩小圆形图大小,使用较小的半径
|
||||||
|
const baseRadius = Math.min(centerX, centerY) * 0.5; // 从0.8改为0.5,缩小一半
|
||||||
|
const maxAmplitude = Math.min(centerX, centerY) * 0.5; // 最大振幅也相应缩小
|
||||||
|
|
||||||
|
// 绘制内部基础圆形(可选,增加层次感)
|
||||||
|
this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
|
||||||
|
this.ctx.lineWidth = 1;
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(centerX, centerY, baseRadius, 0, 2 * Math.PI);
|
||||||
|
this.ctx.stroke();
|
||||||
|
|
||||||
|
// 绘制频谱线条
|
||||||
|
const step = Math.max(1, Math.floor(this.bufferLength / 128)); // 减少线条数量,提高性能
|
||||||
|
|
||||||
|
for (let i = 0; i < this.bufferLength; i += step) {
|
||||||
const angle = (i / this.bufferLength) * Math.PI * 2;
|
const angle = (i / this.bufferLength) * Math.PI * 2;
|
||||||
const barHeight = (this.dataArray[i] / 255) * radius;
|
const amplitude = (this.dataArray[i] / 255) * maxAmplitude;
|
||||||
|
|
||||||
const x1 = centerX + Math.cos(angle) * radius;
|
// 起始点(基础圆上)
|
||||||
const y1 = centerY + Math.sin(angle) * radius;
|
const x1 = centerX + Math.cos(angle) * baseRadius;
|
||||||
const x2 = centerX + Math.cos(angle) * (radius + barHeight);
|
const y1 = centerY + Math.sin(angle) * baseRadius;
|
||||||
const y2 = centerY + Math.sin(angle) * (radius + barHeight);
|
|
||||||
|
|
||||||
const gradient = this.ctx.createLinearGradient(x1, y1, x2, y2);
|
// 结束点(根据频率数据延伸)
|
||||||
gradient.addColorStop(0, '#667eea');
|
const x2 = centerX + Math.cos(angle) * (baseRadius + amplitude);
|
||||||
gradient.addColorStop(1, '#764ba2');
|
const y2 = centerY + Math.sin(angle) * (baseRadius + amplitude);
|
||||||
|
|
||||||
this.ctx.strokeStyle = gradient;
|
// 根据频率数据计算颜色
|
||||||
this.ctx.lineWidth = 3;
|
const intensity = this.dataArray[i] / 255;
|
||||||
|
const hue = (i / this.bufferLength) * 360; // 彩虹色调
|
||||||
|
const saturation = 80 + (intensity * 20); // 饱和度随强度变化
|
||||||
|
const lightness = 40 + (intensity * 40); // 亮度随强度变化
|
||||||
|
|
||||||
|
this.ctx.strokeStyle = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
||||||
|
this.ctx.lineWidth = 1.5 + (intensity * 1.5); // 线条宽度随强度变化
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
this.ctx.moveTo(x1, y1);
|
this.ctx.moveTo(x1, y1);
|
||||||
this.ctx.lineTo(x2, y2);
|
this.ctx.lineTo(x2, y2);
|
||||||
this.ctx.stroke();
|
this.ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绘制中心点(可选,增加视觉焦点)
|
||||||
|
this.ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(centerX, centerY, 2, 0, 2 * Math.PI);
|
||||||
|
this.ctx.fill();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 工具方法
|
// 工具方法
|
||||||
@ -998,10 +1169,16 @@ export function createAudioPlayerDialog(options = {}) {
|
|||||||
titleBar.className = 'dialog-title-bar';
|
titleBar.className = 'dialog-title-bar';
|
||||||
|
|
||||||
// 创建歌曲信息区域
|
// 创建歌曲信息区域
|
||||||
const songInfo = document.createElement('div');
|
const songInfo = document.createElement('div');
|
||||||
songInfo.className = 'song-info';
|
songInfo.className = 'song-info';
|
||||||
songInfo.innerHTML = '<div class="song-title">正在播放</div><div class="song-url"></div>';
|
songInfo.innerHTML = `
|
||||||
titleBar.appendChild(songInfo);
|
<div class="song-main-info">
|
||||||
|
<span class="song-title">正在播放</span>
|
||||||
|
<span class="song-artist"></span>
|
||||||
|
<span class="song-album"></span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
titleBar.appendChild(songInfo);
|
||||||
|
|
||||||
// 创建关闭按钮
|
// 创建关闭按钮
|
||||||
const closeBtn = document.createElement('button');
|
const closeBtn = document.createElement('button');
|
||||||
@ -1013,6 +1190,7 @@ export function createAudioPlayerDialog(options = {}) {
|
|||||||
|
|
||||||
// 创建播放器容器
|
// 创建播放器容器
|
||||||
const playerContainer = document.createElement('div');
|
const playerContainer = document.createElement('div');
|
||||||
|
playerContainer.className="player-dialog-component";
|
||||||
dialog.appendChild(playerContainer);
|
dialog.appendChild(playerContainer);
|
||||||
|
|
||||||
document.body.appendChild(dialog);
|
document.body.appendChild(dialog);
|
||||||
@ -1021,9 +1199,10 @@ export function createAudioPlayerDialog(options = {}) {
|
|||||||
const player = new AudioPlayerComponent(playerContainer, mergedOptions);
|
const player = new AudioPlayerComponent(playerContainer, mergedOptions);
|
||||||
|
|
||||||
// 更新歌曲信息的方法
|
// 更新歌曲信息的方法
|
||||||
const updateSongInfo = (url, title = null) => {
|
const updateSongInfo = (url, title = null, artist = null, album = null) => {
|
||||||
const songTitle = songInfo.querySelector('.song-title');
|
const songTitle = songInfo.querySelector('.song-title');
|
||||||
const songUrl = songInfo.querySelector('.song-url');
|
const songArtist = songInfo.querySelector('.song-artist');
|
||||||
|
const songAlbum = songInfo.querySelector('.song-album');
|
||||||
|
|
||||||
// 从URL中提取歌曲名称(如果可能)
|
// 从URL中提取歌曲名称(如果可能)
|
||||||
let finalTitle = title || '未知歌曲';
|
let finalTitle = title || '未知歌曲';
|
||||||
@ -1039,8 +1218,10 @@ export function createAudioPlayerDialog(options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新标题和艺术家信息
|
||||||
songTitle.textContent = finalTitle;
|
songTitle.textContent = finalTitle;
|
||||||
songUrl.textContent = url || '';
|
songArtist.textContent = artist ? ` - ${artist}` : '';
|
||||||
|
songAlbum.textContent = album ? ` | ${album}` : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听加载事件更新歌曲信息
|
// 监听加载事件更新歌曲信息
|
||||||
@ -1052,8 +1233,8 @@ export function createAudioPlayerDialog(options = {}) {
|
|||||||
|
|
||||||
// 监听歌曲加载完成事件,更新更准确的标题信息
|
// 监听歌曲加载完成事件,更新更准确的标题信息
|
||||||
dialog.addEventListener('songLoaded', (e) => {
|
dialog.addEventListener('songLoaded', (e) => {
|
||||||
const { title, url } = e.detail;
|
const { title, artist, album, url } = e.detail;
|
||||||
updateSongInfo(url, title);
|
updateSongInfo(url, title, artist, album);
|
||||||
});
|
});
|
||||||
|
|
||||||
closeBtn.addEventListener('click', () => {
|
closeBtn.addEventListener('click', () => {
|
||||||
|
|||||||
@ -84,20 +84,6 @@ body {
|
|||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 可视化区域 */
|
|
||||||
.visualization-section {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#visualizer {
|
|
||||||
border: 2px solid #e0e0e0;
|
|
||||||
border-radius: 15px;
|
|
||||||
background: #000;
|
|
||||||
width: 100%;
|
|
||||||
height: 320px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.visualization-controls {
|
.visualization-controls {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -1123,6 +1109,11 @@ body.loading-active {
|
|||||||
animation: pulse 2s infinite;
|
animation: pulse 2s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.player-dialog-component{
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
/* 音频播放器组件样式 */
|
/* 音频播放器组件样式 */
|
||||||
.audio-player-component {
|
.audio-player-component {
|
||||||
background: rgba(255, 255, 255, 0.95);
|
background: rgba(255, 255, 255, 0.95);
|
||||||
@ -1136,9 +1127,15 @@ body.loading-active {
|
|||||||
/* 可视化区域 */
|
/* 可视化区域 */
|
||||||
.visualization-section {
|
.visualization-section {
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#visualizer {
|
#visualizer {
|
||||||
|
margin: 0 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
@ -1552,6 +1549,24 @@ button:focus-visible {
|
|||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 优化滚动条样式 */
|
||||||
|
.audio-player-dialog > div::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-player-dialog > div::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-player-dialog > div::-webkit-scrollbar-thumb {
|
||||||
|
background: #c1c1c1;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-player-dialog > div::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #a8a8a8;
|
||||||
|
}
|
||||||
|
|
||||||
.audio-player-dialog::backdrop {
|
.audio-player-dialog::backdrop {
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
backdrop-filter: blur(5px);
|
backdrop-filter: blur(5px);
|
||||||
@ -1575,21 +1590,39 @@ button:focus-visible {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.song-main-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
.song-title {
|
.song-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 3px;
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-artist {
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.9;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-album {
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0.8;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.song-url {
|
.song-url {
|
||||||
font-size: 12px;
|
display: none; /* 隐藏URL,改为显示媒体信息 */
|
||||||
opacity: 0.9;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 关闭按钮 */
|
/* 关闭按钮 */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user