import time import pygame import os from mutagen.mp3 import MP3 #获取地址并拼接 list1=os.listdir(\'D:\音乐\') list2=[] for i in list1: s=os.path.join(r\'D:\音乐\',i) list2.append(s) for n in list2: # 获取每一首歌的时长 audio = MP3(n) pygame.mixer.init() path = n pygame.mixer.music.load(path) pygame.mixer.music.play() \'\'\'加上多进程加可以实现暂停,播放下一首等功能了\'\'\' time.sleep(int(audio.info.length)) \'\'\' import time:引入time模块,使程序能够长时间存活 import pygame:引入我们pygame中的模块 import os:引入处理获取MP3文件地址的模块 from mutagen.mp3 import MP3:引入获取每一个MP3文件时长的模块 \'\'\'
from threading import Thread from pygame import mixer from os import path,listdir from random import randint def music_thread(): global button,music_index,music_list mixer.init() music_num = len(music_list) while True: if music_index < music_num: mixer.music.load(music_list[music_index]) mixer.music.play() elif order_state == \'7\' and music_index >= music_num: music_index = 0 mixer.music.load(music_list[music_index]) mixer.music.play() while mixer.music.get_busy(): # get_busy()查看是否处于播放状态 if button == \'1\': mixer.music.unpause() button = None elif button == \'2\': mixer.music.pause() button = None elif (order_state==\'6\' and not mixer.music.get_busy()) or (order_state==\'6\' and (button==\'3\' or button==\'4\')): music_index = randint(0,music_num-1) button = None elif button == \'3\' or not mixer.music.get_busy(): music_index += 1 mixer.music.stop() button = None elif button == \'4\': music_index -= 1 mixer.music.stop() button = None elif button == 0 and order_state == \'5\': music_index = 0 mixer.music.stop() button = None music_index = 0 button = None order_state = \'5\' music_list=[] print(path.exists(\'./music_path.txt\')) if not path.exists(\'./music_path.txt\'): music_path = input(\'请输入一个音乐文件目录的绝对路径:\') with open(\'./music_path.txt\',\'w\',encoding=\'utf-8\') as f: f.write(music_path) else: with open(\'./music_path.txt\',\'r\',encoding=\'utf-8\') as f: music_path = f.read() if __name__ == \'__main__\': if path.exists(music_path): list1 = listdir(music_path) for i in list1: if i[-3:] == \'mp3\': file_path = path.join(music_path, i) music_list.append(file_path) music_create = Thread(target=music_thread) music_create.setDaemon(True) music_create.start() \'\'\' 0:空 [1:播放|2:暂停|3:下一首|4:上一首] [5:\'顺序播放\',6:\'随机播放\',7:\'循环播放\',8:\'退出\'] \'\'\' print(\'mp3player功能说明:\') for i, e in enumerate([\'播放\', \'暂停\', \'下一首\', \'上一首\', \'顺序播放/重新播放\', \'随机播放\', \'循环播放\', \'退出\']): print(\' {} 输入{}表示"{}"\'.format(i + 1, i + 1, e)) while True: button = input(\'>>>\') if button in [\'6\', \'7\']: order_state = button button = None elif button == \'5\': order_state = button button = 0 elif button == \'8\': break else: print(\'目录不存在\')
import pyglet window = pyglet.window.Window(resizable=True) @window.event def on_draw(): player.get_texture().blit(0, 0) if __name__ == "__main__": player = pyglet.media.Player() source = pyglet.media.load("F:\\FFOutput\\parent.vob") player.queue(source) player.play() pyglet.app.run()
eyed3
eyeD3 一般只能处理MP3文件,功能上相对来说也是比较简单一点。使用 import eyed3 导入eyeD3 库,然后使用load方法加载mp3文件,后面的几行分别是设置 artist,album等等 ID3 tag ,直接看代码就能看出来,就不说了。如果想显示mp3文件内部的ID3 tag信息,直接print 相应的tag就行了,比如 print(audiofile.tag.artist)等等,当然,前提是你的MP3 metadata得储存了这些信息。其实还有一些更复杂和高级的用法,大家有兴趣直接去官方文档看吧,地址:https://eyed3.readthedocs.io/en/latest/。eyeD3 主要就是处理 MP3文件的metadata的,至于解析音频之类的就得用其他的库了。
import eyed3 audiofile = eyed3.load("song.mp3") audiofile.tag.artist = u"Integrity" audiofile.tag.album = u"Humanity Is The Devil" audiofile.tag.album_artist = u"Integrity" audiofile.tag.title = u"Hollow" audiofile.tag.track_num = 2 audiofile.tag.save()
pydub
这里是说python自带的wave模块只能处理 wav 格式的音频文件,如果要想处理类似MP3格式的文件,就得要装 ffmpeg或者libav了。
ffmpeg 是一个跨平台的 可以用来 记录、转化音频与视频的工具,如果你做过数字信号处理方面的工作,对它应该不陌生。还有一个libav,其实是从ffmpeg分出来的一个分支,功能和 ffmpeg差不多,二者你任选一个下载就可以了。windows下直接选择可执行文件安装即可。
还是看官网的例子来介绍吧。
I:打开 mp3或者mp4等文件
可以采用如下的命令:
1 from pydub import AudioSegment 2 3 song = AudioSegment.from_wav("never_gonna_give_you_up.wav") 4 song = AudioSegment.from_mp3("never_gonna_give_you_up.mp3") 5 6 ogg_version = AudioSegment.from_ogg("never_gonna_give_you_up.ogg") 7 flv_version = AudioSegment.from_flv("never_gonna_give_you_up.flv") 8 9 mp4_version = AudioSegment.from_file("never_gonna_give_you_up.mp4", "mp4") 10 wma_version = AudioSegment.from_file("never_gonna_give_you_up.wma", "wma") 11 aac_version = AudioSegment.from_file("never_gonna_give_you_up.aiff", "aac")
可以打开任何 ffmpeg支持的文件类型,从上面可以看出,主要有 from_filetype()方法,filetype为具体的文件类型,比如 wav,mp3等
或者通用的 from_file()方法,但是这个方法必须在第二个参数指定打开文件的类型,返回的结果都是 AudioSegment对象。
II:切割音频
1 # pydub does things in milliseconds 2 ten_seconds = 10 * 1000 3 4 first_10_seconds = song[:ten_seconds] 5 6 last_5_seconds = song[-5000:]
注意pydub中的标准时间为毫秒,上面的代码就得到了音乐的前10秒和后5秒,非常简单。
III:调整音量
1 # boost volume by 6dB 2 beginning = first_10_seconds + 6 3 4 # reduce volume by 3dB 5 end = last_5_seconds - 3
+6 就表示将音乐的音量提高6分贝,-3就表示将音乐的音量降低3分贝
IV: 拼接两段音乐
without_the_middle = beginning + end
without_the_middle.duration_seconds
拼接之后的音乐时长是两段音乐时长之和,可以通过 .duration_seconds方法来获取一段音乐的时长。这与使用 len(audio)/1000.0得到的结果是一样的。
V:将音乐翻转(reverse)
1 # song is not modified 2 # AudioSegments are immutable 3 backwards = song.reverse()
注意 AudioSegment 对象是不可变的,上面使用reverse 方法不会改变song这个对象,而是会返回一个新的AudioSegment对象,其他的方法也是这样,需要注意。reverse简单来说就是 将音乐从尾部向头部开始逆序播放,我试了一下,发现转换之后还真的挺有意思的。
VI:crossfade(交叉渐入渐出方法)
1 # 1.5 second crossfade 2 with_style = beginning.append(end, crossfade=1500)
crossfade 就是让一段音乐平缓地过渡到另一段音乐,上面的crossfade = 1500 表示过渡的时间是1.5秒。
VII:repeat(重复音乐片段)
# repeat the clip twice do_it_over = with_style * 2
上面的代码让音乐重复播放两次
VIII:fade in and fade out(逐渐增强与逐渐减弱)
# 2 sec fade in, 3 sec fade out awesome = do_it_over.fade_in(2000).fade_out(3000)
逐渐增强2秒,逐渐减弱3秒
XI:save(保存)
awesome.export("mashup.mp3", format="mp3") awesome.export("mashup.mp3", format="mp3", tags={\'artist\': \'Various artists\', \'album\': \'Best of 2011\', \'comments\': \'This album is awesome!\'})
这里展示了两种保存的形式,都是使用export方法,要指定保存的格式,使用format 参数,但第二种方法多了一个tags参数,其实看一下应该就很容易明白,是保存 歌曲ID3 tag信息的。
以上只是pydub 使用方法的初步介绍,还有其他非常多的功能,请自行移步官方API 文档:
介绍的非常详细。
PyAudio
又是一个功能强大的处理音频库。官方介绍:
PyAudio provides Python bindings for PortAudio, the cross-platform audio I/O library. With PyAudio, you can easily use Python to play and record audio on a variety of platforms. PyAudio is inspired by:
- pyPortAudio/fastaudio: Python bindings for PortAudio v18 API.
- tkSnack: cross-platform sound toolkit for Tcl/Tk and Python.
Pyaudio 提供了对于跨平台的 PortAudio(处理 audio输入输出的库)的绑定,PyAudio可以让你轻松录制与播放音频。
废话不多说,直接看官方文档(https://people.csail.mit.edu/hubert/pyaudio/docs/)提供的一个quick start 的代码
1 """PyAudio Example: Play a wave file.""" 2 3 import pyaudio 4 import wave 5 import sys 6 7 CHUNK = 1024 8 9 if len(sys.argv) < 2: 10 print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0]) 11 sys.exit(-1) 12 13 wf = wave.open(sys.argv[1], \'rb\') 14 15 # instantiate PyAudio (1) 16 p = pyaudio.PyAudio() 17 18 # open stream (2) 19 stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), 20 channels=wf.getnchannels(), 21 rate=wf.getframerate(), 22 output=True) 23 24 # read data 25 data = wf.readframes(CHUNK) 26 27 # play stream (3) 28 while len(data) > 0: 29 stream.write(data) 30 data = wf.readframes(CHUNK) 31 32 # stop stream (4) 33 stream.stop_stream() 34 stream.close() 35 36 # close PyAudio (5) 37 p.terminate()
当然,这个提供的是使用命令行参数接收音频文件的形式,CHUNK 是一次读取的音频byte数量,p = pyaudio.PyAudio()初始化一个
PyAudio对象,然后使用其open方法打开一个输入输出流,这里指定了output=True说明这是一个输出流,即我们是往stream中添加data,如果这里改为 input = True就是变成输入流了,一般是从设备的标准 audio device ,对于电脑来说可能就是麦克风了,来读取音频data。使用wave打开一个 .wav 文件,然后使用 readframes方法每次读取 CHUNK 这么多的数据,将数据写入 stream,直到读完为止。写入stream的audio data 就会不断通过麦克风播放出来了,于是我们就可以听到音乐了。最后在结束的时候,注意要关闭相应的对象以释放资源。
还有一种方法是使用callback(回调函数)函数,代码如下:
1 """PyAudio Example: Play a wave file (callback version).""" 2 3 import pyaudio 4 import wave 5 import time 6 import sys 7 8 if len(sys.argv) < 2: 9 print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0]) 10 sys.exit(-1) 11 12 wf = wave.open(sys.argv[1], \'rb\') 13 14 # instantiate PyAudio (1) 15 p = pyaudio.PyAudio() 16 17 # define callback (2) 18 def callback(in_data, frame_count, time_info, status): 19 data = wf.readframes(frame_count) 20 return (data, pyaudio.paContinue) 21 22 # open stream using callback (3) 23 stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), 24 channels=wf.getnchannels(), 25 rate=wf.getframerate(), 26 output=True, 27 stream_callback=callback) 28 29 # start the stream (4) 30 stream.start_stream() 31 32 # wait for stream to finish (5) 33 while stream.is_active(): 34 time.sleep(0.1) 35 36 # stop stream (6) 37 stream.stop_stream() 38 stream.close() 39 wf.close() 40 41 # close PyAudio (7) 42 p.terminate()
不细说了。
下面来看一个使用pyaudio + numpy + pylab 可视化音频的代码,下面的代码打开电脑的麦克风,然后接受音频输入,再以图像的形式展示出来。
1 # -*- coding: utf-8 -*- 2 """ 3 Created on Fri May 12 10:30:00 2017 4 @author: Lyrichu 5 @description: show the sound in graphs 6 """ 7 import pyaudio 8 import numpy as np 9 import pylab 10 import time 11 12 RATE = 44100 13 CHUNK = int(RATE/20) # RATE/number of updates per second 14 15 def sound_plot(stream): 16 t1 = time.time() # time starting 17 data = np.fromstring(stream.read(CHUNK),dtype = np.int16) 18 pylab.plot(data) 19 pylab.title(i) 20 pylab.grid() 21 pylab.axis([0,len(data),-2**8,2**8]) 22 pylab.savefig("sound.png",dpi=50) 23 pylab.show(block = False) time.sleep(0.5) 24 pylab.close(\'all\') 25 print("took %.2f ms." % (time.time() - t1)*1000) 26 27 if __name__ == \'__main__\': 28 p = pyaudio.PyAudio() 29 stream = p.open(format = pyaudio.paInt16,channels = 1,rate = RATE, 30 input = True,frames_per_buffer = CHUNK) 31 for i in range(int(20*RATE/CHUNK)): 32 # for 10 seconds 33 sound_plot(stream) 34 stream.stop_stream() 35 stream.close() 36 p.terminate()
代码应该比较容易理解。得到的大概是像下面这样的图形(图4):
图 4
需要注意的是,如果不是在交互式命令下执行pylab或者matplotlib的plot命令,其plt.show()函数是一个block函数,这会导致最后的
plt.close(\'all\') 关闭所有的窗口只会在手动关闭了图像之后才会执行,所有我们无法看到连续变化的图像,为了解决这个问题,我们将plt.show()函数block参数设为False,这样show函数就不是block函数了,可以直接执行plt.close(\'all\')命令,为了不因为图像刷新太快我们看不清变化,所以使用time.sleep(0.5) 暂停0.5秒。
其实还没介绍完,还有pygame模块(python的一个做游戏的模块)以及librosa库(专业的数字信号处理库)
录制与播放案例
import numpy as np import wave from pyaudio import PyAudio,paInt16 framerate=8000 NUM_SAMPLES=2000 channels=1 sampwidth=2 TIME=2 def save_wave_file(filename,data): \'\'\'save the date to the wavfile\'\'\' wf=wave.open(filename,\'wb\') wf.setnchannels(channels) wf.setsampwidth(sampwidth) wf.setframerate(framerate) wf.writeframes(b"".join(data)) wf.close() def my_record(): pa=PyAudio() stream=pa.open(format = paInt16,channels=1, rate=framerate,input=True, frames_per_buffer=NUM_SAMPLES) my_buf=[] count=0 while count<TIME*20:#控制录音时间 string_audio_data = stream.read(NUM_SAMPLES) my_buf.append(string_audio_data) count+=1 print(\'.\') save_wave_file(\'01.wav\',my_buf) stream.close() chunk=2014 def play(): wf=wave.open(r"01.wav",\'rb\') p=PyAudio() stream=p.open(format=p.get_format_from_width(wf.getsampwidth()),channels= wf.getnchannels(),rate=wf.getframerate(),output=True) print(type(wf)) print(stream) print(type(stream)) while True: data_byte=wf.readframes(chunk) print(p.get_format_from_width(wf.getsampwidth())) data = np.fromstring(data_byte, dtype=np.int16) #将byte转换成数组 print(data.tobytes()) #将数组转换成byte if data_byte==b\'\':break stream.write(data_byte) stream.close() p.terminate() if __name__ == \'__main__\': # my_record() # print(\'Over!\') play()
from scipy.io.wavfile import read from pydub import AudioSegment rate, signal = read("01.wav") print(signal) print(rate) print(type(signal)) print(type(rate)) channel1 = signal[:] audio_segment = AudioSegment( channel1.tobytes(), frame_rate=rate, sample_width=channel1.dtype.itemsize, channels=1 ) # test that it sounds right (requires ffplay, or pyaudio): from pydub.playback import play play(audio_segment)
在MTK平台,音频/图片文件基本以数组的形式存在,一般MTK会提供工具来转换音频/图片文件为数组。
这里使用python来实现把二进制文件转为数组,目的有两个:
- 把python程序转换的二进制数组替换目前代码中已有的数组,可以实现快速验证;
- 对于比较大的二进制文件,MTK提供的工具未必支持转换,这个时候就可以用这里的python程序来转换。
# -*- coding: utf-8 -*- # It is ok at python-3.3.1rc1.msi installer condition. import os def read_data_from_binary_file(filename, list_data): f = open(filename, \'rb\') f.seek(0, 0) while True: t_byte = f.read(1) if len(t_byte) == 0: break else: list_data.append("0x%.2X" % ord(t_byte)) def write_data_to_text_file(filename, list_data): f_output = open(filename, \'w+\') f_output.write(\'__align(4) const U8 temp[] = \n\') f_output.write(\'{\n \') count = 0 lenth = len(list_data) for data in list_data: count += 1 if count != lenth: f_output.write(data+\', \') else: f_output.write(data) if count%16==0: f_output.write(\'\n \') f_output.write(\'\n};\') f_output.close() list_data = [] input_f = r\'python.gif\' output_f = r\'python.txt\' read_data_from_binary_file(input_f, list_data) write_data_to_text_file(output_f, list_data)
""" Created on Mon Jun 24 14:47:35 2019 @author: erio """ from PIL import Image,ImageGrab import cv2 import pyaudio import wave \'\'\' #录音 input_filename = "record.wav" # 麦克风采集的语音输入 input_filepath = "E:" # 输入文件的path in_pathrec = input_filepath + input_filename #通俗解释就是wav文件路径 def get_audio(filepath): CHUNK = 256 #定义数据流块 FORMAT = pyaudio.paInt16 #量化位数(音量级划分) CHANNELS = 1 # 声道数;声道数:可以是单声道或者是双声道 RATE = 8000 # 采样率;采样率:一秒内对声音信号的采集次数,常用的有8kHz, 16kHz, 32kHz, 48kHz, 11.025kHz, 22.05kHz, 44.1kHz RECORD_SECONDS = 10 #录音秒数 WAVE_OUTPUT_FILENAME = filepath #wav文件路径 p = pyaudio.PyAudio() #实例化 stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) # print("*"*10, "开始录音:请在5秒内输入语音") frames = [] #定义一个列表 for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): #循环,采样率11025 / 256 * 5 data = stream.read(CHUNK) #读取chunk个字节 保存到data中 frames.append(data) #向列表frames中添加数据data # print(frames) # print("*" * 10, "录音结束\n") stream.stop_stream() stream.close() #关闭 p.terminate() #终结 wf = wave.open(WAVE_OUTPUT_FILENAME, \'wb\') #打开wav文件创建一个音频对象wf,开始写WAV文件 wf.setnchannels(CHANNELS) #配置声道数 wf.setsampwidth(p.get_sample_size(FORMAT)) #配置量化位数 wf.setframerate(RATE) #配置采样率 wf.writeframes(b\'\'.join(frames)) #转换为二进制数据写入文件 wf.close() #关闭 get_audio(in_pathrec) \'\'\' #截屏 input_filenamescr = "screen.jpg" input_filepath = "E:" in_pathscr = input_filepath + input_filenamescr def get_screen(filepath): img = ImageGrab.grab() img.save(filepath) get_screen(in_pathscr) \'\'\' #拍照 input_filenamecam = "camera.jpg" input_filepath = "E:" in_pathcam = input_filepath + input_filenamecam def get_camera(filepath): cap=cv2.VideoCapture(0) ret,frame = cap.read() i=0; cv2.imwrite(filepath,frame) cap.release() cv2.destroyAllWindows() get_camera(in_pathcam) \'\'\' \'\'\' #录制视频 cap = cv2.VideoCapture(0)#创建一个 VideoCapture 对象 flag = 1 #设置一个标志,用来输出视频信息 num = 1 #递增,用来保存文件名 while(cap.isOpened()):#循环读取每一帧 ret_flag, Vshow = cap.read() #返回两个参数,第一个是bool是否正常打开,第二个是照片数组,如果只设置一个则变成一个tumple包含bool和图片 cv2.imshow("Capture_Test",Vshow) #窗口显示,显示名为 Capture_Test k = cv2.waitKey(1) & 0xFF #每帧数据延时 1ms,延时不能为 0,否则读取的结果会是静态帧 if k == ord(\'s\'): #若检测到按键 ‘s’,打印字符串 cv2.imwrite("D:/pycharmthings/IMF/getpics/"+ str(num) + ".jpg", Vshow) print(cap.get(3)); #得到长宽 print(cap.get(4)); print("success to save"+str(num)+".jpg") print("-------------------------") num += 1 elif k == ord(\'q\'): #若检测到按键 ‘q’,退出 break cap.release() #释放摄像头 cv2.destroyAllWindows()#删除建立的全部窗口 \'\'\'
在pygame中,有很多模块,每个模块对应着不同的功能,如果我们知道这些模块是做什么的,那么,对我们的游戏开发会起到关键性的作用。
官方文档:http://www.pygame.org/docs/
1 #pygame modules 2 3 __author__ = {\'name\' : \'Hongten\', 4 \'mail\' : \'hongtenzone@foxmail.com\', 5 \'blog\' : \'http://www.cnblogs.com/hongten\', 6 \'QQ\' : \'648719819\', 7 \'Version\' : \'1.0\'} 8 9 __modules__ =\'\'\' 10 pygame.cdrom 访问光驱 11 pygame.color 颜色 12 pygame.cursors 加载光标 13 pygame.display 访问显示设备 14 pygame.draw 绘制形状、线和点 15 pygame.event 管理事件 16 pygame.examples 不同的例子 17 pygame.font 使用字体 18 pygame.image 加载和存储图片 19 pygame.gfxdraw Anti-aliasing draw functions 20 pygame.locals 常量 21 pygame.joystick 使用游戏手柄或者 类似的东西 22 pygame.key 读取键盘按键 23 pygame.mixer 声音 24 pygame.mouse 鼠标 25 pygame.movie 播放视频 26 pygame.music 播放音频 27 pygame.overlay 访问高级视频叠加 28 pygame 就是我们在学的这个东西了…… 29 pygame.rect 管理矩形区域 30 pygame.scrap 本地剪贴板访问 31 pygame.sndarray 操作声音数据 32 pygame.sprite 操作移动图像 33 pygame.surface 管理图像和屏幕 34 pygame.surfarray 管理点阵图像数据 35 pygame.tests 测试例子 36 pygame.time 管理时间和帧信息 37 pygame.transform 缩放和移动图像 38 \'\'\' 39 40 print(__modules__)
实现功能:
运行后自动播放背景音乐,单击左键播放音效①,单击右键播放音效②,
空格键控制暂停背景音乐与恢复背景音乐,并且实现播放图标的切换。
import pygame import sys from pygame.locals import * pygame.init() pygame.mixer.init() # 初始化混音器模块 # 音效可以同时播放多个,而music只能同时播放一个 pygame.mixer.music.load(\'D:\Sublime project\MyMusicPlay\musics\侃侃 - 滴答.mp3\') # 背景音乐通常用.ogg格式 pygame.mixer.music.set_volume(0.1) # 设置音量 pygame.mixer.music.play() # 播放音乐 sound1 = pygame.mixer.Sound(\'./data/output/1_1.wav\') # 音效通常用.wav格式 # sound1.set_volume(0.5) sound2 = pygame.mixer.Sound(\'./data/output/3_1.wav\') # sound2.set_volume(0.5) bg_size = width, height = 300, 200 screen = pygame.display.set_mode(bg_size) pygame.display.set_caption(\'Music\') pause = False pause_img = pygame.image.load(r\'D:\Sublime project\MyMusicPlay\images\397483_20150129161416921330_1.jpg\').convert_alpha() unpause_img = pygame.image.load(r\'D:\Sublime project\MyMusicPlay\images\16465298_108519523001178_4421263158685990912_n-990x1237.jpg\').convert_alpha() pause_rect = pause_img.get_rect() pause_rect.left, pause_rect.top = (width - pause_rect.width) // 2, (height - pause_rect.height) // 2 clock = pygame.time.Clock() while True: for event in pygame.event.get(): if event.type == QUIT: sys.exit() if event.type == MOUSEBUTTONDOWN: if event.button == 1: # 左键 sound1.play() if event.button == 3: # 右键 sound2.play() if event.type == KEYDOWN: if event.key == K_SPACE: # 空格 pause = not pause screen.fill((255, 255, 255)) # 填充背景 if pause: screen.blit(pause_img, pause_rect) pygame.mixer.music.pause() # 暂停播放 else: screen.blit(unpause_img, pause_rect) pygame.mixer.music.unpause() # 恢复播放 pygame.display.flip() clock.tick(30) # 帧率为30