如何在python中播放wav文件?

如何在python中播放wav文件?,python,audio,pygame,pyglet,Python,Audio,Pygame,Pyglet,我尝试了pygame来播放wav文件,如下所示: import pygame pygame.init() pygame.mixer.music.load("mysound.wav") pygame.mixer.music.play() pygame.event.wait() 但它改变了声音,我不知道为什么! 我阅读解决方案,但无法解决播放wave文件的问题 对于此解决方案,我不知道应该导入什么 s = Sound() s.read('sound.wav') s.play() 对于此解决

我尝试了pygame来播放wav文件,如下所示:

import pygame
pygame.init()

pygame.mixer.music.load("mysound.wav")
pygame.mixer.music.play()
pygame.event.wait()
但它改变了声音,我不知道为什么! 我阅读解决方案,但无法解决播放wave文件的问题

对于此解决方案,我不知道应该导入什么

s = Sound() 
s.read('sound.wav') 
s.play()
对于此解决方案,新版本的linux中不存在/dev/dsp文件:

from wave import open as waveOpen
from ossaudiodev import open as ossOpen
s = waveOpen('tada.wav','rb')
(nc,sw,fr,nf,comptype, compname) = s.getparams( )
dsp = ossOpen('/dev/dsp','w')
try:
  from ossaudiodev import AFMT_S16_NE
except ImportError:
  if byteorder == "little":
    AFMT_S16_NE = ossaudiodev.AFMT_S16_LE
  else:
    AFMT_S16_NE = ossaudiodev.AFMT_S16_BE
dsp.setparameters(AFMT_S16_NE, nc, fr)
data = s.readframes(nf)
s.close()
dsp.write(data)
dsp.close()
当我尝试pyglet时,它给了我一个错误:

import pyglet

music = pyglet.resource.media('mysound.wav')
music.play()

pyglet.app.run()
--------------------------

nima@ca005 Desktop]$ python play.py
Traceback (most recent call last):
  File "play.py", line 4, in <module>
    music = pyglet.resource.media('mysound.wav')
  File "/usr/lib/python2.7/site-packages/pyglet/resource.py", line 587, in media
    return media.load(path, streaming=streaming)
  File "/usr/lib/python2.7/site-packages/pyglet/media/__init__.py", line 1386, in load
    source = _source_class(filename, file)
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 194, in __init__
    format = wave_form.get_format_chunk()
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 174, in get_format_chunk
    for chunk in self.get_chunks():
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 110, in get_chunks
    chunk = cls(self.file, name, length, offset)
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 155, in __init__
    raise RIFFFormatException('Size of format chunk is incorrect.')
pyglet.media.riff.RIFFFormatException: Size of format chunk is incorrect.
AL lib: ReleaseALC: 1 device not closed
导入pyglet music=pyglet.resource.media('mysound.wav') 音乐播放 pyglet.app.run()文件 -------------------------- nima@ca005桌面]$python play.py 回溯(最近一次呼叫最后一次): 文件“play.py”,第4行,在 music=pyglet.resource.media('mysound.wav') 文件“/usr/lib/python2.7/site packages/pyglet/resource.py”,第587行,在介质中 返回媒体。加载(路径,流=流) 文件“/usr/lib/python2.7/site packages/pyglet/media/_init__.py”,第1386行,已加载 source=\u source\u类(文件名、文件名) 文件“/usr/lib/python2.7/site packages/pyglet/media/riff.py”,第194行,在__ format=wave\u form.get\u format\u chunk() 文件“/usr/lib/python2.7/site packages/pyglet/media/riff.py”,第174行,get_格式 对于self中的chunk.get_chunks(): 文件“/usr/lib/python2.7/site packages/pyglet/media/riff.py”,第110行,在get_块中 chunk=cls(self.file、名称、长度、偏移量) 文件“/usr/lib/python2.7/site packages/pyglet/media/riff.py”,第155行,在__ raise RIFFORMATEXCEPTION('格式块大小不正确') pyglet.media.riff.RIFFFormatException:格式块的大小不正确。 AL lib:ReleaseALC:1设备未关闭 您可以使用。在我的Linux上,这里有一个例子:

#!usr/bin/env python  
#coding=utf-8  

import pyaudio  
import wave  

#define stream chunk   
chunk = 1024  

#open a wav format music  
f = wave.open(r"/usr/share/sounds/alsa/Rear_Center.wav","rb")  
#instantiate PyAudio  
p = pyaudio.PyAudio()  
#open stream  
stream = p.open(format = p.get_format_from_width(f.getsampwidth()),  
                channels = f.getnchannels(),  
                rate = f.getframerate(),  
                output = True)  
#read data  
data = f.readframes(chunk)  

#play stream  
while data:  
    stream.write(data)  
    data = f.readframes(chunk)  

#stop stream  
stream.stop_stream()  
stream.close()  

#close PyAudio  
p.terminate()  

pygame更改音频的原因是混音器默认为22k采样率:

initialize the mixer module
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096): return None
您的wav可能是8k。所以当pygame玩它时,它的速度大约是它的两倍。因此,请在init中指定wav频率

Pyglet在正确读取RIFF头时遇到一些问题。如果您有一个非常基本的wav文件(正好有一个16字节的fmt块),而fmt块中没有其他信息(如“事实”数据),那么它可以工作。但是它没有在数据块中提供额外的数据,因此它实际上不符合RIFF接口规范。

在Windows上适用于我:

注意:这在Windows中有一个bug,它没有关闭流。 我在此处添加了修复的PR:

有两个不同的模块用于播放声音和音乐,分别为模块和模块。此模块包含用于加载声音对象和控制播放的类。文件中解释了差异:

音乐播放和常规声音播放的区别在于,音乐是流式播放的,而不是一次实际加载的。混音系统一次只支持一个音乐流

如果要播放单个wav文件,必须初始化模块并从该文件创建对象。调用以开始播放文件。最后,您必须等待文件播放

用于以秒为单位获取声音的长度,并等待声音结束: (的参数以毫秒为单位)

导入pygame
pygame.mixer.init()
my_sound=pygame.mixer.sound('mysound.wav'))
我的声音。播放()
pygame.time.wait(int(my_sound.get_length()*1000))
或者,您可以使用来测试是否混音。在循环中连续查询混合器的状态:

导入pygame
pygame.init()
pygame.mixer.init()
my_sound=pygame.mixer.sound('mysound.wav'))
我的声音。播放()
当pygame.mixer.get_busy()时:
pygame。时间。延迟(10)
pygame.event.poll()

你说的“它改变了声音”是什么意思?它把男人的声音变成了孩子的声音(很抱歉,我的英语不是很好,我找不到合适的词来解决我的问题)你的意思是,它听起来比它应该的音调高?是的,它有更高的音调。我只收到一个附加错误:更改
而数据!='':
while len(data)>0:
解决了while进入无限循环的问题。这个问题只有在pyaudio 0.2.9从python 3.4升级到3.5后才会出现来源:不幸的是,这在windows中为播放的每个声音打开了一个新的LAV音频解码器进程,这很糟糕,因为否则它很简单。我也注意到了这一点。我已经添加了修复的PR。请参阅我的最新评论
>>> from playsound import playsound
>>> playsound('/path/to/a/sound/file/you/want/to/play.wav')