亚伦影音工作室 发表于 2024-12-17 10:50

火焰频谱--不愿和你再相遇

本帖最后由 亚伦影音工作室 于 2025-10-23 18:45 编辑 <br /><br /><style>
#papa { margin: 10px 0 20px calc(50% - 721px); background:#800 url('https://pic.imgdb.cn/item/66a34f6ed9c307b7e9581634.jpg')no-repeat center/cover;width: 1286px; height: 720px;   box-shadow: 3px 3px 6px gray; overflow: hidden; z-index: 1; position: relative; display: grid; place-items: center;}

#canv {display: block; position: absolute;width:100%; height:250px; bottom: 0px; left: 0px;z-index:4; animation: sp 1s linear infinite;}
@keyframes sp {
      0% { filter:hue-rotate(360deg)contrast(150%)brightness(80%); }
}

#waibao{position: absolute;top:60%; left:12%;z-index: 44;width: 125px; height: 185px; background: linear-gradient(90deg, #601000, #333, #601000);border: 2px solid #bbb;
border-radius: 5px;
box-shadow: 0px 1px 5px #000;}
#pyie {top:0%; left:0%;z-index: 44;
display: block;position: absolute;
    width: 120px; height: 180px;
    background:url(https://pic.imgdb.cn/item/6752c720d0e0a243d4ded0ba.png)no-repeat center/240px 180px;
animation: burst steps(2) 1s infinite;}
@keyframes burst {0% {background-position: 0px 0;}
100% {background-position: -240px 0;}}
#lrc {--state: paused;--motion: cover2;--tt: 2s;--bg: linear-gradient(0deg, #880000, #880000, #880000);
position: absolute;z-index: 6;left: 50%; top: 90%;transform: translate(-50%);font:normal 2.8em/1em 华文隶书; font-weight:400;color: #000080;white-space: pre;-webkit-background-clip: text;filter:drop-shadow(#FFFFFF 1px 0 0)drop-shadow(#FFFFFF 0 1px 0)drop-shadow(#FFFFFF -1px 0 0) drop-shadow(#FFFFFF 0 -1px0);}
#lrc::before {position: absolute;content: attr(data-lrc);width: 100%; height: 100%;color: transparent;overflow: hidden;white-space: pre;background: var(--bg);clip-path: inset(0 100% 0 0);-webkit-background-clip: text;animation: var(--motion) var(--tt) linear forwards;animation-play-state: var(--state);}
@keyframes cover1{ to { clip-path: inset(0 0 0 0); } }@keyframes cover2 { to { clip-path: inset(0 0 0 0); } }
</style>
<div id="papa">

<div id="waibao" ><div id="pyie" ></div></div>

<canvas id='canv'width="1286" height="250"></canvas>
<div data-lrc="" id="lrc"></div>
</div>
<audio id="aud" src="https://s2.ananas.chaoxing.com/sv-w8/audio/75/36/22/d2c783fc88063f4cd0e823b4d7514e99/audio.mp3" autoplay loop crossOrigin="anonymous"></audio>

<script>
pyie.onclick = () => aud.paused ?aud.play():aud.pause();
aud.addEventListener('play', () => mState());
aud.addEventListener('pause', () => mState());

