使用 pygame 从流中播放 MIDI 文件
Using pygame to play a MIDI file from stream
我想做的是:创建一个 MIDI 文件,但只在内存中,并将其输入 pygame.mixer.music.load()
。这是我一直在尝试的(我正在使用 here 的 MidiFile):
import pygame.mixer
import MidiFile3
import io
pygame.mixer.init()
midi = MidiFile3.MIDIFile(1) # midi file with one track
midi.addTrackName(0,0,"Track 1") #Track Name on track 0, position 0
midi.addTempo(0,0,120) #Tempo to 120 bpm on track 0, position 0
for i in range(8):
midi.addNote(0,0,60,i,1,100) #add 8 c1-notes to the track
bytestream = io.BytesIO()
midi.writeFile(bytestream)
pygame.mixer.music.load(bytestream.getvalue())
这里我收到错误信息
pygame.error: File path 'MThd' contains null characters
当我做的时候
bytestream = open('file.mid','wb')
midi.writeFile(bytestream)
bytestream.close()
pygame.mixer.music.load('file.mid')
它按预期工作。
当然,我知道包含文件名的字符串和包含文件内容的字节串是有区别的。但我发现这个 Post on Daniweb 使用字节流,这个例子对我有用。
我只是想不出如何让我的示例起作用。
music.load()
函数需要文件名或文件对象。
bytestream.getvalue()
是字节流的内容,貌似是文件名
您必须使用文件/BytesIO
对象本身:
pygame.mixer.music.load(bytestream)
我修复了如下问题:
bytestream = io.BytesIO()
midi.writeFile(bytestream)
temp = io.BytesIO(bytestream.getvalue())
pygame.mixer.music.load(temp)
看起来,writeFile()
操作以某种方式使 BytesIO 对象对 pygame.mixer.music.load()
方法无效。通过使用正确创建的字节流再次使用 BytesIO 的构造函数,我们神奇地得到了一个有效的字节流,我们可以传递给 pygame.mixer.music.load()
.
接受的答案虽然有效,但并不是正确的解决方案。写入字节流后,您需要做的就是将指针重置为开头。正确的代码(部分)如下:
bytestream = io.BytesIO()
midi.writeFile(bytestream)
bytestream.seek(0)
pygame.mixer.music.load(bytestream)
其实我也回答过类似的问题here。
我想做的是:创建一个 MIDI 文件,但只在内存中,并将其输入 pygame.mixer.music.load()
。这是我一直在尝试的(我正在使用 here 的 MidiFile):
import pygame.mixer
import MidiFile3
import io
pygame.mixer.init()
midi = MidiFile3.MIDIFile(1) # midi file with one track
midi.addTrackName(0,0,"Track 1") #Track Name on track 0, position 0
midi.addTempo(0,0,120) #Tempo to 120 bpm on track 0, position 0
for i in range(8):
midi.addNote(0,0,60,i,1,100) #add 8 c1-notes to the track
bytestream = io.BytesIO()
midi.writeFile(bytestream)
pygame.mixer.music.load(bytestream.getvalue())
这里我收到错误信息
pygame.error: File path 'MThd' contains null characters
当我做的时候
bytestream = open('file.mid','wb')
midi.writeFile(bytestream)
bytestream.close()
pygame.mixer.music.load('file.mid')
它按预期工作。
当然,我知道包含文件名的字符串和包含文件内容的字节串是有区别的。但我发现这个 Post on Daniweb 使用字节流,这个例子对我有用。
我只是想不出如何让我的示例起作用。
music.load()
函数需要文件名或文件对象。
bytestream.getvalue()
是字节流的内容,貌似是文件名
您必须使用文件/BytesIO
对象本身:
pygame.mixer.music.load(bytestream)
我修复了如下问题:
bytestream = io.BytesIO()
midi.writeFile(bytestream)
temp = io.BytesIO(bytestream.getvalue())
pygame.mixer.music.load(temp)
看起来,writeFile()
操作以某种方式使 BytesIO 对象对 pygame.mixer.music.load()
方法无效。通过使用正确创建的字节流再次使用 BytesIO 的构造函数,我们神奇地得到了一个有效的字节流,我们可以传递给 pygame.mixer.music.load()
.
接受的答案虽然有效,但并不是正确的解决方案。写入字节流后,您需要做的就是将指针重置为开头。正确的代码(部分)如下:
bytestream = io.BytesIO()
midi.writeFile(bytestream)
bytestream.seek(0)
pygame.mixer.music.load(bytestream)
其实我也回答过类似的问题here。