import time
import pygame
class MusicFader:
def __init__(self,fadeDuration,musicDuration):
self.fadeDuration=fadeDuration
self.musicDuration=musicDuration
self.steps=30
def fadeIn(self,musicPath=None):#淡入
if musicPath:
pygame.mixer.music.load(musicPath)#载入音频
pygame.mixer.music.set_volume(0.0)#设置初始音量
pygame.mixer.music.play()#播放音乐
stepTime=self.fadeDuration/self.steps
for i in range(self.steps+1):
volume=i/self.steps
pygame.mixer.music.set_volume(volume)
time.sleep(stepTime)
##逐步提高音量
def fadeOut(self):#淡出
currentVolume=pygame.mixer.music.get_volume()#获取现在音量
if currentVolume<=0:#如果现在音量为0,停止播放
pygame.mixer.music.stop()
return
stepTime=self.fadeDuration/self.steps
for i in range(self.steps+1):
volume=currentVolume*(1- i/self.steps)
pygame.mixer.music.set_volume(max(0,volume))
time.sleep(stepTime)
##逐步降低音量
pygame.mixer.music.stop()
if __name__ == '__main__':
pygame.mixer.init()#初始化mixer
fader=MusicFader(fadeDuration=5.0,musicDuration=83)#5秒淡入淡出,83秒音频时长
fader.fadeIn('1.mp3')#淡入
time.sleep(fader.musicDuration-fader.fadeDuration*2)#音乐主体部分(减去了淡入淡出时间)
fader.fadeOut()#淡出
如果不确定音频文件时长,可以用librosa库
pip install librosa
改进代码:
import time
import pygame
import librosa
class MusicFader:
def __init__(self,fadeDuration,musicDuration):
self.fadeDuration=fadeDuration
self.musicDuration=musicDuration
self.steps=30
def fadeIn(self,musicPath=None):#淡入
if musicPath:
pygame.mixer.music.load(musicPath)#载入音频
pygame.mixer.music.set_volume(0.0)#设置初始音量
pygame.mixer.music.play()#播放音乐
stepTime=self.fadeDuration/self.steps
for i in range(self.steps+1):
volume=i/self.steps
pygame.mixer.music.set_volume(volume)
time.sleep(stepTime)
##逐步提高音量
def fadeOut(self):#淡出
currentVolume=pygame.mixer.music.get_volume()#获取现在音量
if currentVolume<=0:#如果现在音量为0,停止播放
pygame.mixer.music.stop()
return
stepTime=self.fadeDuration/self.steps
for i in range(self.steps+1):
volume=currentVolume*(1- i/self.steps)
pygame.mixer.music.set_volume(max(0,volume))
time.sleep(stepTime)
##逐步降低音量
pygame.mixer.music.stop()
if __name__ == '__main__':
def getAudioDuration(filePath):
duration=librosa.get_duration(path=filePath)#读取元数据
return round(duration,2)#保留两位小数
fadeDuration=5.0#淡入淡出时长
audio='1.flac'
musicDuration=getAudioDuration(audio)#音频时长
pygame.mixer.init()#初始化mixer
fader=MusicFader(fadeDuration=fadeDuration,musicDuration=musicDuration)
fader.fadeIn(audio)#淡入
time.sleep(fader.musicDuration-fader.fadeDuration*2)#音乐主体部分(减去了淡入淡出时间)
fader.fadeOut()#淡出
后续我改进了一下,有了这个musicFader功能:
import time
import pygame
import librosa
import warnings
import threading
class MusicFader:
"""音频淡入淡出处理器
Copyright (c) 2026 hhcgchpspk
Attributes:
fadeDuration (float): 淡入/淡出时长(秒)
musicDuration (float): 音频总时长(秒)
steps (int): 淡入淡出的步数
"""
def __init__(self,fadeDuration,musicDuration):#淡出淡入时长;音频时长
"""初始化MusicFader
Args:
fadeDuration: 淡入/淡出时长(秒),必须大于0
musicDuration: 音频总时长(秒),必须大于0
Raises:
ValueError: 如果参数无效
"""
if fadeDuration<=0:
raise ValueError('fadeDuration必须大于0')
if musicDuration<=0:
raise ValueError('musicDuration必须大于0')
if musicDuration < fadeDuration*2:
warnings.warn(f"warning:淡入淡出总时长{fadeDuration*2}超过音乐总时长{musicDuration}")
self.fadeDuration=fadeDuration
self.musicDuration=musicDuration
self.steps=30
def fadeInOut(self,musicPath=None):
"""执行淡入淡出效果(在后台线程执行,不阻塞主线程)
Args:
musicPath: 音频文件路径
Returns:
threading.Thread: 执行播放的线程对象
"""
self._thread=threading.Thread(target=self._execute_fadeInOut,args=(musicPath,))
self._thread.daemon=True#设置为守护线程
self._thread.start()
return self._thread
def _execute_fadeInOut(self,musicPath):#淡入淡出
"""执行淡入效果
Args:
musicPath: 音频文件路径
Raises:
FileNotFoundError: 音频文件不存在
pygame.error: Pygame加载音频失败
"""
try:
pygame.mixer.init()#初始化mixer
pygame.mixer.music.load(musicPath)#载入音频
except pygame.error as e:
raise Exception(f"加载音频文件失败{e}")
except Exception as e:
raise FileNotFoundError(f"无法找到或读取文件:{musicPath}") from e
try:
pygame.mixer.music.set_volume(0.0)#设置初始音量
pygame.mixer.music.play()#播放音乐
stepTime=self.fadeDuration/self.steps
for i in range(self.steps+1):
volume=i/self.steps
pygame.mixer.music.set_volume(volume)
time.sleep(stepTime)
##逐步提高音量
time.sleep(self.musicDuration-self.fadeDuration*2)#音乐主体部分(减去了淡入淡出时间)
except Exception as e:
print(f"淡入音频时发生错误:{e}")
"""执行淡出效果
"""
try:
currentVolume=pygame.mixer.music.get_volume()#获取现在音量
if currentVolume<=0:#如果现在音量为0,停止播放
pygame.mixer.music.stop()
return
stepTime=self.fadeDuration/self.steps
for i in range(self.steps+1):
volume=currentVolume*(1- i/self.steps)
pygame.mixer.music.set_volume(max(0,volume))
time.sleep(stepTime)
##逐步降低音量
pygame.mixer.music.stop()
except Exception as e:
print(f"淡出音频时发生错误:{e}")
@staticmethod#设置为静态方法来在创建实例之前获取音频时长
def getAudioDuration(filePath):
duration=librosa.get_duration(path=filePath)#读取元数据
return round(duration,2)#保留两位小数