想你的时候问月亮(DJ 版)-孙艺棋
本帖最后由 亚伦影音工作室 于 2025-9-17 18:33 编辑 <br /><br /><style>#bj {position: relative;
width: 1286px;
height: 720px;
margin-left: -300px;
margin-top: 120px;
overflow: hidden;z-index:12345;
background: ;
}
.intro {margin: 0px0px;z-index:1;
width: 100%;
height:100%;
position: absolute;
background:radial-gradient(ellipse farthest-corner at center center, transparent 38%,#000 90%),url(https://pic1.imgdb.cn/item/68ca5f03c5157e1a88118a50.webp),linear-gradient(135deg, #e56420, #c22525, #3d9c31, #000078);
background-size: cover;
animation: hue-rotate 1s linear infinite;
}
.stop.intro{animation-play-state: paused;}
@keyframes hue-rotate {
from {
filter: hue-rotate(0);
}
to {
filter: hue-rotate(360deg);
}
}
video::-webkit-media-controls-enclosure{ display: none;}
.lyrics{margin: 0;z-index: 6;
top: 89%;
left: 50%;
transform: translate(-50%, -50%);
height: 100px; /* 调整高度,只容纳当前歌词 */
text-align: center;
position: absolute;
}
.lyric-line{
width: 100%;
position: relative;
height: 60px;
overflow: visible;
font: 300 50px '华文隶书', sans-serif;
line-height: 60px;
text-align: left;
white-space: nowrap; /* 禁止换行 */
filter: drop-shadow(#fff 1px 0 0) drop-shadow(#fff 0 1px 0) drop-shadow(#fff -1px 0 0) drop-shadow(#fff 0 -1px 0);
}
.lyric-mask {
position: absolute;
top: 0;
left: 0;
width: 0;
overflow: hidden;
color: #8B4513;
height: 100%;
white-space: nowrap;
}
.lyric-original {
color: #ag0000;
white-space: nowrap;
}
#bfqbnt{ width: 300px;height: 160px;position: absolute; top:90%; left: 5%;overflow: hidden;z-index: 13;}
.start{color: #fff;position: absolute; top:14px; left: 26px;z-index: 3;}
.end{color: #fff;position: absolute;top:14px; left: 150px;z-index: 3;}
#btn{background: url(https://pic.imgdb.cn/item/675813f6d0e0a243d4e14a48.png) no-repeat 0px 0px/cover;width:50px;height: 50px;left: 80px; top: 2px;position: absolute;z-index: 20;}
#prog {position: absolute;z-index: 13;
width: 210px;
height: 2px;background:#ccc;
cursor: pointer;
top:54px;
left:0%;
border-radius: 1px;}
#prog-bar {
height: 100%;
background: #FF0000;
width: 0%;
}
</style>
<divid="bj">
<video id="audio" src="https://file.uhsea.com/2509/b7f68b41a7d496da58de78d668e545c78E.mp4" autoplay loop controls style="width: 100%; height: 100%;z-index:2;position: absolute;left: 0%;top:0%;object-fit: cover; pointer-events: none;mix-blend-mode:lighten;"></video>
<div class='intro'></div>
<div id='bfqbnt'>
<span class="start">00:00</span><p id="btn"></p><span class="end">00:00</span>
<div id="prog" title="播放进度条"><div id="prog-bar"></div></div>
</div>
<div class="lyrics" >
<div class="lyric-line">
<div class="lyric-mask"></div>
<div class="lyric-original"></div>
</div>
</div>
</div>
<script>
// 歌词解析ksc歌词或lrc歌词
const lrc = `想你的时候问月亮(DJ 版)-孙艺棋
作词Lyricist: 党明毅| 一只舟
作曲Composer: 一只舟
编曲Arranger:DJ 默涵
想你的夜晚总是很漫长
萧萧的冷风还带着寒霜
远隔千里你身处在他乡
苦苦滋味我独自去品尝
问问月亮思念它有多长
你是否也会把我去守望
无法忘掉你旧时的模样
想你的心伴着淡淡忧伤
相思的泪水在不停流淌
只有默默的遥望着远方
把那相思的苦深深埋藏
等你在那曾经的老地方
亲爱的你不知现在怎样
夜深人静时是否把我想
月亮恰似你那甜美脸庞
想你的时候只能问月亮
想你的夜晚总是很漫长
萧萧的冷风还带着寒霜
远隔千里你身处在他乡
苦苦滋味我独自去品尝
问问月亮思念它有多长
你是否也会把我去守望
无法忘掉你旧时的模样
想你的心伴着淡淡忧伤
相思的泪水在不停流淌
只有默默的遥望着远方
把那相思的苦深深埋藏
等你在那曾经的老地方
亲爱的你不知现在怎样
夜深人静时是否把我想
月亮恰似你那甜美脸庞
想你的时候只能问月亮
相思的泪水在不停流淌
只有默默的遥望着远方
把那相思的苦深深埋藏
等你在那曾经的老地方
亲爱的你不知现在怎样
夜深人静时是否把我想
月亮恰似你那甜美脸庞
想你的时候只能问月亮
月亮恰似你那甜美脸庞
想你的时候只能问月亮
`;
const audio = document.getElementById('audio');
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>
<script>
const intro= document.querySelector('.intro');
let mState = () => audio.paused ? (intro.classList.add('stop')):(intro.classList.remove('stop'));
audio.addEventListener('play', () => mState());
audio.addEventListener('pause', () => mState());
btn.onclick = () => audio.paused ? (audio.play(), btn.style.background = 'url(https://pic.imgdb.cn/item/675813f6d0e0a243d4e14a48.png) no-repeat 0px 0px/cover') : (audio.pause(), btn.style.background = 'url(https://pic.imgdb.cn/item/675813e7d0e0a243d4e14a18.png) no-repeat 0px 0px/cover');
const start = document.querySelector('.start')
const end= document.querySelector('.end')
function conversion (value) {
let minute = Math.floor(value / 60)
minute = minute.toString().length === 1 ? ('0' + minute) : minute
let second = Math.round(value % 60)
second = second.toString().length === 1 ? ('0' + second) : second
return `${minute}:${second}`
}
audio.onloadedmetadata = function () {
end.innerHTML = conversion(audio.duration)
start.innerHTML = conversion(audio.currentTime)
}
setInterval(() => {
start.innerHTML = conversion(audio.currentTime)
}, 1000)
prog.onclick = (e) => { audio.currentTime = audio.duration * e.offsetX / prog.offsetWidth; }
var progBar = document.getElementById('prog-bar');
audio.addEventListener('timeupdate', () => {
const percent = (audio.currentTime / audio.duration) * 100;
progBar.style.width = percent + '%';
});
</script>
漂亮!谢谢亚伦老师精彩分享{:4_191:} 本帖最后由 彩云归 于 2025-9-17 18:37 编辑
欣赏佳作! 漂亮的频谱效果,欣赏亚伦老师好帖{:4_199:} 又是歌词配的视频歌曲呢{:4_204:} 这个也是频谱视频,亚纶运用的很完美{:4_199:}
页:
[1]