• 售前

  • 售后

热门帖子
入门百科

js通过audioContext实现3D音效

[复制链接]
馥琳 显示全部楼层 发表于 2021-10-26 13:35:39 |阅读模式 打印 上一主题 下一主题
本文实例为各人分享了js通过audioContext实现3D音效的详细代码,供各人参考,详细内容如下
媒介

AudioContext的setPosition实现3D音效
效果展示


代码展示
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>3D Audio</title>
  6.     <style>
  7.         body, div{
  8.             margin: 0px;
  9.             padding: 0px;
  10.             text-align: center;
  11.         }
  12.         #cav{
  13.             border: 1px solid black;
  14.             border-radius: 4px;
  15.             margin: 10px auto;
  16.         }
  17.     </style>
  18. </head>
  19. <body>
  20. <canvas id="cav" width="320" height="200"></canvas>
  21. </body>
  22. <script>
  23.     let Aud = function (ctx, url) {
  24.         this.ctx = ctx;
  25.         this.url = url;
  26. //    source节点
  27.         this.src = ctx.createBufferSource();
  28. //    多个处理节点组
  29.         this.pNode = [];
  30.     };
  31.     Aud.prototype = {
  32.         output(){
  33.             for (let i = 0; i < this.pNode.length; i++){
  34.                 let tNode = this.src;
  35.                 for (let j = 0; j < this.pNode[i].length; j++){
  36.                     tNode.connect(this.pNode[i][j]);
  37.                     tNode = this.pNode[i][j];
  38.                 }
  39.                 tNode.connect(this.ctx.destination);
  40.             }
  41.         },
  42.         play(loop){
  43.             this.src.loop = loop || false;
  44.             this.output();
  45.             this.src.start(0);
  46.         },
  47.         stop() {
  48.             this.src.stop();
  49.         },
  50.         addNode(node, groupIdx = 0){
  51.             this.pNode[groupIdx] = this.pNode[groupIdx] || [];
  52.             this.pNode[groupIdx].push(node);
  53.         }
  54.     };
  55.     //设置节点类型
  56.     Aud.NODETYPE = {
  57.         GNODE: 0 // 表示gainNode节点
  58.     }
  59.     //Aud管理对象
  60.     AudManager = {
  61.         urls: [],
  62.         items: [],
  63.         ctx: null,
  64.         init(){
  65.             try{
  66.                 this.ctx = new AudioContext();
  67.             }catch (e) {
  68.                 console.log(`${e}`);
  69.             }
  70.         },
  71.         load(callback){
  72.             for (let i = 0; i < this.urls.length; i++){
  73.                 this.loadSingle(this.urls[i], callback);
  74.             }
  75.         },
  76.         loadSingle(url, callback){
  77.             let req = new XMLHttpRequest();
  78.             req.open('GET', url, true);
  79.             req.responseType = 'arraybuffer';
  80.             let self = this;
  81.             req.onload = function () {
  82.                 self.ctx.decodeAudioData(this.response)
  83.                     .then(
  84.                         buf => {
  85.                             let aud = new Aud(self.ctx, url);
  86.                             aud.src.buffer = buf;
  87.                             self.items.push(aud);
  88.                             if (self.items.length == self.urls.length){
  89.                                 callback();
  90.                             }
  91.                         },
  92.                         err => {
  93.                             console.log(`decode error:${err}`);
  94.                         }
  95.                     )
  96.             };
  97.             req.send();
  98.         },
  99.         createNode(nodeType, param){
  100.             let node = null;
  101.             switch (nodeType) {
  102.                 case 1:
  103.                     node = this.ctx.createPanner();
  104.                     break;
  105.                 case 2:
  106.                     node = this.ctx.createScriptProcessor(param[0], param[1], param[2]);
  107.                     break;
  108.                 default:
  109.                     node = this.ctx.createGain();
  110.             }
  111.             return node;
  112.         }
  113.     };
  114.     let ctx = document.getElementById('cav').getContext('2d');
  115. //    定义移动点坐标
  116.     let cX = 190,
  117.         cY = 100,
  118.         deg = 0;
  119.     window.onload = function (){
  120.         init();
  121.     }
  122.     function renderCir(x, y, r, col){
  123.         ctx.save();
  124.         ctx.beginPath();
  125.         ctx.arc(x, y, r, 0, Math.PI*2);
  126.         ctx.closePath();
  127.         ctx.fillStyle = col;
  128.         ctx.fill();
  129.         ctx.restore();
  130.     }
  131.     function renderCenter(){
  132.         renderCir(160, 100, 8, "red");
  133.     }
  134.     function renderCat() {
  135.         renderCir(cX, cY, 8, "blue");
  136.     }
  137.     function init(){
  138.         AudManager.urls = ["test.mp3"];
  139.         AudManager.init();
  140.         AudManager.load(()=>{
  141.             let pNod1 = AudManager.createNode(1);
  142.             let sound1 = AudManager.items[0];
  143.             sound1.addNode(pNod1);
  144.             sound1.play(true);
  145.             timeHandle();
  146.         });
  147.     }
  148.     function timeHandle() {
  149.         window.setInterval(()=>{
  150.             ctx.clearRect(0,0,320,200);
  151.             let rad = Math.PI*deg / 180;
  152.             let sx = 90*Math.cos(rad),
  153.                 sy = 90*Math.sin(rad);
  154.             cX = 160 + sx;
  155.             cY = 100 + sy;
  156.             AudManager.items[0].pNode[0][0].setPosition(sx*0.1, -sy*0.1, 0);
  157.             renderCenter();
  158.             renderCat();
  159.             deg++;
  160.         }, 30);
  161.     }
  162. </script>
  163. </html>
复制代码
以上就是本文的全部内容,盼望对各人的学习有所资助,也盼望各人多多支持脚本之家。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作