简体   繁体   English

使用 Pyaudio 和 Ursina 时代码延迟

[英]Code gets delayed when using Pyaudio and Ursina

All I'm trying to do is play a sound with Pyaudio while using the Ursina engine for the rest of my game.我要做的就是在使用 Ursina 引擎为我的游戏的 rest 播放声音时使用 Pyaudio。 The game won't start until the sound is done playing.直到声音播放完毕,游戏才会开始。 This isn't the case when I use the case when I use the playsound module.当我使用 playsound 模块时,情况并非如此。 It also isn't a lag problem since my Ursina window is always at 60 fps when the sound is playing.这也不是延迟问题,因为我的 Ursina window 在播放声音时始终保持 60 fps。 `from ursina import * `从 ursina 进口 *

import random
import pyaudio
import wave
from playsound import playsound

def play(file):
    CHUNK = 1024
    sound = wave.open(file, 'rb')
    p = pyaudio.PyAudio()
    stream = p.open(format=p.get_format_from_width(sound.getsampwidth()),
        channels=sound.getnchannels(),
        rate=sound.getframerate(),
        output=True,
        input =False)

    data = sound.readframes(CHUNK)
    while len(data)>0:
        stream.write(data)
        data = sound.readframes(CHUNK)
    stream.stop_stream()
    stream.close()
    p.terminate()
app = Ursina()
quantity = Entity(color=color.clear,position=(0,0,-30))
points=Entity(color=color.clear,position=(0,0,-30))
high= Entity(color=color.clear, position=(0, 0, -30))
score_text = int(points.x)
score_text2 = str(score_text)
score = Text(text=score_text2, scale=5,position=(-0.6,0.35,-18), color=color.black)
score_top = Text(text="score:", scale=3,position=(-0.65,0.45,-18), color=color.black); highscore_text = int(high.x)
highscore_text2 = str(highscore_text)
highscore = Text(text=highscore_text2, scale=5, position=(0.6, 0.35, -18), color=color.black)
highscore_top = Text(text="high score:", scale=3,position=(0.45,0.45,-18), color=color.black)
respawn_texture = Entity(model='quad',scale=(0.3,0.1),position=(0,0,5),texture=load_texture('textures/replay'))
menu_texture = Entity(model='quad',scale=(0.3,0.1),position=(0,-0.1,5),texture=load_texture('textures/main_menu'))
while quantity.x < 0:
    quantity.x = 0

class background(Button):
    def __init__(self):
        super().__init__(
            model = 'cube',
            parent=scene,
            color=color.white,
            position=(0,0,4.5),
            scale = (30,30,2))

    def input(self, key):
        if self.hovered:
            if key == 'left mouse down':
                playsound("audio/screeching.m4a", block=False)
                camera.z = 4
                points.x = 0

class Tile(Button):
    def __init__(self):
        quantity.x +=1
        placement = random.randint(-4, 4)
        potential_color_list = (color.red,color.black,color.black,color.black,color.black,color.black)

        super().__init__(
            model = 'quad',
            parent=scene,
            color= random.choice(potential_color_list),
            position=(placement,quantity.x * 2 + 3,3),
            scale = (random.uniform(0.1,3),random.uniform(0.5,3))),


    def input(self,key):
        if self.hovered:
            if key == 'left mouse down':
                if points.x == 0:
                    play('audio/Game_music.wav')
                if self.color == color.black:
                    play("audio/scored.wav")
                    destroy(self)
                    quantity.x -=1
                    amount = random.randint(1,3)
                    multiplier_calculations = points.x / 10 + 1
                    Multiplier = int(multiplier_calculations)
                    points.x += Multiplier
                    score.Text = points.x
                    score_text = int(points.x)
                    score_text2 = str(score_text)
                    score.text = score_text2
                    if quantity.x <= 0:
                        if amount == 1:
                            Tile()
                        if amount == 2:
                            Tile()
                            Tile()
                        if amount == 3:
                            Tile()
                            Tile()
                            Tile()

                if self.color == color.red:
                    play("audio/screeching.m4a")
                    camera.z = 4
                if high.x < points.x:
                    high.x = points.x
                    highscore_text = int(high.x)
                    highscore_text2 = str(highscore_text)
                    highscore.text = highscore_text2
                    score.Text=points.x

        if camera.z == 4:
            destroy(self)
    def update(self):
        speed = points.x / 40 + 3
        if camera.z == -20 and points.x != 0:
            self.y -= speed * time.dt
        else:
            self.position=(0,4,3)
            self.color = color.black
        if self.y <= -6.5:
            if self.color == color.black:
                playsound("audio/screeching.m4a", block=False)
                camera.z = 4
                destroy(self)
            if self.color == color.red:
                destroy(self)
                quantity.x -= 1
                if quantity <= 0:
                    amount = random.randint(1,3)
                    if amount == 1:
                        Tile()
                    if amount == 2:
                        Tile()
                        Tile()
                    if amount == 3:
                        Tile()
                        Tile()
                        Tile()
        if camera.z == 4:
            score.text = '0'
            destroy(self)
            Tile()
            quantity.x = 0


class menu(Button):
    def __init__(self):
        super().__init__(
            model = 'quad',
            color=color.clear,
            parent=scene,
            position=(0,-0.05,5),
            scale = (0.09,0.03))

    def input(self, key):
        if self.hovered:
            if key == 'left mouse down':
                playsound("audio/bounce.m4a", block=False)
                points.x = 0
                quantity.x = 0
                camera.z = 8

class play_again(Button):
    def __init__(self):
        super().__init__(
            model = 'quad',
            color=color.clear,
            parent=scene,
            position=(0,0,4.8),
            scale = (0.09,0.03))

    def input(self, key):
        if self.hovered:
            if key == 'left mouse down':
                playsound("audio/bounce.m4a", block=False)
                points.x = 0
                quantity.x = 0
                camera.z = -20
                Tile()

menu()
play_again()
background()
Tile()
app.run()`

while loops will block the main ursina loop, and thus stop ursina fron running until the while loop has finished. while 循环将阻塞主 ursina 循环,从而停止 ursina fron 运行,直到 while 循环完成。 To go around that you could use pyaudio in another thread.到 go 周围,您可以在另一个线程中使用 pyaudio。 However, is there any reason why you can't use ursina's Audio class to play sound instead?但是,您有什么理由不能使用 ursina 的 Audio class 来代替播放声音?

Example:例子:

a = Audio('jump_sfx')

If you need to generate the waveform from code.如果您需要从代码生成波形。 It would make sense to me to do that beforehand and save it, not every time you want to play it.事先这样做并保存它对我来说是有意义的,而不是每次你想玩它时。

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

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