霜染枫丹 发表于 2025-12-3 20:06

套用马老师代码 《终于把你遇见》

本帖最后由 霜染枫丹 于 2025-12-13 14:03 编辑 <br /><br /><!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>音乐播放器</title>
    <style>
      * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
      }

      body {
            background-color: #fff;
            min-height: 100vh;
            font-family: sans-serif;
            padding: 20px; /* 添加内边距,避免小屏幕时贴边 */
            /* 移除了 display: flex,这可能是导致页面右移的原因 */
      }

      /* 外层容器:确保播放器始终居中 */
      .player-wrapper {
            width: 100%;
            max-width: 1200px; /* 最大宽度限制 */
            margin: 0 auto; /* 水平居中 */
      }

      #pa {
            width: 100%; /* 宽度自适应父容器 */
            height: 675px;
            border: 1px solid #ddd;
            display: grid;
            place-items: center;
            position: relative;
            overflow: hidden;
            border-radius: 8px;
            box-shadow: 0 0 30px rgba(0, 0, 0, 0.1);
            /* 修复居中问题的关键:确保容器正常显示 */
      }

      /* 背景MP4层 */
      #bg-video {
            position: absolute;
            top: 50%; /* 垂直居中 */
            left: 50%; /* 水平居中 */
            width: 100%;
            height: 100%;
            object-fit: cover;
            opacity: 0.6;
            z-index: 0;
            transform: translate(-50%, -50%); /* 修正居中 */
      }

      /* 静态图片层 */
      #bg-image {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-image: url('https://cccimg.com/view.php/8f7191d6c76360c65308a5b525b9f558.jpg');
            background-size: cover;
            background-position: center;
            opacity: 0.8;
            z-index: 1;
      }

      #wrapper {
            position: absolute;
            padding: 10px;
            font: bold 2.5rem/1.5 sans-serif;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
            bottom: 80px;
            z-index: 10;
            text-align: center;
            width: 80%; /* 限制歌词宽度,避免溢出 */
            max-width: 800px;
            left: 50%;
            transform: translateX(-50%); /* 水平居中 */
      }

      .char {
            display: inline-block;
            padding: 0 3px;
            opacity: 0;
            transform: translate(var(--x), var(--y));
            animation: fadeIn 0.3s var(--delay) forwards;
            transition: all 0.3s ease;
      }

      /* 隐藏原生音频控件 */
      audio {
            display: none;
      }

      /* 自定义播放器控制面板 */
      .player-controls {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%); /* 精确水平居中 */
            z-index: 20;
            display: flex;
            align-items: center;
            gap: 15px; /* 调整间距,避免溢出 */
            width: 95%; /* 宽度自适应 */
            max-width: 800px;
            padding: 0 10px;
      }

      .control-btn {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            background-color: rgba(240, 240, 240, 0.8);
            border: 2px solid rgba(100, 100, 100, 0.8);
            color: #333;
            font-size: 24px;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            transition: all 0.3s ease;
            backdrop-filter: blur(5px);
            flex-shrink: 0; /* 防止按钮缩小 */
      }

      .control-btn:hover {
            background-color: rgba(220, 220, 220, 0.8);
            transform: scale(1.1);
      }

      .play-btn {
            width: 70px;
            height: 70px;
            background-color: rgba(255, 105, 180, 0.8);
            border-color: #ff4785;
            color: white;
      }

      .play-btn:hover {
            background-color: rgba(255, 105, 180, 1);
      }

      /* 进度条 */
      .progress-container {
            flex: 1;
            height: 8px;
            background-color: rgba(200, 200, 200, 0.5);
            border-radius: 4px;
            cursor: pointer;
            position: relative;
            min-width: 100px; /* 最小宽度,避免太小时消失 */
      }

      .progress-bar {
            position: absolute;
            top: 0;
            left: 0;
            height: 100%;
            background-color: #ff69b4;
            border-radius: 4px;
            width: 0%;
            transition: width 0.3s ease;
      }

      /* 时间显示 */
      .time-display {
            color: #333;
            font-size: 14px;
            min-width: 60px; /* 固定最小宽度,避免抖动 */
            text-align: center;
            flex-shrink: 0; /* 防止时间文字缩小 */
      }

      @keyframes fadeIn {
            to {
                transform: translate(0, 0);
                opacity: 1;
            }
      }

      /* 响应式调整:针对不同屏幕尺寸优化 */
      @media (max-width: 1024px) {
            #pa {
                height: 550px; /* 中等屏幕减小高度 */
            }
            #wrapper {
                font-size: 2.2rem;
                bottom: 130px;
            }
      }

      @media (max-width: 768px) {
            #pa {
                height: 480px; /* 平板屏幕进一步减小高度 */
            }
            #wrapper {
                font-size: 1.8rem;
                bottom: 110px;
            }
            .player-controls {
                gap: 10px;
            }
            .control-btn {
                width: 45px;
                height: 45px;
                font-size: 18px;
            }
            .play-btn {
                width: 55px;
                height: 55px;
            }
            .time-display {
                font-size: 12px;
                min-width: 50px;
            }
      }

      @media (max-width: 480px) {
            #pa {
                height: 400px; /* 手机屏幕最小高度 */
            }
            #wrapper {
                font-size: 1.5rem;
                bottom: 90px;
            }
            .player-controls {
                gap: 8px;
            }
            .control-btn {
                width: 40px;
                height: 40px;
                font-size: 16px;
            }
            .play-btn {
                width: 50px;
                height: 50px;
            }
      }
    </style>
