本帖最后由 china365love 于 2025-2-20 21:29 编辑
在人生中最重要的婚礼时刻,音乐是营造浪漫与温馨氛围的关键元素。
婚庆音乐管家,专为婚礼打造,是您的理想音乐伴侣。
它提供便捷的婚礼音乐包导入功能,支持多种音频格式,简洁直观的用户界面让操作轻松上手,
点击播放列表歌曲即可一键播放,还支持进度跳转。每首歌曲都配有精美的波形图,
直观展示音乐节奏变化,主波形图实时呈现播放动态,为您带来沉浸式音乐体验。
大飞哥婚庆音乐管家适用于各种婚礼场景,无论是室内豪华婚礼,还是户外清新婚礼,都能提供恰到好处的音乐。 大飞哥软件自习室的专业技术团队运用先进音频处理技术打造这款音乐管家,使其具备强大兼容性,可在多种设备上流畅运行,为您的婚礼音乐播放保驾护航。 选择大飞哥婚庆音乐管家,让音乐成为您婚礼中最动人的旋律,为幸福时刻增添更多美好回忆 。
源码[HTML] 纯文本查看 复制代码 <!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>大飞哥婚庆音乐管家</title>
<style>
.brand-header {
text-align: center;
padding: 15px 0;
background: linear-gradient(135deg, #ff4b4b, #ff8c8c);
color: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
font-size: 1.2em;
}
.brand-header a {
color: #ffd700;
text-decoration: none;
transition: text-shadow 0.3s;
}
.brand-header a:hover {
text-shadow: 0 0 8px rgba(255,215,0,0.6);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f5f5f5; font-family: Arial, sans-serif; }
.controls {
padding: 20px;
background: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
text-align: center;
}
button {
padding: 10px 20px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: opacity 0.3s;
}
button:hover { opacity: 0.9; }
.playlist {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 10px;
padding: 20px;
}
.song-item {
background: white;
padding: 15px;
border-radius: 8px;
cursor: pointer;
transition: transform 0.2s;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.song-item:hover {
transform: translateY(-3px);
}
.waveform {
height: 100px;
background: #f0f0f0;
position: relative;
cursor: pointer;
}
.waveform canvas {
width: 100%;
height: 100%;
}
.player-controls {
position: fixed;
bottom: 0;
width: 100%;
background: white;
padding: 20px;
box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
}
audio { width: 100%; margin-top: 10px; }
</style>
</head>
<body>
<div class="brand-header">
<a href="https://space.bilibili.com/286436365" target="_blank">大飞哥软件自习室</a>荣誉出品
</div>
<div class="controls">
<input type="file" id="folderInput" webkitdirectory directory multiple accept="audio/*" hidden>
<button>🎵 导入婚礼音乐包</button>
</div>
<div class="playlist" id="playlist"></div>
<div class="player-controls">
<div class="waveform" id="waveformContainer">
<canvas id="waveform"></canvas>
</div>
<audio id="audioPlayer" controls></audio>
</div>
<script>
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
let currentTrackIndex = 0;
// 文件导入处理
document.getElementById('folderInput').addEventListener('change', async function(e) {
const files = Array.from(e.target.files).filter(f => f.type.startsWith('audio/'));
const playlist = document.getElementById('playlist');
playlist.innerHTML = files.map(file => `
<div class="song-item" data-url="${URL.createObjectURL(file)}">
<div class="song-title">${file.name.replace(/\.[^/.]+$/, "")}</div>
<div class="waveform"></div>
</div>
`).join('');
// 生成波形图
files.forEach((file, index) => {
const item = playlist.children[index];
drawWaveform(file, item.querySelector('.waveform'));
});
});
// 波形绘制函数
async function drawWaveform(file, container) {
try {
const arrayBuffer = await file.arrayBuffer();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = container.offsetWidth;
canvas.height = 80;
container.appendChild(canvas);
const data = audioBuffer.getChannelData(0);
const step = Math.ceil(data.length / canvas.width);
ctx.fillStyle = '#ff6b6b';
for(let x = 0; x < canvas.width; x++) {
let max = 0;
for(let i = 0; i < step; i++) {
max = Math.max(max, Math.abs(data[(x * step) + i] || 0));
}
const height = max * canvas.height;
ctx.fillRect(x, (canvas.height - height)/2, 1, height);
}
} catch (error) {
console.error('波形绘制失败:', error);
}
}
// 播放控制
document.getElementById('playlist').addEventListener('click', async (e) => {
const item = e.target.closest('.song-item');
if(item) {
const url = item.dataset.url;
const audio = document.getElementById('audioPlayer');
try {
audio.src = url;
await audio.play();
drawMainWaveform(url);
setActiveItem(item);
} catch (error) {
alert('播放失败,请点击播放器控件进行播放');
}
}
});
// 进度跳转
document.getElementById('waveformContainer').addEventListener('click', (e) => {
const audio = document.getElementById('audioPlayer');
if(audio.duration) {
const rect = e.currentTarget.getBoundingClientRect();
const percent = (e.clientX - rect.left) / rect.width;
audio.currentTime = audio.duration * percent;
}
});
// 主波形绘制
async function drawMainWaveform(url) {
try {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
const canvas = document.getElementById('waveform');
const ctx = canvas.getContext('2d');
canvas.width = canvas.offsetWidth;
canvas.height = 100;
ctx.clearRect(0, 0, canvas.width, canvas.height);
const data = audioBuffer.getChannelData(0);
const step = Math.ceil(data.length / canvas.width);
ctx.fillStyle = '#ff4b4b';
for(let x = 0; x < canvas.width; x++) {
let max = 0;
for(let i = 0; i < step; i++) {
max = Math.max(max, Math.abs(data[(x * step) + i] || 0));
}
const height = max * canvas.height;
ctx.fillRect(x, (canvas.height - height)/2, 1, height);
}
} catch (error) {
console.error('主波形绘制失败:', error);
}
}
function setActiveItem(activeItem) {
document.querySelectorAll('.song-item').forEach(item => {
item.style.background = item === activeItem ? '#fff0f0' : 'white';
});
}
</script>
</body>
</html> 软件用浏览器打开在附件下载
|