紧紧拉住月亮的手
本帖最后由 亚伦影音工作室 于 2025-9-19 16:15 编辑 <br /><br /><style>#lyrics{width: 800px;height:80px;position: relative;top:110px; left:0%; background:#0000;z-index: 1;}
.lyrics{margin: 0;
top: 0%;
left: 50%;
transform: translate(-50%, -50%);
height: 100px; /* 调整高度,只容纳当前歌词 */
text-align: center;
position: absolute;
}
.lyric-line{
width: 100%;
position: relative;
height: 60px;
overflow: visible;
font:600 40px 'FZYaoti', sans-serif;
line-height: 60px;
text-align: left;
white-space: nowrap; /* 禁止换行 */
}
.lyric-mask {
position: absolute;
top: 0;
left: 0;
width: 0;
overflow: hidden;
color: #880000;
height: 100%;
white-space: nowrap;
}
.lyric-original {
color: #444;
white-space: nowrap;
}
#jiemian{position: relative;top:250px; left:16%;width:70%;height:50px;z-index: 2;background:#2222;border-radius: 4px;border: 1px solid #000;}
#audio {position: absolute;top:0px; left:0%;width:100%;z-index: 2;filter: invert(0%);}
#audio::-webkit-media-controls-play-button {transform:scale(1.4);}
#audio::-webkit-media-controls-enclosure {background:transparent;
border-radius: 0px;}
#audio::-webkit-media-controls-current-time-display {
order: 1; //设置弹性盒对象元素的顺序
text-shadow: unset;}
#audio::-webkit-media-controls-time-remaining-display {
order:3;text-shadow: unset;}
</style>
<div id="jiemian">
<audio id="audio"autoplay controls >
<source src="https://www.dda5.com/plug/down.php?ac=mp3&id=f8c08c23a7adc001e654919565dfdbac&.mp3" type="audio/mpeg">
</audio>
</div>
<div id="lyrics" >
<div class="lyrics" >
<div class="lyric-line">
<div class="lyric-mask"></div>
<div class="lyric-original"></div>
</div>
</div>
</div>
</br> </br> </br> </br></br> </br> </br> </br>
<script>
// 歌词解析ksc歌词或lrc歌词
const lrc = `。。。。。。
酒那么浓心那么空
那么那么爱你也没有用
情那么真爱那么痛
那么那么想你可是你不懂
风那么冷雨那么凶
你来也匆匆去也匆匆
月儿那么美花儿那么红
我的眼泪那么那么汹涌
我看你看你看得那么重
你伤我伤我伤得那么痛
既然没结果又为何要相逢
不爱我为何要让我心动
我看你看你看得那么重
你伤我伤我伤得那么痛
你给我一场梦又赐我一场空
你不在乎我泪眼朦胧
风那么冷雨那么凶
你来也匆匆去也匆匆
月儿那么美花儿那么红
我的眼泪那么那么汹涌
我看你看你看得那么重
你伤我伤我伤得那么痛
既然没结果又为何要相逢
不爱我为何要让我心动
我看你看你看得那么重
你伤我伤我伤得那么痛
你给我一场梦又赐我一场空
你不在乎我泪眼朦胧
我看你看你看得那么重
你伤我伤我伤得那么痛
既然没结果又为何要相逢
不爱我为何要让我心动
我看你看你看得那么重
你伤我伤我伤得那么痛
你给我一场梦又赐我一场空
你不在乎我泪眼朦胧
`;
const lyrics = parseLyrics(lrc);
const lyricMask = document.querySelector('.lyric-mask');
const lyricOriginal = document.querySelector('.lyric-original');
let currentIndex = -1;
let currentLyric = null;
// 解析歌词(支持两种格式)
function parseLyrics(lrcText) {
const lyrics = [];
if (lrcText.includes('karaoke.add')) {
const lineRegex = /karaoke\.add\('([^']+)', '([^']+)', '([^']+)', '([^']+)'\);/g;
let match;
while ((match = lineRegex.exec(lrcText)) !== null) {
const startTime = timeToMs(match);
const endTime = timeToMs(match);
const text = match.replace(/\[|\]/g, '').trim();
const durations = match.split(',').map(Number);
if (text) {
lyrics.push({startTime, endTime, text, durations});
}
}
}
else if (lrcText.includes('[')) {
const lines = lrcText.split('\n').filter(line => line.trim());
lines.forEach((line, index) => {
const timeMatch = line.match(/\[(\d+:\d+\.\d+)\]/);
if (timeMatch) {
const timeStr = timeMatch;
const text = line.replace(/\[.*?\]/, '').trim();
if (text) {
const startTime = timeToMs(timeStr);
const nextLine = lines;
const nextTimeMatch = nextLine ? nextLine.match(/\[(\d+:\d+\.\d+)\]/) : null;
const endTime = nextTimeMatch ? timeToMs(nextTimeMatch) : startTime + 5000;
lyrics.push({
startTime,
endTime,
text,
durations: calculateCharDurations(text, startTime, endTime)
});
}
}
});
}
return lyrics;
}
function calculateCharDurations(text, startTime, endTime) {
const totalDuration = endTime - startTime;
const charCount = text.length;
const baseDur = Math.floor(totalDuration / charCount);
const durations = new Array(charCount).fill(baseDur);
const remainder = totalDuration % charCount;
for (let i = 0; i < remainder; i++) {
durations++;
}
return durations;
}
function timeToMs(timeStr) {
const parts = timeStr.split(':');
const minutes = parseInt(parts, 10);
const secondsAndMs = parts.split('.');
const seconds = parseInt(secondsAndMs, 10);
const ms = parseInt(secondsAndMs || 0, 10);
return minutes * 60 * 1000 + seconds * 1000 + ms;
}
function getCurrentLyricIndex(lyrics, currentTimeMs) {
for (let i = 0; i < lyrics.length; i++) {
if (currentTimeMs >= lyrics.startTime && currentTimeMs <= lyrics.endTime) {
return i;
}
}
return -1;
}
function updateLyricDisplay(index) {
if (index < 0 || index >= lyrics.length) return;
currentIndex = index;
currentLyric = lyrics;
lyricOriginal.textContent = currentLyric.text;
lyricMask.textContent = currentLyric.text;
lyricMask.style.width = '0%';
}
function updateLyricMask(currentTimeMs) {
if (!currentLyric) return;
const lyricStartTime = currentLyric.startTime;
const elapsed = currentTimeMs - lyricStartTime;
const totalDuration = currentLyric.durations.reduce((sum, d) => sum + d, 0);
let charIndex = 0;
let accumulatedTime = 0;
for (let i = 0; i < currentLyric.durations.length; i++) {
accumulatedTime += currentLyric.durations;
if (elapsed <= accumulatedTime) {
charIndex = i + 1;
break;
}
}
if (elapsed >= totalDuration) {
charIndex = currentLyric.text.length;
}
charIndex = Math.min(charIndex, currentLyric.text.length);
const tempSpan = document.createElement('span');
tempSpan.style.visibility = 'hidden';
tempSpan.style.position = 'absolute';
tempSpan.style.fontSize = '50px';
tempSpan.style.fontWeight = '800';
document.body.appendChild(tempSpan);
const visibleText = currentLyric.text.substring(0, charIndex);
tempSpan.textContent = visibleText;
const width = tempSpan.offsetWidth;
document.body.removeChild(tempSpan);
lyricMask.style.width = `${width}px`;
}
// 监听更新歌词
audio.addEventListener('timeupdate', () => {
const currentTimeMs = audio.currentTime * 1000;
const index = getCurrentLyricIndex(lyrics, currentTimeMs);
if (index !== currentIndex) {
updateLyricDisplay(index);
}
updateLyricMask(currentTimeMs);
});
updateLyricDisplay(0);
</script> 简洁、美观、实用,谢谢亚伦老师精彩分享{:4_191:} 这半透明的播放条功能很完备。歌词同步也很漂亮。
欣赏亚伦老师好帖{:4_199:} 本帖最后由 亚伦影音工作室 于 2025-9-19 16:11 编辑
https://www.dda5.com/plug/down.php?ac=lrc&id=f8c08c23a7adc001e654919565dfdbac&.lrc
欣赏老师的新代码,点赞!
页:
[1]