NodeJS 如何在Vue中导入和使用P5.Sound?

p3rjfoxz  于 6个月前  发布在  Node.js
关注(0)|答案(4)|浏览(76)

我一直在尝试使用Vue和P5制作一个音乐可视化应用程序,在使用这篇文章作为我的指南(https://medium.com/js-dojo/experiment-with-p5-js-on-vue-7ebc05030d33)修补P5之后,我设法得到了一个带有一些很酷的图形的画布。
现在,我尝试在给定歌曲的波形/振幅和画布中呈现的视觉效果之间创建链接。我一直在尝试从P5.sound库中获取构造函数/函数,以从文件路径加载歌曲,然后使用FFT对象的输出来控制画布中呈现的视觉效果。
现在,我的研究表明,P5库必须在示例模式下运行才能运行(https://github.com/processing/p5.js/wiki/Global-and-instance-mode),我已经尽我所能在我的Vue项目中坚持这种方法。但是,尽管视觉渲染工作,P5.sound功能都没有。
下面是我的模型的代码,它设置了P5对象:

import P5 from 'p5';
import P5sound from "p5/lib/addons/p5.sound";

let p5;
let fft;
let sound;

export function main(_p5) {
  p5 = _p5;

  p5.setup = () => {
    p5.createCanvas(500, 500);
    p5.background(100);
    fft = new p5.FFT();
    fft.setInput("../assets/sawtooth.mp3")
    sound.amp(0.2);
  };
  p5.draw = () => {
    p5.background(220);
    let spectrum = fft.analyze();
    noStroke();
    fill(255, 0, 255);
    for (let i = 0; i < spectrum.length; i++) {
      let x = map(i, 0, spectrum.length, 0, width);
      let h = -height + map(spectrum[i], 0, 255, height, 0);
      rect(x, height, width / spectrum.length, h);
    }

    let waveform = fft.waveform();
    noFill();
    beginShape();
    stroke(20);
    for (let i = 0; i < waveform.length; i++){
      let x = map(i, 0, waveform.length, 0, width);
      let y = map( waveform[i], -1, 1, 0, height);
      vertex(x,y);
    }
    endShape();
  };
}

字符串
然后,在我的MusicVisualization.vue组件中,我在组件的mounted()部分调用这个模型:

import P5 from 'p5';
var musicVisualizerModel = require("../models/musicVisualizerModel.js");

export default {
  name: "MusicVisualization",
  data(){
      return{
          message: ""
      } 
  },
  mounted() {
    new P5(musicVisualizerModel.main);
  }
};


无论我如何尝试导入我的P5.sound库,fft = new p5.FFT()行总是产生错误p5.FFT is not a constructor。我已经检查了我的node_modules中的P5.js模块,我可以清楚地看到P5.sound.js库存在于p5/lib/addons/p5.sound文件路径中,但我不能使用它的任何功能。我应该注意,当我从模型的代码中删除所有P5.sound功能时,只需要一张简单形状的画布,它就能工作得很好。
我使用npm install --save p5安装了P5,并尝试了许多方法来让P5.sound工作,例如P5-manager包(https://www.npmjs.com/package/p5-manager/v/0.1.0)和Vue-P5 Package 器(https://www.npmjs.com/package/vue-p5)。我也曾尝试实施类似问题中提出的一些解决方案(Using p5.sound.js in instance mode: 'p5.Amplitude() not a constructor').这些都不起作用,尽管我可能实现得不正确。有人知道如何将P5.sound库导入到我的Vue项目中吗?

**

如果我没有运行fft= new p5.FFT()行,我注意到的另一个错误是错误ReferenceError: p5 is not defined。我深入研究了这个问题,发现其他人也遇到过这个问题。(https://github.com/processing/p5.js-sound/issues/453)。显然,一位用户通过“降级到0.9,将sound.js复制到项目文件夹,提升回1.0,并将导入链接到本地,0.9版本的声音”来解决这个问题。可悲的是,我不确定如何执行此解决方案。有人知道如何吗?

s1ag04yj

s1ag04yj1#

感谢我在Github问题页面(https://github.com/processing/p5.js-sound/issues/453)上得到的帮助,我找到了如何导入P5.sound库的方法。
首先,我在node_modules中安装了P5.js,然后安装了P5.js版本0.9.0:

npm uninstall p5
npm install [email protected]

字符串
接下来,在node_modules中找到P5模块后,我复制了P5声音库文件并将其粘贴到我的项目的src目录中,然后将import P5sound from "p5/lib/addons/p5.sound"替换为import "../p5.sound.js"(代表我的相对文件路径)。然后我使用以下命令在终端中安装了最新版本的P5.js:

npm install p5@1


现在我可以导入声音库而不会得到错误ReferenceError: p5 is not definedp5.FFT is not a constructor

4nkexdtk

4nkexdtk2#

问题是p5-sound依赖于p5的全球可用性。
如果你使用的是webpack,可以通过webpack的ProvidePlugin轻松解决,如下所示:

plugins: [
    new webpack.ProvidePlugin({
      p5: 'p5',
    })
  ]

字符串
然后,您应该能够通过以下方式导入:

import p5 from 'p5';
import 'p5/lib/addons/p5.sound';

eyh26e7m

eyh26e7m3#

我在react中使用p5时也遇到了类似的问题,但我能够通过在html文件中包含p5脚本来实现这一点(暂时没有)。

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/addons/p5.sound.min.js"></script>

字符串
然后在React中创建我的p5示例时,我调用:

new window.p5(sketch, node);


我的草图文件看起来像这样:

const sketch = (p, props) => {
  p.preload = () => {
    ...
  };

  p.setup = function () {
    ...
  };

  p.draw = () => {
    ...
  };
};

export default sketch;


在我的sketch逻辑中,我使用示例p变量来实现标准的p5.js功能,比如绘制形状。每当我需要使用p5类的构造函数,比如AudioInAmplitudeSoundFile等,我都会使用全局p5变量来创建它。例如:

new window.p5.AudioIn()


我相信这是必要的,因为p5声音插件库将函数和类添加到全局p5变量中。当我使用es6导入时,一定有一些混乱,声音插件没有正确添加到导入的p5类中。
希望有一天会有一个更好的p5.js的es6模块系统,但这似乎对我来说很有用。

ibps3vxo

ibps3vxo4#

我使用ViteSSG(Vite的静态站点生成器)来设置我的Vue应用程序,并在主入口文件main.ts中全局注册p5.js。

主入口文件:main.ts

import { ViteSSG } from 'vite-ssg'
import App from './App.vue'
import { setupLayouts } from 'virtual:generated-layouts'
import { routes } from 'vue-router/auto/routes'
import p5 from 'p5'

import 'uno.css'
import 'animate.css'
import './style.css'
import 'splitting/dist/splitting.css'
import 'splitting/dist/splitting-cells.css'

// Register p5 as a global variable
window.p5 = p5

export const createApp = ViteSSG(
  App,
  {
    routes: setupLayouts(routes),
    base: import.meta.env.BASE_URL,
  },
  ({ app, router, routes, isClient, initialState }) => {},
)

字符串
这样,p5就被设置为一个全局变量,可以在任何Vue组件中访问。

Vue组件示例在Vue组件中,我可以直接使用p5来加载和操作音频文件。

<template>
  <div ref="canvasWrapper"></div>
</template>

<script setup>
import '~/models/p5.sound'

let song

const preload = (p) => {
  console.log(p)
  song = p.loadSound('The_Deep.mp3')
}

onMounted(() => {
  new p5(preload)
})
</script>


我认为这个实现并不优雅,但它暂时解决了我目前的问题。我希望p5.js将来能有更好的ES6支持。

相关问题