首页 公开文件分享 文章 随笔 聊天大厅 小工具 登录 注册 留言我们

python实现音频淡入淡出功能

作者:hhcgchpspk
要用到pygame库
pip install pygame
示例代码:
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)#保留两位小数