如何在python中播放wav文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17657103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 08:47:59  来源:igfitidea点击:

how to play wav file in python?

pythonaudiopygamepyglet

提问by nim4n

I tried pygame for playing wav file like this:

我试过 pygame 播放 wav 文件是这样的:

import pygame
pygame.init()

pygame.mixer.music.load("mysound.wav")
pygame.mixer.music.play()
pygame.event.wait()

but It change the voice and I don't know why! I read this linksolutions and can't solve my problem with playing wave file!

但它改变了声音,我不知道为什么!我阅读了此链接解决方案,但无法解决播放波形文件的问题!

for this solution I dont know what should I import?

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

s = Sound() 
s.read('sound.wav') 
s.play()

and for this solution /dev/dsp dosen't exist in new version of linux :

对于此解决方案,新版本的 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()

and when I tried pyglet It give me this error:

当我尝试 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

采纳答案by zhangyangyu

You can use PyAudio. An example here on my Linux it works:

您可以使用PyAudio。在我的 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()  

回答by Gene

The reason pygame changes your audio is mixer defaults to a 22k sample rate:

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

initialize the mixer module
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096): return None

Your wav is probably 8k. So when pygame plays it, it plays roughly twice as fast. So specify your wav frequency in the init.

你的 wav 可能是 8k。所以当 pygame 播放它时,它的播放速度大约是它的两倍。所以在 init.d 文件中指定你的 wav 频率。

Pyglet has some problems correctly reading RIFF headers. If you have a very basic wav file (with exactly a 16 byte fmt block) with no other information in the fmt chunk (like 'fact' data), it works. But it makes no provision for additional data in the chunks, so it's really not adhering to the RIFF interface specification.

Pyglet 在正确读取 RIFF 标头时存在一些问题。如果您有一个非常基本的 wav 文件(恰好有一个 16 字节的 fmt 块),并且 fmt 块中没有其他信息(如“事实”数据),则它可以工作。但是它没有在块中提供额外的数据,所以它真的不遵守 RIFF 接口规范。

回答by driedler

Works for me on Windows: https://pypi.org/project/playsound/

在 Windows 上为我工作:https: //pypi.org/project/playsound/

>>> from playsound import playsound
>>> playsound('/path/to/a/sound/file/you/want/to/play.wav')