繁体   English   中英

如何使AudioWorklets与vue-cli / webpack / babel一起使用? (获取非法调用错误)

[英]How to make AudioWorklets work with vue-cli/webpack/babel? (getting illegal invocation error)

我正在尝试使用vue-cli创建一个使用AudioWorklets的WebApp,但是在尝试访问AudioWorkletNode的任何属性(例如端口或channelCount等)时遇到很多错误:

TypeError: Illegal invocation at MyWorkletNode.invokeGetter

经过数小时的谷歌搜索和调试,我认为这与类有某种联系,AudioWorklet似乎仅适用于ES6类,但是vue-cli / babel / webpack之一确实具有魔力(我不知道它在哪里和做什么)并进行转换将类转移到常规的构造函数或其他东西上。 也许是由worklet-loader进行编译? 我不知道,我完全处于黑暗中,也不知道在哪里看。

如果我编写的代码没有任何捆绑程序,仅使用香草JS,它就能正常工作,那么我不会收到任何错误。 但是我需要在vue项目中使用AudioWorklets,所以我有什么选择? 有比禁止类移植更好的方法吗? 如果没有,我在哪里以及如何禁用它?

// main.js
import worklet from 'worklet-loader!./processor.js'

class MyWorkletNode extends AudioWorkletNode {
  constructor(context) {
    super(context, 'my-worklet-processor');
    // Throws TypeError: Illegal invocation
    console.log(this.channelCount);
  }
}

this.audioCtx.audioWorklet.addModule(worklet).then(() => {
  let node = new MyWorkletNode(this.audioCtx);
  console.log("Loaded!");

  // Throws TypeError: Illegal invocation
  node.port.onmessage = event => {
    console.log(event.data);
  };
}).catch(e => console.log(`${e.name}: ${e.message}`));


// processor.js
class MyWorkletProcessor extends AudioWorkletProcessor {
  constructor() {
    super();
    this.port.postMessage('hello!');
  }

  process(inputs, outputs, parameters) {
    // audio processing code here.
  }
}

registerProcessor('my-worklet-processor', MyWorkletProcessor);

如果没有更多代码,很难在这里说出问题所在。 工作零件看起来正确。

但是要回答一般性问题(对于后代),处理器必须位于单独的捆绑软件中,并装入其自身的上下文中。 当使用worklet-loader时,导入实际上只是一个URL。

import MyWorkletProceessor from 'worklet-loader!./path/MyWorkletProcessor'

console.log(MyWorkletProcessor) 

>5b91ba45c32d94f52b3a.worklet.js

我不建议使用内联加载器,因为默认情况下它会将工件放在dist根目录下,这可能会导致部署问题。

这是基本设置的演练。

// vue-config.js
configureWebpack: {
  module: {
    rules: [
      {
        test: /Worklet\.js$/,  <---- change this to match your filename conventions
        loader: 'worklet-loader',
        options: {
          name: 'js/[hash].worklet.js'
        }
      }
    ]
  }
}

// somewhere in vue code
import MyWorkletProcessor from './path/MyWorkletProcessor'
import MyWorkletNode from './path/MyWorkletNode'
...

try {
  await context.audioWorklet.addModule(MyWorkletProcessor)
  myWorkletNode = new MyWorkletNode(context)
  // or if no custom node
  // myWorkletNode = new AudioWorkletNode(context, 'my-worklet-processor') 
} catch (error) {
  // ...
}
// connect the workletNode input to a source node
someSourceNode.connect(myWorkletNode )
// connect the worklet output to some other node or destination
myWorkletNode.connect(context.destination)

// MyWorkletNode.js
export default class MyWorkletNode extends AudioWorkletNode {
   constructor(context) {
    super(context, 'my-worklet-processor')
    console.log(this.channelCount)
  }
}

// MyWorkletProcessor.js
class MyWorkletProcessor extends AudioWorkletProcessor {
  constructor() {
    super()
    this.port.postMessage('hello!')
  }

  process(inputs, outputs, parameters) {
    // audio processing code here.
    return true
  }
}
registerProcessor('my-worklet-processor', MyWorkletProcessor)

我还制作了一个相关的演示应用程序 ,其中显示了在vue中运行的工作集。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM