使用ScriptProcessorNode在iPhone的Safari(Use ScriptProc

2019-10-18 05:47发布

我在HTML5新的,我想用一个ScriptProcessorNode来生成声音。 我的问题是,该代码并不在iPhone的Safari工作。 但它在Safari浏览器在桌面上。

VAR背景; 是IsPlaying模块; 为发电机节点; 是isNeedShowAlert;

            function myButtonClick(button) 
        {
            isNeedShowAlert = true;
            if (isPlaying)
            {
                isPlaying = false;
                console.log("Stop!");
                generatorNode.disconnect();
            }
            else
            {
                alert("Play!");
                isPlaying = true;
                console.log("Play!");

                context = new webkitAudioContext();

                generatorNode = context.createJavaScriptNode(2048, 1, 2);
                generatorNode.onaudioprocess = function (e) 
                {
                    console.log("onaudioprocess!");
                    $("body").append("buffering<br/>");
                    var output = e.outputBuffer.getChannelData(0);

                    if (isNeedShowAlert)
                    {
                        isNeedShowAlert = false;
                        console.log("Length "+ output.length);
                        alert("Length "+ output.length);
                    }

                    for (var i = 0; i < output.length; i++)
                    {
                        output[i] = Math.random();
                    }
                }                   
                generatorNode.connect(context.destination);
                alert("Node Connected");
            }
            }

貌似onaudioprocess从来没有所谓。 这里的人写ScriptProcessorNode可垃圾收集器被破坏,但对我来说它是全局变量。 我尝试了很多,并开始思考,即trere是没有办法在iPhone的Safari使用ScriptProcessorNode。 有人能做到ID?

UPD。 但是,如果使用AudioBufferSourceNode,它的工作原理。

bufferNode = context.createBufferSource()
var buffer = context.createBuffer(1, 1024, context.sampleRate)
var  data = buffer.getChannelData(0);

for (var i = 0; i < 1024; i++) 
{
  data[i] = Math.random();
}
bufferNode.buffer = buffer;
bufferNode.loop = true;
bufferNode.connect(context.destination);
bufferNode.noteOn(0);

看起来问题是特别是在ScriptProcessorNode及其onaudioprocess方法。

Answer 1:

我自己找到了答案。 它需要一个源节点添加到ScriptProcessorNode。 事情是这样的。

bufferNode = context.createBufferSource()
var buffer = context.createBuffer(1, 1024, context.sampleRate)
var  data = buffer.getChannelData(0);
for (var i = 0; i < 2048; i++) 
{
  data[i] = 0;
}
bufferNode.buffer = buffer;
bufferNode.loop = true;

generatorNode = context.createJavaScriptNode(2048, 1, 1);
generatorNode.channelCount = 2;
generatorNode.channelCountMode = "max";
generatorNode.channelInterpretation = "speakers";
generatorNode.onaudioprocess = function generateWhiteNoise(e) 
{
   var output = e.outputBuffer.getChannelData(0);
   console.log("onaudioprocess!");
   for (var i = 0; i < output.length; i++)
   {
     output[i] = ( Math.random() * 2 ) - 1;
   }
}
bufferNode.connect(generatorNode);
generatorNode.connect(context.destination);
bufferNode.noteOn(0);

该代码将在iOS的Safari浏览器的工作。

UPD。 更新白噪声生成代码。 我不是我的目标,只是用它测试,但它会是坏的,如果有人用我的错误代码来生成真正的白噪声。



Answer 2:

有同样的问题后,我在这里试图接受的答案,但它并没有为我工作。 看来问题是,当generatorNode被conntected到context.destination context.state仍然暂停! 并加入context.resume()在相同的块没有效果。 添加context.resume()通过一个按钮单击事件触发的作品,也触发了前面的简历! 这仍然是太多我喜欢的一种解决方法,但是是一个可行的解决方法。

如果任何人有任何建议/一个更好的解决办法的想法触发context.resume()或消除所有需要它(像所有其他浏览器),这将是大加赞赏。

例如的jsfiddle就在这里!

var suspendBtn = document.getElementById("suspendBtn");
var resumeBtn = document.getElementById("resumeBtn");

suspendBtn.onclick = function() {
    context.suspend();
}

resumeBtn.onclick = function() {
    context.resume();
}

var context = new webkitAudioContext();
var generatorNode = context.createJavaScriptNode(2048, 1, 2);

generatorNode.onaudioprocess = function generateWhiteNoise(e) {
    var output = e.outputBuffer.getChannelData(0);

    for (var i = 0; i < output.length; i++) {
        output[i] = ( Math.random() * 2 ) - 1;
    }
}

// This connects the generatorNode but in a suspended state!
generatorNode.connect(context.destination);

// This has no effect! 
// seems that it needs to be called from another context/closure
context.resume();


文章来源: Use ScriptProcessorNode in iPhone Safari