</head>
<body>
    <!-- 外层容器,确保整体居中 -->
    <div class="player-wrapper">
      <div id="pa">
            <!-- 背景MP4层 -->
            <video id="bg-video" loop muted playsinline>
                <source src="https://cccimg.com/view.php/3ea54d6409ddc292d6b89500f016f96e.mp4" type="video/mp4">
                您的浏览器不支持视频播放
            </video>

            <!-- 静态图片层 -->
            <div id="bg-image"></div>

            <!-- 音频元素 -->
            <audio id="aud" src="https://cccimg.com/view.php/7404fa9c5e73097aefa645b90d63a7a2.mp3" autoplay></audio>

            <!-- 歌词显示区 -->
            <div id="wrapper">HUACHAO LRC</div>

            <!-- 自定义播放器控制面板 -->
            <div class="player-controls">
                <div class="time-display" id="current-time">00:00</div>
                <div class="progress-container" id="progress-container">
                  <div class="progress-bar" id="progress-bar"></div>
                </div>
                <div class="time-display" id="total-time">00:00</div>
                <button class="control-btn" id="prev-btn">⏮</button>
                <button class="control-btn play-btn" id="play-btn">⏸</button>
                <button class="control-btn" id="next-btn">⏭</button>
            </div>
      </div>
    </div>

    <script>
      const gc = `终于把你遇见 - 徐子崴/罗姣
词:徐子崴
曲:徐子崴
编曲:冯丹
吉他:孙越
萧:丁晓逵
伴唱:凌菲
录音:欧力
录音棚:崴IP•MUSIC
音频编辑 Audio Editor:刘璇
混音工程师 Mixing Engineer:王路遥
母带工程师 Mastering Engineer:王路遥
录音/混音/母带棚:@2496 Top Music
封面设计:李政
出品:福唱音乐
制作人:徐子崴
如果一生有一百年
不过是三万六千五百天
我穿过河流啊我越过高山
只为能和你见呀见一面
如果一生有一百年
说起来很长说来也很短
我仰望日月啊我祈求上天
只为能和你走呀走一段
多想把你遇见
恰好在对的时间
我愿用前世的苦难
换与你今生的情缘
终于把你遇见
恰好在对的时间
我愿以今生的相伴
许和你来世的圆满
如果一生有一百年
说起来很长说来也很短
我仰望日月啊我祈求上天
只为能和你走呀走一段
多想把你遇见
恰好在对的时间
我愿用前世的苦难
换与你今生的情缘
终于把你遇见
恰好在对的时间
我愿以今生的相伴
许和你来世的圆满
许和你来世的圆满`;

      const gcAr = lrc2HC(gc);
      let curkey = 0, isSeeking = false;
      const aud = document.getElementById('aud');
      const playBtn = document.getElementById('play-btn');
      const progressBar = document.getElementById('progress-bar');
      const progressContainer = document.getElementById('progress-container');
      const currentTimeEl = document.getElementById('current-time');
      const totalTimeEl = document.getElementById('total-time');
      const bgVideo = document.getElementById('bg-video');
      const wrapper = document.getElementById('wrapper'); // 添加这行,修复wrapper未定义的问题

      // 初始化背景视频播放
      window.addEventListener('load', () => {
            bgVideo.play().catch(err => {
                console.log('视频自动播放被阻止,用户交互后将播放:', err);
                document.body.addEventListener('click', () => {
                  bgVideo.play();
                }, { once: true });
            });
      });

      // 音频时间更新事件
      aud.ontimeupdate = () => {
            updateProgress();
            updateTimeDisplay();

            if(curkey > gcAr.length - 1) return;
            if(aud.currentTime >= gcAr && !isSeeking) {
                const nextTime = gcAr?. || aud.duration;
                const gap = nextTime - gcAr;
                showLrc(gcAr, wrapper, gap);
            }
      };

      // 音频结束事件
      aud.onended = () => {
            curkey = 0;
            playBtn.textContent = '▶';
            aud.play();
      };

      // 音频就绪后显示总时长
      aud.onloadedmetadata = () => {
            totalTimeEl.textContent = formatTime(aud.duration);
      };

      // 音频跳转后重新计算歌词位置
      aud.onseeked = () => {
            calcKey();
            updateProgress();
      };

      // 播放/暂停按钮点击事件
      playBtn.addEventListener('click', () => {
            if(aud.paused) {
                aud.play();
                bgVideo.play();
                playBtn.textContent = '⏸';
            } else {
                aud.pause();
                bgVideo.pause();
                playBtn.textContent = '▶';
            }
      });

      // 进度条点击事件
      progressContainer.addEventListener('click', (e) => {
            const rect = progressContainer.getBoundingClientRect();
            const pos = (e.clientX - rect.left) / rect.width;
            aud.currentTime = pos * aud.duration;
            isSeeking = true;
      });

      // 格式化时间为 MM:SS 格式
      function formatTime(seconds) {
            if(isNaN(seconds)) return '00:00';
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
      }

      // 更新进度条
      function updateProgress() {
            const percent = (aud.currentTime / aud.duration) * 100;
            progressBar.style.width = `${percent}%`;
      }

      // 更新时间显示
      function updateTimeDisplay() {
            currentTimeEl.textContent = formatTime(aud.currentTime);
      }

      // 歌词解析函数
      function lrc2HC(text) {
            let lrcAr = [];
            let ar = text.trim().split('\n');
            ar.sort();
            let reg = /\[(\d+)[.:](\d+)[.:](\d+)\](.*)/;
            ar.forEach(item => {
                if(reg.test(item)) {
                  let result = item.match(reg);
                  let tmsg = parseInt(result) * 60 + parseInt(result) + parseInt(result) / 1000;
                  lrcAr.push(.trim()]);
                }
            });
            return lrcAr.length ? lrcAr : [];
      }

      // 计算当前应该显示的歌词索引
      function calcKey() {
            for (let j = 0; j < gcAr.length; j++) {
                if (aud.currentTime <= gcAr) {
                  curkey = j - 1;
                  break;
                }
            }
            if (curkey < 0) curkey = 0;
            if (curkey >= gcAr.length) curkey = gcAr.length - 1;

            const nextTime = gcAr?. || aud.duration;
            const time = nextTime - gcAr;
            isSeeking = false;
            showLrc(gcAr, wrapper, time);
      }

      // 显示歌词
      function showLrc(str, targetElm, time) {
            if(isSeeking) return;
            targetElm.innerHTML = '';
            const chars = str.split('').map(c => c === ' ' ? '&nbsp;' : c);
            const frg = document.createDocumentFragment();

            chars.forEach((char, idx) => {
                const span = document.createElement('span');
                span.innerHTML = char;
                span.classList.add('char');
                const x = Math.random() * (Math.random() > 0.5 ? 300 : -300);
                const y = Math.random() * (Math.random() > 0.5 ? 300 : -300);
                const color = Math.floor(Math.random() * 0x666666 + 0x000000).toString(16).padStart(6, '0');
                span.style.cssText += `
                  color: #${color};
                  --x: ${x}px;
                  --y: ${y}px;
                  --delay: ${Math.random() * 0.5}s;
                `;
                frg.appendChild(span);
            });

            targetElm.appendChild(frg);
            curkey++;
            setTimeout(() => isSeeking = false, time * 1000);
      }

      // 上一曲/下一曲功能
      document.getElementById('prev-btn').addEventListener('click', () => {
            aud.currentTime = Math.max(0, aud.currentTime - 10);
            isSeeking = true;
      });

      document.getElementById('next-btn').addEventListener('click', () => {
            aud.currentTime = Math.min(aud.duration, aud.currentTime + 10);
            isSeeking = true;
      });
    </script>
