音频&案例

知识点:

案例效果图:

代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .controlls {
                display: flex;
                justify-content: space-around;  
                align-items: center;
                margin-bottom: 16px;
            }
            .music-wrapper {
                position: relative;
                display: flex;
                flex-direction: row;
                justify-content: space-between;
                list-style: none;
                width: 100%;
                height: 148px;
                padding: 16px;
                border-top:1px solid #ccc;
            }
            .music-draw{
                width: 20px;
                height: 50px;
                transition: .5s;
            }
            #controll{
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%,-50%);
                padding: 8px;
                background-color: #64c239;
                border: none;
                color: #fff;
                width: 80px;
                height: 80px;
                border-radius: 50%;
                cursor: pointer;
                border: 2px solid #ccc;
            }
            #controll:hover{
                opacity: .8;
            }
        </style>
    </head>
    <body>
        <!-- 控制音量 -->
        <div class="controlls">
            <div>
                <h3>控制音量</h3>
                <input type="range" id="volume" min="0" max="2" value="1" step="0.01">  
            </div>
            <div>
                <h3>控制立体声方向</h3>
                <input type="range" id="panner" min="-1" max="1" value="0" step="0.01">
            </div>
        </div>
        <ul class="music-wrapper">
            <button id="controll" data-playing="false">播放</button>
        </ul>
        <!-- 如果你要加载的声音文件保留在其他域中,则需要使用  crossorigin 属性  -->
        <audio src="./audio.mp3" type="audio/mpeg" id="source"></audio>
        <script>
            const pillarNumber = 128;
            /** 创建负责动效的长方形的个数 */
            const ulWrapper = document.querySelector(".music-wrapper");
            new Array(pillarNumber).fill("").forEach(()=>{
                const li = document.createElement("li");
                li.classList.add("music-draw");
                li.style.backgroundColor = "#"+new Array(6).fill(0).map(()=> [0,1,2,3,4,5,6,7,8,9,"a","b","c","d","e","f"][Math.floor(Math.random()*16)]).join("");
                ulWrapper.appendChild(li);
            });
            /** 创建音频上下文 */
            const AudioContext = window.AudioContext || window.webkitAudioContext;
            const audioContext = new AudioContext();
             
            /** 获取音频源 */
            const audioElement = document.querySelector("#source");
            /** 讲音频源放在音频上下文中 */
            const track = audioContext.createMediaElementSource(audioElement);
             
            /** 修改音量 */
            const gainNode = audioContext.createGain();
            
            /** 为应用程序增加立体声平移 */
            const pannerOptions = { pan: 0 };
            const panner = new StereoPannerNode(audioContext,pannerOptions);

            /**  获取数据分析 */
            const analyser = audioContext.createAnalyser();

            /** 连接 */
            track.connect(gainNode).connect(panner).connect(analyser).connect(audioContext.destination);

 
            /** 控制播放 */
            const controllBtn = document.querySelector("#controll");
            controllBtn.onclick = function () {
                if(audioContext.state === "suspended"){
                    audioContext.resume();
                }
                
                if(this.dataset.playing === "false"){
                    audioElement.play();
                    this.dataset.playing = "true";
                    this.innerHTML = "暂停";
                    this.style.backgroundColor = "#e61021";
                }else {
                    audioElement.pause();
                    this.dataset.playing = "false";
                    this.innerHTML = "播放";
                    this.style.backgroundColor = "#64c239";
                }
            }

            /** 音频播放结束,将状态更新 */
            audioElement.addEventListener("ended",()=>{
                controllBtn.dataset.playing = "false";
            });

            /** 修改音量 */
            const volumeInput = document.querySelector("#volume");
            volumeInput.oninput = function () {
                gainNode.gain.value = this.value;
            }

            /** 立体声平移 */
            const pannerInput = document.querySelector("#panner");
            pannerInput.oninput = function (){
                panner.pan.value = this.value;
            }

            
            /** 获取音频数据 */
            function getAudioData (){
                const freqArry = new Uint8Array(analyser.frequencyBinCount);
                analyser.getByteFrequencyData(freqArry);
                const step = Math.round(freqArry.length / pillarNumber);
                const results = freqArry.slice(0,pillarNumber).map(i => i * step);

                if(audioElement.currentTime >= audioElement.duration){
                    audioElement.currentTime  = 0;
                }

                results.currentTime = audioElement.currentTime ;
                results.duration = audioElement.duration;

                return results;
            }
            const musicDraws = document.querySelectorAll(".music-draw");

            const timer = setInterval(()=>{
                if(controllBtn.dataset.playing === "true"){
                    const data = getAudioData();
                    console.log('data:',data);
                    musicDraws.forEach((item,index)=>{
                        item.style.height = 20+Number(data[index])+"px";
                    })
                }
            },20)

        </script>
    </body>
</html>
posted @ 2022-04-29 23:24  胡姐姐  阅读(27)  评论(0编辑  收藏  举报