一、背景
需要用Python做软件,能够实现播放音频。我的需求是:
- 载入音频文件
- 能够循环播放或单次播放
- 能够两个音频同时播放,形成手动叠加的效果
目前在Python的音频库有很多,比如Pydub、SimpleAudio、pygame、playsound等,这些库都可以实现音频的播放,但是在我的2、3需求上很难同时兼顾的实现,因此结合python的线程自己再次封装出了一个音频播放类。
二、依赖
使用threading与simpleaudio两个库完成,threading是自带的,simpleaudio有简单的几个函数。
2.1 载入与播放-wave_obj
import simpleaudio as sa
audio_path = "./Simple.wav"
wave_obj = sa.WaveObject.from_wave_file(audio_path)
play_obj = wave_obj.play()
simpleaudio是使用在wave_obj上创建一个play对象来播放音频的,这个过程会同时播放音频与创建对象。
2.2 停止-play_obj
# 播放直到结束,会占用线程
play_obj.wait_done()
# 强制结束所有音频
sa.stop_all()
三、自建类
根据以上两个方法,自己创建播放类,如下所示:
import threading
import simpleaudio as sa
class audioPlayer(object):
def __init__(self, audio_path):
self.wave_obj = sa.WaveObject.from_wave_file(audio_path)
self.play_obj = None
self.thread = threading.Thread(target=self.play_sound)
self.thread.setDaemon(True)
self.play_flag = False
def play_sound(self):
if not self.play_flag:
return
while self.play_flag:
self.play_obj = self.wave_obj.play()
self.play_obj.wait_done()
def play(self):
self.play_flag = True
self.thread.start()
def play_once(self):
self.wave_obj.play()
def stop(self):
self.play_flag = False
self.play_obj.stop()
self.thread.join()
self.thread = threading.Thread(target=self.play_sound)
self.thread.setDaemon(True)
if __name__ == "__main__":
import time
test_audio1 = audioPlayer("./Audio/Finish.wav")
test_audio = audioPlayer("./Audio/OnProcess.wav")
test_audio.play()
time.sleep(3)
test_audio1.play_once()
time.sleep(7)
# sa.stop_all()
test_audio.stop()
至此,完成播放类的创建与使用。