</body>

霜染枫丹 发表于 2025-12-3 20:10

我不清楚在这里我是哪里错了,规格被改变,在其他网站正常的1200X675正常显示

马黑黑 发表于 2025-12-3 20:32

霜染枫丹 发表于 2025-12-3 20:10
我不清楚在这里我是哪里错了,规格被改变,在其他网站正常的1200X675正常显示

首先,你的代码中存在一些帖子不应有的标签,如 <body> 等。<html>、<body> 等这类标签是一张网页必有的,但是,做帖子就是在web页里做的,它已经有了,这些标签只能有一套,好比一个住户的套房,正门只有一个。

其次,帖子容器你是用的是margin 实现水平居中,这在独立网页或帖子所在的父标签就是居中的,没有问题,但在 discuz! 论坛,帖子所在的父容器不居中,花潮当前的格式是右移 81px,所以,margin:0 auto; 的设置并不能保证帖子水平居中,需要使用偏移量计算,很早以前有过专门介绍的帖子。

霜染枫丹 发表于 2025-12-3 20:41

本帖最后由 霜染枫丹 于 2025-12-3 20:43 编辑

马黑黑 发表于 2025-12-3 20:32
首先,你的代码中存在一些帖子不应有的标签,如等。、 等这类标签是一张网页必有的,但是,做帖子就是 ...
额的神耶,我要把这弄懂还得费很大的功夫,在DZ3.5论坛和中画都能是正常的比例。还好,这里的画面比还给保持了,月亮还是圆的。{:4_189:}

