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

半腔热情 提交于 2021-02-19 05:18:46

问题


I'm trying to create a WebApp with vue-cli that uses AudioWorklets, but I'm getting a bunch of errors when trying to access any property of my AudioWorkletNode, like port or channelCount etc:

TypeError: Illegal invocation at MyWorkletNode.invokeGetter

After hours of googling and debugging I think it's somehow related to classes, AudioWorklet seems to only work with ES6 classes but one of vue-cli/babel/webpack does it's magic (which I don't understand where and what it does) and transpiles the classes away to regular constructor functions or something. Or maybe it's worklet-loader that does the transpilation? I don't know, I'm completely in the dark and have no idea where to look.

If I write the code without any bundlers, just vanilla JS, it works, I'm not getting any errors. But I need to use AudioWorklets in my vue project, so what are my options? Anything better than disabling class transpilation? If not, where and how can I disable it?

// 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);

回答1:


It's hard to tell whats wrong here without more code. The worklet parts look right.

But to answer the general question (for posterity), the processor has to be in a separate bundle loaded into it's own context. When you use worklet-loader, the import is really just a url.

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

console.log(MyWorkletProcessor) 

>5b91ba45c32d94f52b3a.worklet.js

I don't recommend using the inline loader though since it puts the artifact at the dist root by default which can cause deployment issues.

Here's a walkthrough of the basic setup.

// 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)

I also made a related demo app that shows worklets running in vue.



来源:https://stackoverflow.com/questions/53794127/how-to-make-audioworklets-work-with-vue-cli-webpack-babel-getting-illegal-invo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!