飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 456|回复: 13

[原创] 音频可视化(精准播放控制与专业级波形)是一款专为婚庆行业打造的智能音乐管理工具

[复制链接]
  • TA的每日心情
    开心
    2024-8-8 11:24
  • 签到天数: 75 天

    [LV.6]常住居民II

    发表于 前天 21:27 | 显示全部楼层 |阅读模式
    本帖最后由 china365love 于 2025-2-20 21:29 编辑

    在人生中最重要的婚礼时刻,音乐是营造浪漫与温馨氛围的关键元素。

    婚庆音乐管家,专为婚礼打造,是您的理想音乐伴侣。

    它提供便捷的婚礼音乐包导入功能,支持多种音频格式,简洁直观的用户界面让操作轻松上手,

    点击播放列表歌曲即可一键播放,还支持进度跳转。每首歌曲都配有精美的波形图,

    直观展示音乐节奏变化,主波形图实时呈现播放动态,为您带来沉浸式音乐体验。

    微信截图_20250220212359.png


    大飞哥婚庆音乐管家适用于各种婚礼场景,无论是室内豪华婚礼,还是户外清新婚礼,都能提供恰到好处的音乐。
    大飞哥软件自习室的专业技术团队运用先进音频处理技术打造这款音乐管家,使其具备强大兼容性,可在多种设备上流畅运行,为您的婚礼音乐播放保驾护航。
    选择大飞哥婚庆音乐管家,让音乐成为您婚礼中最动人的旋律,为幸福时刻增添更多美好回忆 。

    微信截图_20250220211657.png

    源码
    [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>&#127925; 导入婚礼音乐包</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>
       
       
    软件用浏览器打开在附件下载

    全功能智能图片轮播器——支持多格式导入自定义尺寸顺序控制响应式布局的专业级可视化.rar

    9.57 KB, 下载次数: 34, 下载积分: 飘云币 -2 枚

    售价: 1 枚飘云币  [记录]

    软件

    评分

    参与人数 1威望 +1 飘云币 +1 收起 理由
    飞天 + 1 + 1 感谢发布原创作品,PYG有你更精彩!

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2025-1-14 13:49
  • 签到天数: 393 天

    [LV.9]以坛为家II

    发表于 前天 22:32 | 显示全部楼层
    原创精品 感谢分享!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2025-1-14 22:42
  • 签到天数: 1226 天

    [LV.10]以坛为家III

    发表于 前天 23:53 | 显示全部楼层
    谢谢楼主分享!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2025-1-14 08:19
  • 签到天数: 325 天

    [LV.8]以坛为家I

    发表于 昨天 08:15 | 显示全部楼层
    原创精品 感谢分享!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-1-14 08:40
  • 签到天数: 675 天

    [LV.9]以坛为家II

    发表于 昨天 09:18 | 显示全部楼层
    原创精品 感谢分享!正好想用用
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-1-14 11:11
  • 签到天数: 940 天

    [LV.10]以坛为家III

    发表于 昨天 10:24 | 显示全部楼层
    源码点导入没反应,下载附件试试                              
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-1-14 11:11
  • 签到天数: 940 天

    [LV.10]以坛为家III

    发表于 昨天 10:24 | 显示全部楼层
    源码点导入没反应,下载附件试试                              
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2025-1-14 11:15
  • 签到天数: 243 天

    [LV.8]以坛为家I

    发表于 昨天 11:59 | 显示全部楼层
    感谢分享!正好用用
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表