在 Raspberry Pi(Python 和 Socket)上播放 .wav 文件时遇到问题

Posted

技术标签:

【中文标题】在 Raspberry Pi(Python 和 Socket)上播放 .wav 文件时遇到问题【英文标题】:Having issues playing a .wav file on Raspberry Pi (Python & Socket) 【发布时间】:2021-04-23 21:55:24 【问题描述】:

所以我的代码是通过引用this post 和this post 来构建的,用于发送波形文件,这似乎是关于该主题的最受欢迎的 *** 帖子,但我似乎无法解决这个问题。所以,我的代码可以发送音频文件,但在 Pi 上播放它时只有一半的时间有效。首先,一些细节:

我正在尝试将笔记本电脑上生成的 .wav 音频文件发送到运行最新默认 Raspberry Pi 操作系统的 Raspberry Pi,然后通过连接的 USB 扬声器播放音频。

我发现它实际上是我用来播放音频的代码。有时它会播放整个文件,但有时它只播放四分之一或最后几秒钟。我该如何解决这个问题?

我尝试了多种不同的音频播放器,例如 pygame、pyttsx3 和下面显示的那个,即使出现错误,这段代码也能发挥最佳效果。

这是我的代码:

注意:服务器在树莓派上,我的电脑作为客户端发送.wav到服务器。

服务器:

def audio_reciever(): # this is the audio receiver
port = 65432                  # Reserve a port for your service.
s = socket.socket()             # Create a socket object
host = 'this is the pi ip'
chunk = 1024
# Get local machine name
s.bind((host, port))
f = open('voice.wav', 'w+b')
# Bind to the port
s.listen()                     # Now wait for client connection.
while True:
    conn, addr = s.accept()     # Establish connection with client.
    l = conn.recv(1024)
    while (l):
       f.write(l)
       l = conn.recv(1024)
    f.close()
    conn.send(b'Audio_Recieved')
    break
conn.close()
return

树莓派的音频播放器:

def audio_player():
  chunk = 1024
  wf = wave.open('voice.wav', 'rb')
  # create an audio object
  p = pyaudio.PyAudio()
  # open stream based on the wave object which has been input.
  stream = p.open(format =
                  p.get_format_from_width(wf.getsampwidth()),
                  channels = wf.getnchannels(),
                  rate = wf.getframerate(),
                  output = True)
  # read data (based on the chunk size)
  data = wf.readframes(chunk)
  # play stream (looping from beginning of file to the end)
  while data != b'':
      # writing to the stream is what *actually* plays the sound.
      stream.write(data)
      data = wf.readframes(chunk)
  stream.stop_stream()    # "Stop Audio Recording
  stream.close()          # "Close Audio Recording
  p.terminate()           # "Audio System Close
  wf.close()
  return

客户:

def audio_sender(self,command):
command = "command goes here"
print(command)
engine.save_to_file(command, 'voice.wav')
engine.runAndWait()
engine.stop()

arr = array('B') # create binary array to hold the wave file
result = stat("voice.wav")  # sample file is in the same folder
f = open("voice.wav", 'rb')
arr.fromfile(f, result.st_size) # using file size as the array length
HOST = 'this is the pi ip'
PORT = 65432
print("actually sending")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.send(arr)
    print('Finished sending...')
    s.close()
f.close()
os.remove('voice.wav')
print('done.')

我非常感谢一些帮助,以找出它有时会中断的原因,因为我需要此代码每次都按预期工作,因为需要为个人项目重复调用此代码。另外,有什么办法可以在 Pi 上播放音频文件时稍微减慢速度?

感谢您的宝贵时间。

【问题讨论】:

我建议您在十六进制编辑器中提取一个损坏的文件并将其与原始文件进行比较,这样您就可以看到问题可能是什么,这可以缩小您对导致代码的搜索范围问题。 感谢推荐!我实际上发现错误是我用来播放波形文件的方法。关于如何修复它的任何想法?有时它会播放整个文件,但有时它只播放后半部分或最后几秒 此外,sendallsend 更安全。 @blevlabs 也许最好问一个单独的、更集中的问题,特别是;我能想到的唯一问题是您遇到缓冲区溢出或不足,但我相信还有更多可能性。 相应地编辑了帖子。感谢您的提示 【参考方案1】:

我最终使用 PyGame 模块来播放音频。代码如下:

def playSound(filename):
  pygame.mixer.music.load(filename)
  pygame.mixer.music.play()
def audio_player():
  pygame.init()
  playSound('voice.wav')
  while pygame.mixer.music.get_busy() == True:
      continue
  return

【讨论】:

以上是关于在 Raspberry Pi(Python 和 Socket)上播放 .wav 文件时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

在raspberry pi中安装缺少的python包

并行计算Python / Raspberry Pi

Raspberry Pi 3B 和 RFID RC522 - Python TypeError

慢响应Firebase + Python + Raspberry pi

在 Raspberry PI 上使用 Python 和 OpenCV 进行图像处理 [关闭]

城会玩:Linux+Python+Raspberry Pi酿制啤酒