一个简单的p5.js音频播放器,声音始终为 'undefined'

前端开发 2026-07-08

两天前我开始这个项目,目的是在逐步学习音频特征的同时,搭一个简单的音频播放器,但连第一步都过不去:让音频播放。浏览器里它总是抛出错误;"Uncaught (in promise) TypeError: can't access property (insert property the program first encounters here), sound is undefined"。我检查了路径、检查了源标签、拼写,把loadSound的命令放在setup函数里而不是preload。我现在已经陷入一堆无关紧要的细节里,因为我已经完全不知道问题可能出在哪里。这段代码基本上是来自某个网站的极简模板,只是在其中加了一个按钮:

let sound; 
let ply; 
function preload() { 

    // Initialize sound
    sound = loadSound("https://upload.wikimedia.org/wikipedia/commons/8/8a/Computer_Sound_(Gravity_Sound).wav"); 
} 

function setup() { 

    //Checking playing or not
    var ply = sound.isPlaying();
    console.log(ply);

    playStopButton = createButton('Play');
    playStopButton.position(20, 20);
    playStopButton.mousePressed(playStopSound);
} 

function playStopSound() {
    sound.play();
    console.log(getAudioContext().state);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/p5.sound.min.js"></script>

以下是最近的错误:

Uncaught (in promise) TypeError: can't access property "isPlaying", sound is undefined
    setup http://127.0.0.1:5501/sketch.js:43
    #F https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js:1
    #S https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js:1
    e https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js:1
    p5 https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js:1
    promise callback*p5< https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js:1
    <anonymous> https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js:1

再说一遍,除了属性名不同,所有错误看起来一模一样。结合测试和乱搞的尝试,我大致判断似乎是声音没有被正确加载到变量中,但我就是想不明白为什么?

解决方案

在p5.js v2中不支持 preload 函数。你需要在 setup 中等待 loadSound 函数。

let sound; 
let ply;

async function setup() { 
    sound = await loadSound("https://upload.wikimedia.org/wikipedia/commons/8/8a/Computer_Sound_(Gravity_Sound).wav");

    //Checking playing or not
    var ply = sound.isPlaying();
    console.log(ply);

    playStopButton = createButton('Play');
    playStopButton.position(20, 20);
    playStopButton.mousePressed(playStopSound);
} 

function playStopSound() {
    sound.play();
    console.log(getAudioContext().state);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/p5.sound.min.js"></script>

如果你想加载多个文件,可以使用 Promise.all 来并行加载它们,而不是按顺序一个个等待。

const [
    sound1,
    sound2,
    sound3,
] = await Promise.all([
    loadSound(sound1_url),
    loadSound(sound2_url),
    loadSound(sound3_url),
]);
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章