这个比例折腾我一个多小时也没找到原因,投降了。我记着马老师的指点,按图索骥的给弄明白。偏移量我知道,可是我开始错了,偏的找不到了,拉进度条看能看到{:4_189:}
谢谢马老师,费心了。

https://cccimg.com/view.php/c5fc41f6f9a44821fb7913e140f12581.gif

樵歌 发表于 2025-12-3 20:54

论坛正在准备改宽屏了,目前许多工作正有序进行中,以后,音画帖子更好看了。。。。。。

樵歌 发表于 2025-12-3 20:55

意境营造得真好!配上这歌,简直绝配。{:4_178:}

樵歌 发表于 2025-12-3 20:56

太厉害了,一来就学会马大师的代码了,我到现在还目不识丁{:4_198:}

霜染枫丹 发表于 2025-12-3 20:59

本帖最后由 霜染枫丹 于 2025-12-3 21:03 编辑

樵歌 发表于 2025-12-3 20:54
论坛正在准备改宽屏了,目前许多工作正有序进行中,以后,音画帖子更好看了。。。。。。
还是我不会造成的,我把不理解的都记下来了,等我儿子有时间让他给我讲一下。很感谢这里有马老师指点,我的赶紧跟着学,在其他地方想学习也找不到头绪。系统学习对我来说不可能了,会几种能玩就知足了,{:4_204:}

