溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在JavaScript中利用audioContext實(shí)現(xiàn)一個(gè)3D音效

發(fā)布時(shí)間:2021-04-19 16:16:45 來源:億速云 閱讀:174 作者:Leah 欄目:開發(fā)技術(shù)

怎么在JavaScript中利用audioContext實(shí)現(xiàn)一個(gè)3D音效?針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

JavaScript的特點(diǎn)

1.JavaScript主要用來向HTML頁面添加交互行為。 2.JavaScript可以直接嵌入到HTML頁面,但寫成單獨(dú)的js文件有利于結(jié)構(gòu)和行為的分離。 3.JavaScript具有跨平臺(tái)特性,在絕大多數(shù)瀏覽器的支持下,可以在多種平臺(tái)下運(yùn)行。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3D Audio</title>
    <style>
        body, div{
            margin: 0px;
            padding: 0px;
            text-align: center;
        }

        #cav{
            border: 1px solid black;
            border-radius: 4px;
            margin: 10px auto;
        }
    </style>
</head>
<body>
<canvas id="cav" width="320" height="200"></canvas>
</body>
<script>
    let Aud = function (ctx, url) {
        this.ctx = ctx;
        this.url = url;

//    source節(jié)點(diǎn)
        this.src = ctx.createBufferSource();

//    多個(gè)處理節(jié)點(diǎn)組
        this.pNode = [];
    };

    Aud.prototype = {
        output(){
            for (let i = 0; i < this.pNode.length; i++){
                let tNode = this.src;
                for (let j = 0; j < this.pNode[i].length; j++){
                    tNode.connect(this.pNode[i][j]);
                    tNode = this.pNode[i][j];
                }
                tNode.connect(this.ctx.destination);
            }
        },

        play(loop){
            this.src.loop = loop || false;
            this.output();
            this.src.start(0);
        },

        stop() {
            this.src.stop();
        },

        addNode(node, groupIdx = 0){
            this.pNode[groupIdx] = this.pNode[groupIdx] || [];
            this.pNode[groupIdx].push(node);
        }
    };

    //設(shè)置節(jié)點(diǎn)類型
    Aud.NODETYPE = {
        GNODE: 0 // 表示gainNode節(jié)點(diǎn)
    }

    //Aud管理對象
    AudManager = {
        urls: [],
        items: [],
        ctx: null,
        init(){
            try{
                this.ctx = new AudioContext();
            }catch (e) {
                console.log(`${e}`);
            }
        },
        load(callback){
            for (let i = 0; i < this.urls.length; i++){
                this.loadSingle(this.urls[i], callback);
            }
        },

        loadSingle(url, callback){
            let req = new XMLHttpRequest();
            req.open('GET', url, true);
            req.responseType = 'arraybuffer';
            let self = this;
            req.onload = function () {
                self.ctx.decodeAudioData(this.response)
                    .then(
                        buf => {
                            let aud = new Aud(self.ctx, url);
                            aud.src.buffer = buf;
                            self.items.push(aud);

                            if (self.items.length == self.urls.length){
                                callback();
                            }
                        },
                        err => {
                            console.log(`decode error:${err}`);
                        }
                    )
            };

            req.send();
        },

        createNode(nodeType, param){
            let node = null;
            switch (nodeType) {
                case 1:
                    node = this.ctx.createPanner();
                    break;
                case 2:
                    node = this.ctx.createScriptProcessor(param[0], param[1], param[2]);
                    break;
                default:
                    node = this.ctx.createGain();
            }
            return node;
        }
    };

    let ctx = document.getElementById('cav').getContext('2d');
//    定義移動(dòng)點(diǎn)坐標(biāo)
    let cX = 190,
        cY = 100,
        deg = 0;

    window.onload = function (){
        init();
    }

    function renderCir(x, y, r, col){
        ctx.save();
        ctx.beginPath();
        ctx.arc(x, y, r, 0, Math.PI*2);
        ctx.closePath();

        ctx.fillStyle = col;
        ctx.fill();
        ctx.restore();
    }

    function renderCenter(){
        renderCir(160, 100, 8, "red");
    }

    function renderCat() {
        renderCir(cX, cY, 8, "blue");
    }

    function init(){
        AudManager.urls = ["test.mp3"];
        AudManager.init();

        AudManager.load(()=>{
            let pNod1 = AudManager.createNode(1);
            let sound1 = AudManager.items[0];

            sound1.addNode(pNod1);
            sound1.play(true);
            timeHandle();
        });
    }

    function timeHandle() {
        window.setInterval(()=>{
            ctx.clearRect(0,0,320,200);
            let rad = Math.PI*deg / 180;
            let sx = 90*Math.cos(rad),
                sy = 90*Math.sin(rad);
            cX = 160 + sx;
            cY = 100 + sy;

            AudManager.items[0].pNode[0][0].setPosition(sx*0.1, -sy*0.1, 0);
            renderCenter();
            renderCat();
            deg++;
        }, 30);
    }
</script>
</html>

關(guān)于怎么在JavaScript中利用audioContext實(shí)現(xiàn)一個(gè)3D音效問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI