【问题标题】:Pygame won't work on Mac mini with no monitor connectedPygame 无法在未连接显示器的 Mac mini 上运行
【发布时间】:2014-01-19 09:19:47
【问题描述】:

我正在制作一个 Makey Makey 项目,但就这个问题而言,它可以被视为一个简单的键盘。

我制作了一个 YouTube 视频来展示该项目,我想要相同的功能,除了屏幕破解: http://youtu.be/98ATkZUR48k

我把它连接到我的厨房橱柜上,所以当我打开其中一个时,它会播放一首歌。

我将它连接到我的 Mac mini,只要它连接了屏幕,它就可以正常工作。 当我拔下屏幕时,歌曲停止播放。

我了解到 Mac mini 会根据是否连接显示器来加载不同的图形驱动程序,尤其是不支持 OpenGL 的显示器。

这是我为什么它不起作用的直觉,但我不确定。

所以我的问题是 pygame 是否需要 OpenGL 才能运行,有没有办法禁用它?

我发现的唯一一件事就是这些硬件解决方案,对于我的用例,我认为这些解决方案有点矫枉过正: https://macminicolo.net/blog/files/build-a-dummy-dongle-for-a-headless-mac-mini

更新:


正如@Torxed 指出的那样,Pygame 严重依赖 OpenGL,所以也许另一个模块或多个模块的组合会更有用。

我选择 Pygame 是因为我可以:

  • 轻松循环获取键盘输入
  • 一次播放多个声音文件
  • 能够暂停和恢复声音文件

您能否推荐一个模块或模块组合来帮助我轻松完成这两个功能。

这是我现在用 pygame 运行的代码:

import sys, pygame
from pygame.mixer import Sound, Channel

class MakeyCupboard :
    channelIdCounter = 0
    def __init__(self, fileName):
        self.channelId = MakeyCupboard.channelIdCounter
        MakeyCupboard.channelIdCounter = MakeyCupboard.channelIdCounter + 1
        self.channel = Channel(MakeyCupboard.channelIdCounter)
        self.sound = Sound(fileName)
        self.channel.play(self.sound, -1)
        self.channel.pause()


pygame.init()

dictCupboard = {
    pygame.K_w : MakeyCupboard("rien.ogg"),
    pygame.K_a : MakeyCupboard("train.ogg"),
    pygame.K_s : MakeyCupboard("stronger.ogg")
}

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN :
            try : 
                makeyCupboard = dictCupboard[event.key]
                makeyCupboard.channel.pause()
            except KeyError:
                pass

        elif event.type == pygame.KEYUP :
            try:
                makeyCupboard = dictCupboard[event.key]
                makeyCupboard.channel.unpause()
            except KeyError:
                pass

【问题讨论】:

  • 是的 afaik Pygame 依赖于 OpenGL,它主要是围绕它的一个包装器。一旦你移除监视器,OSX 将禁用渲染引擎,从而使任何试图使用 OpenGL 的东西崩溃。使用一个在 Cocoa 下渲染的,我认为它在 OSX 中的支持更灵活。一个使用它的库是wiki.python.org/moin/PyGUI
  • 感谢您的信息。我将研究 PyGUI。 Pygame 拥有我需要的所有东西,以便尽快获得我想要的功能。现在我正在使用硬件解决方案:我有一根 DVI 电缆连接到 Mac,它的另一端随机接触我的加热器,这使它认为它连接了显示器;如果我自己可以这么说,那不是很优雅。我认为这很荒谬,因为基本上我只使用声音而且我的程序因为 OpenGL 而无法运行 :)
  • 除非您稍后需要图形,否则我会同时使用另一种解决方案。但即便如此,它可能本身就是一个单独的项目?如果您只需要哔哔声,还有sys.stdout.write('\a')

标签: python macos opengl pygame


【解决方案1】:

如果您只对播放声音感兴趣,这是解决问题的一种方法:

from subprocess import Popen, STDOUT, PIPE
from time import sleep
audio_file = "/tmp/music.wav"

x = Popen('afplay ' + audio_file, shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
while x.poll() == None:
    output = x.stdout.readline() # You need this!
    # Otherwise the output buffer will get full and hang your application.
    # Or just remove stdout=PIPE, stdin=PIPE, stderr=STDOUT from the Popen() call
    # if you're not interested in the output of the application.
    sleep(0.025)    
print('Music stoped')

更新:

由于您想暂停/切换曲目,因此您需要通过x.stdin.write('next\n') 发送命令,或者将afplay 作为命令。

另一种解决方案是使用找到的库之一 here,例如:

PyAudio 看起来很简单:

import pyaudio
import wave
import sys

CHUNK = 1024

if len(sys.argv) < 2:
    print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
    sys.exit(-1)

wf = wave.open(sys.argv[1], 'rb')

p = pyaudio.PyAudio()

stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                channels=wf.getnchannels(),
                rate=wf.getframerate(),
                output=True)

data = wf.readframes(CHUNK)

while data != '':
    stream.write(data)
    data = wf.readframes(CHUNK)

stream.stop_stream()
stream.close()

p.terminate()

【讨论】:

  • 我不确定使用此命令是否可以让我暂停和取消暂停正在播放的曲目。也使用 python 模块看起来更优雅。这仅足以播放曲目。对不起,我没有在规格中提到这一点。我制作了一个快速视频来展示该项目的功能以及问题所在。请检查 youtube 链接的问题。
猜你喜欢
  • 1970-01-01
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
相关资源
最近更新 更多