霜染枫丹 发表于 2025-12-3 21:01

樵歌 发表于 2025-12-3 20:56
太厉害了,一来就学会马大师的代码了,我到现在还目不识丁

我不懂英文,把代码就当做标准件来记忆,就像学会在音画中怎样用螺丝把标准件串起来。说道理一点都不明白。{:4_172:}

樵歌 发表于 2025-12-3 21:05

霜染枫丹 发表于 2025-12-3 20:59
还是我不会造成的,我爸不理解的都记下来了,等我儿子有时间让他给我讲一下。很感谢这里有马老师指点,我 ...

对对,系统的太过复杂了,也太费神费眼睛!会几种自己喜欢的就好。小辣椒就是以前玩播放制作玩多了,眼睛都差点整坏了{:4_189:}

樵歌 发表于 2025-12-3 21:07

霜染枫丹 发表于 2025-12-3 21:01
我不懂英文,把代码就当做标准件来记忆,就像学会在音画中怎样用螺丝把标准件串起来。说道理一点都不明白 ...

这个也失为一个好方法,管它黑猫白猫,套用起来就很好。{:4_189:}

红影 发表于 2025-12-3 22:17

枫丹厉害了,这么快就做出了特效歌词,还有自己的播放按钮呢。
欣赏枫丹好帖{:4_187:}

小辣椒 发表于 2025-12-3 22:25

老师这个代码不是纯套用黑黑老师的代码的,现在论坛网页中间也是有点变形了,

小辣椒 发表于 2025-12-3 22:27

这个歌曲会跳动换颜色,我还没有看见黑黑这个教程的,先去看看黑黑老师的分享教程

感谢老师分享{:4_171:}

霜染枫丹 发表于 2025-12-3 22:49

红影 发表于 2025-12-3 22:17
枫丹厉害了,这么快就做出了特效歌词,还有自己的播放按钮呢。
欣赏枫丹好帖

我就是喜欢看了就有动力,不喜欢的一点也不想做,‘感谢红影支持,晚上好!{:4_204:}

霜染枫丹 发表于 2025-12-3 22:51

小辣椒 发表于 2025-12-3 22:27
这个歌曲会跳动换颜色,我还没有看见黑黑这个教程的,先去看看黑黑老师的分享教程

感谢老师分享{:4_171: ...

也是觉得这个词灵动,填补了播放器相对死板一些的遗憾,挺喜欢的。谢红影支持,晚上好!{:4_204:}

小辣椒 发表于 2025-12-3 22:54

霜染枫丹 发表于 2025-12-3 22:51
也是觉得这个词灵动,填补了播放器相对死板一些的遗憾,挺喜欢的。谢红影支持,晚上好!

你这个播放器按钮点击下去出来是乱码

霜染枫丹 发表于 2025-12-3 23:41

小辣椒 发表于 2025-12-3 22:54
你这个播放器按钮点击下去出来是乱码

是颜色的代码。没隐藏起来{:4_189:}

杨帆 发表于 2025-12-4 00:14

学的挺快哇,谢谢枫丹版主精彩分享{:4_204:}

霜染枫丹 发表于 2025-12-4 01:17

杨帆 发表于 2025-12-4 00:14
学的挺快哇,谢谢枫丹版主精彩分享

杨帆晚上好,这个制作欠火候,马老师指出了问题所在,我在找教程看看。

谢谢你的支持,冬安~~{:4_204:}
页: [1] 2
查看完整版本: 套用马老师代码 《终于把你遇见》