pyie.style.animationPlayState = aud.paused ? 'paused' : 'running';
aud.addEventListener('playing', () =>pyie.style.animationPlayState = 'running');
aud.addEventListener('pause', () =>pyie.style.animationPlayState = 'paused');
</script>
<script>
(function () {

        let Act = new AudioContext();

        let audSrc = Act.createMediaElementSource(aud);

        let analyser = Act.createAnalyser();

        audSrc.connect(analyser);

        analyser.connect(Act.destination);

        let ctx = canv.getContext('2d');

        let width = canv.width;

        let height = canv.height;

        let ppColor = ctx.createLinearGradient(250,200,250,0);

        ppColor.addColorStop(0.8, '#fff000');

        ppColor.addColorStop(1, '#00ff00');

        ppColor.addColorStop(0.8, '#fff000');

        let ppNum = 1286;

        let voiceHeight = new Uint8Array(analyser.frequencyBinCount);



        (function draw() {

                analyser.getByteFrequencyData(voiceHeight);

                let step = Math.round(voiceHeight.length / ppNum);

                ctx.clearRect(0, 0, width, height);

                for (let j = 0; j < ppNum; j++) {

                        let audiheighteight = voiceHeight;

                        ctx.fillStyle = ppColor;

                        ctx.fillRect(width / 2+ (j * 1), height, 2, -audiheighteight);

                        ctx.fillRect(width / 2- (j * 1), height, 2, -audiheighteight);

                }

                window.requestAnimationFrame(draw);

        })();
})();
</script>
<script >
(function() {
/*原始lrc歌词*/
let lrcStr = `不愿和你再相遇
演唱:肖雨蒙
作词:刘子祥
作曲:刘子祥
编混:艺朵朵文化
和声:雪无影
推广:艺朵朵文化
制作人:刘子祥
出品人:刘子祥
OP/SP:艺朵朵文化
昨日的你就这样离去
我落下了伤心的泪滴
那些点点滴滴
都变成了回忆
就像冷风
阵阵刺痛我的心里
为何一切不能再继续
你像云朵随着风散去
如果时间倒流
不愿和你再相遇
我的心已经被你
伤的彻底
真心的付出全被你抛弃
对你的呵护是一场悲剧
面对这一切真的无能为力
从此以后不会把你提起
为何一切不能再继续
你像云朵随着风散去
如果时间倒流
不愿和你再相遇
我的心已经被你
伤的彻底
真心的付出全被你抛弃
对你的呵护是一场悲剧
面对这一切真的无能为力
从此以后不会把你提起
真心的付出全被你抛弃
对你的呵护是一场悲剧
面对这一切真的无能为力
从此以后不会把你提起

`;
/*变量 :mKey - 当前歌词索引;mFlag :调用关键帧动画索引;averAdd :平均值补偿*/
let mKey = 0, mFlag = true, averAdd = 0.3;

/*函数 :获取每句歌词用时,歌词用时若超过平均值则取平均值,最后一句歌词则取平均值*/
let lrcTime = (ar) => {
        let tmpAr = [];
        for(j = 0; j <ar.length - 1; j ++) {
                if(j !== ar.length - 1) tmpAr = parseFloat((ar - ar).toFixed(1));
        }
        let aver = parseInt(tmpAr.reduce((a,b) => a + b) / (tmpAr.length - 1)) + averAdd;
        tmpAr.push(aver);
        tmpAr.forEach((item,key) => {
                ar = item > aver ? aver : item;
        });
        return ar;
};

/*函数 :从原始lrc歌词获取信息并存入 n*3 数组*/
let getLrcAr = (text) => {
        let lrcAr = [];
        let calcRule = ;
        for(x of text.split('\n')) {
                let ar = [];
                let re = /\d+[\.:]\d+([\.:]\d+)?/g;
                let geci = x.replace(re,'');
                if(geci) {
                        geci = geci.replace(/[\[\]\'\"\t,]s?/g,'');
                        let time = x.match(re);
                        if(time != null) {
                                for(y of time) {
                                        let tmp = y.match(/\d+/g);
                                        let sec = 0;
                                        for(z in tmp) sec += tmp * calcRule;
                                        ar = ;
                                        lrcAr.push(ar);
                                }
                        }
                }
        }
        lrcAr.sort((a,b)=> a - b);
        return(lrcTime(lrcAr));
};

/*函数 :模拟显示同步歌词*/
let showLrc = (time) => {
        let name = mFlag ? 'cover1' : 'cover2';
        lrc.innerHTML = lrcAr;
        lrc.dataset.lrc = lrcAr;
        lrc.style.setProperty('--motion', name);
        lrc.style.setProperty('--tt', time + 's');
        lrc.style.setProperty('--state', 'running');
        mKey += 1;
        mFlag = !mFlag;
};

/*函数 :处理当前歌词索引 mKey*/
let calcKey = () => {
        for (j = 0; j < lrcAr.length; j++) {
                if (aud.currentTime <= lrcAr) {
                        mKey = j - 1;
                        break;
                }
        }
        if (mKey < 0) mKey = 0;
        if (mKey > lrcAr.length - 1) mKey = lrcAr.length - 1;
        let time = lrcAr - (aud.currentTime - lrcAr);
        showLrc(time);
};

/*格式化时间信息*/
let toMin = (val) => {
        if (!val) return '00:00';
        val = Math.floor(val);
        let min = parseInt(val / 60),
        sec = parseFloat(val % 60);
        if (min < 10) min = '0' + min;
        if (sec < 10) sec = '0' + sec;
        return min + ':' + sec;
}

/*函数 :关键帧动画状态切换*/
let mState = () => aud.paused ? (lrc.style.setProperty('--state','paused'),document.style.animationPlayState = 'paused') : (lrc.style.setProperty('--state','running'),document.style.animationPlayState = 'running');

/*监听播放进度*/
aud.addEventListener('timeupdate', () => {
        for (j = 0; j < lrcAr.length; j++) {
                if (aud.currentTime >= lrcAr) {
                        cKey = j;
                        if (mKey === j) showLrc(lrcAr);
                        else continue;
                }
        }
});
aud.addEventListener('pause', () => mState());/*监听暂停事件*/
aud.addEventListener('play', () => mState());/*监听播放事件*/
aud.addEventListener('seeked', () => calcKey());/*监听查询事件*/
let lrcAr = getLrcAr(lrcStr); /*获得歌词数组*/
})();

</script>


小辣椒 发表于 2024-12-17 14:59

看了代码,亚伦很厉害哦,这个频谱用了代码制作,但我电脑代码预览不能出来,

小辣椒 发表于 2024-12-17 14:59

这个播放器也是好卡,不够灵活

小辣椒 发表于 2024-12-17 15:00

欣赏亚伦精彩的制作{:4_199:}

亚伦影音工作室 发表于 2024-12-18 17:37

attach://46423.rar
页: [1]
查看完整版本: 火焰频谱--不愿和你再相遇