Meteor - 脚本在刷新/仅在某些路由上无法正确加载 Web 音频缓冲区

Posted

技术标签:

【中文标题】Meteor - 脚本在刷新/仅在某些路由上无法正确加载 Web 音频缓冲区【英文标题】:Meteor - Script doesn't load Web Audio Buffers properly on refresh / only on certain routes 【发布时间】:2015-12-22 11:52:43 【问题描述】:

https://github.com/futureRobin/meteorAudioIssues

尝试将音频缓冲区加载到内存中。当我点击 localhost:3000/tides 或 localhost:3000 时,它会毫无问题地将我的缓冲区加载到内存中。然后当我点击一个会话时,例如本地主机:3000/潮汐/SOMESESSIONID。缓冲区已经从之前的状态加载。

但是,当我在“localhost:3000/tides/SOMESESSIONID”上刷新页面时,缓冲区未正确加载,控制台仅记录文件路径名数组。

对应用功能至关重要。任何帮助都会很棒!

audio.js

             //new context for loadKit
             var context = new AudioContext();
             var audioContext = null;
             var scheduleAheadTime = 0;
             var current16thNote = 0;
             var bpm = 140;

             //array of samples to load first. 
             var samplesToLoad = [
                 "ghost_kick.wav", "ghost_snare.wav", "zap.wav", "ghost_knock.wav"
             ];


             //create a class called loadKit for loading the sounds. 
             function loadKit(inputArg) 
                 //get the array of 6 file paths from input. 
                 this.drumPath = inputArg;
             

             //load prototype runs loadsample function. 
             loadKit.prototype.load = function() 
                 //when we call load, call loadsample 6 times
                 //feed it the id and drumPath index value 
                 for (var i = 0; i < 6; i++) 
                     this.loadSample(i, this.drumPath[i]);
                 

             ;

             //array to hold the samples in. 
             //now loadKitInstance.kickBuffer will hold the buffer.  
             var buffers = [
                 function(buffer) 
                     this.buffer1 = buffer;
                 ,
                 function(buffer) 
                     this.buffer2 = buffer;
                 ,
                 function(buffer) 
                     this.buffer3 = buffer;
                 ,
                 function(buffer) 
                     this.buffer4 = buffer;
                 ,
                 function(buffer) 
                     this.buffer5 = buffer;
                 ,
                 function(buffer) 
                     this.buffer6 = buffer;
                 
             ];


             //load in the samples. 
             loadKit.prototype.loadSample = function(id, url) 
                 //new XML request.
                 var request = new XMLHttpRequest();
                 //load the url & set response to arraybuffer
                 request.open("GET", url, true);
                 request.responseType = "arraybuffer";

                 //save the result to sample
                 var sample = this;



                 //once loaded decode the output & bind to the buffers array
                 request.onload = function() 
                         buffers[id].bind("");
                         context.decodeAudioData(request.response, buffers[id].bind(sample));
                     
                     //send the request. 
                 request.send();
             ;

             //get the list of drums from the beat.json
             //load them into a the var 'loadedkit'.
             loadDrums = function(listOfSamples) 
                 var drums = samplesToLoad;
                 loadedKit = new loadKit(listOfSamples);
                 loadedKit.load();
                 console.log(loadedKit);
             

             //create a new audio context.
             initContext = function() 
                 try 
                     //create new Audio Context, global.
                     sampleContext = new AudioContext();
                     //create new Tuna instance, global
                     console.log("web audio context loaded");
                  catch (e) 
                     //if not then alert
                     alert('Sorry, your browser does not support the Web Audio API.');
                 
             


             //inital function, ran on window load. 
             init = function() 
                 audioContext = new AudioContext();
                 timerWorker = new Worker("/timer_worker.js");


            

client/main.js

Meteor.startup(function() 
    Meteor.startup(function() 
        init();
        initContext();
    );

router.js

Router.route('/', 
        template: 'myTemplate',

        subscriptions: function() 
        this.subscribe('sessions').wait();
      ,
       // Subscriptions or other things we want to "wait" on. This also
      // automatically uses the loading hook. That's the only difference between
      // this option and the subscriptions option above.
      waitOn: function () 
        return Meteor.subscribe('sessions');
      ,

       // A data function that can be used to automatically set the data context for
      // our layout. This function can also be used by hooks and plugins. For
      // example, the "dataNotFound" plugin calls this function to see if it
      // returns a null value, and if so, renders the not found template.
      data: function () 
        return Sessions.findOne();
      ,

        action: function () 
        loadDrums(["ghost_kick.wav", "ghost_snare.wav", "zap.wav", "ghost_knock.wav"]);
        // render all templates and regions for this route
        this.render();
      
    );



    Router.route('/tides/:_id',
        template: 'idTemplate', 
     // a place to put your subscriptions
      subscriptions: function() 
        this.subscribe('sessions', this.params._id).wait();
      ,
       // Subscriptions or other things we want to "wait" on. This also
      // automatically uses the loading hook. That's the only difference between
      // this option and the subscriptions option above.
      waitOn: function () 
        return Meteor.subscribe('sessions');
      ,

       // A data function that can be used to automatically set the data context for
      // our layout. This function can also be used by hooks and plugins. For
      // example, the "dataNotFound" plugin calls this function to see if it
      // returns a null value, and if so, renders the not found template.
      data: function (params) 
        return Sessions.findOne(this.params._id);
      ,

        action: function () 
          console.log("IN ACTION")
          console.log(Sessions.findOne(this.params._id));
          var samples = Sessions.findOne(this.params._id)["sampleList"];
          console.log(samples);
        loadDrums(samples);
        // render all templates and regions for this route
        this.render();
      
    )

【问题讨论】:

您确定所有这些代码都是理解和重现您的问题所必需的吗?请查看minimal reproducible example 是什么。 【参考方案1】:

好的,所以我在流星论坛上得到了回复!

https://forums.meteor.com/t/script-doesnt-load-web-audio-buffers-properly-on--id-routes/15270

“看起来你的问题是相对路径,如果你将路由器的第 58 行更改为每个文件的目录,它会尝试从 localhost:3000/tides/ghost_*.wav 加载文件应该工作。

loadDrums(["../ghost_kick.wav", "../ghost_snare.wav", "../zap.wav", "../ghost_knock.wav"]);

这成功了。似乎很奇怪,Meteor 可以在一条路线中不使用“../”但在另一条路线中不使用的情况下很好地加载东西,但我们走了。希望这对将来的人有所帮助。

【讨论】:

以上是关于Meteor - 脚本在刷新/仅在某些路由上无法正确加载 Web 音频缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

错误:发送后无法设置标题,仅在刷新页面后发生

使用 React Router 和 Webpack 2 如何仅在某些路由上需要外部库?

仅在 Laravel 中公开某些身份验证路由

使用 Iron:router 将某些功能或事件的输出返回到 Meteor 中的某个新页面或模板

CollectionView 仅在 SVPullToRefresh 上刷新,不在 .reloadData 上刷新

Ng-如果仅在刷新页面时起作用