Python工具箱系列(五十八)

音频的操作

音乐是人类的通用语言,不分国界不分种族。而从数学角度看,音乐就是时间和频率的关系。声音的本质是波,人类听觉的原理就是波引起了耳朵鼓膜的振动。人们用不同乐器、不同力度,在一段连续时间里敲击,就组合出了时间和频率的关系。一切物体都有自己的频率,所以整个世界也可以理解为声音的盛宴。对于计算机而言,要想保存声音,就必须使用传感器来采样并且进行编码,从而能够以文件的形式保存它。但现实世界的声音是连续的,而计算机世界是离散(由0和1组成)的。想要用计算机捕捉声音,就得把连续信息转为离散的数据,这个过程就是信号的“模数转化”。处理过程中最关键的参数就是“采样率”,即每秒钟用多少份数据表达声音信号。此外每份数据大小以及声道数,与采样率一起,决定了保存后声音和原声间的差距。和图像一样,音乐也有很多种压缩算法。所谓“无损音乐”,就是确保源文件信息不丢失情况下压缩数据,常见格式如flac、ape、wav;更常见的音乐格式是mp3,是一种有损压缩格式,虽然老旧,但依旧流行。Python标准模块wave支持wav文件读写,但涉及到压缩算法时,都需要借助外部模块。其中功能最全也最流行的就是ffmpeg,它是开源视频处理软件,支持绝大多数的音视频格式编码,被广泛引用于各大视频网站和商业软件。许多软件包的底层就是ffmpeg。ffmpeg需要独立安装,下载时请参考官方文档。安装完成后输入以下命令进行确认。


# 列出基本信息
ffmpeg
# 列出所有支持的格式
ffmpeg -formats
# 安装音频处理库
pip install pyaudio
pip install pydub

对于音频文件来说,最常见的操作需要是进行格式转换。网上有各种所谓的转换器,不是功能不全,就是需要付费,或者试用版本只转换一部分音频。而程序员最大的美德就是偷懒,使用现场的工具几行代码就可以完成大部分的转换工作。

格式转换

以下代码使用pydub完成各类格式间的相互转换。

from pathlib import Path
from pydub import AudioSegment

def gensuffix(inputname, fmt):
    """
    根据现有文件名,生成目标文件名

    Args:
        inputname (string): 原始音频文件名称
        fmt (string): 转换后的音频格式名称(flac/wav...)

    Returns:
        string: 生成的目标文件名称
    """
    p = Path(inputname)
    return Path.joinpath(p.parent, f'{p.stem}.{fmt}')


def getsuffix(inputname):
    """
    根据音频名称,获得后缀

    Args:
        inputname (string): 原始音频文件名称

    Returns:
        string: 后缀
    """
    p = Path(inputname)
    return p.suffix


def transaudio(audioname, fmt):
    """
    对音频文件进行格式转换

    Args:
        audioname (string): 要转换的音频文件
        fmt (string): 目标格式
    """
    suffix = getsuffix(audioname)
    if suffix == '.mp3':
        print(f'convert {audioname} to {fmt} file')
        song = AudioSegment.from_mp3(audioname)
        song.export(gensuffix(audioname, fmt), format=fmt)

    if suffix == '.wav':
        print(f'convert {audioname} to {fmt} file')
        song = AudioSegment.from_wav(audioname)
        song.export(gensuffix(audioname, fmt), format=fmt)

    if suffix == '.ogg':
        print(f'convert {audioname} to {fmt} file')
        song = AudioSegment.from_ogg(audioname)
        song.export(gensuffix(audioname, fmt), format=fmt)

    if suffix in ['.flac', '.m4a', '.ape']:
        print(f'convert {audioname} to {fmt} file')
        song = AudioSegment.from_file(audioname)
        song.export(gensuffix(audioname, fmt), format=fmt)


def test_convert():
    sourcefilelist = list()
    sourcefilelist.append(r'D:\sync\relax-r\music\MV\王菲\02 王菲 - 下雨天.flac')
    sourcefilelist.append(
        'D:\sync\relax-r\music\高级小提琴\高品质\雨果唱片.-.[花儿与少年].专辑.(APE).ape')
    sourcefilelist.append('D:\sync\relax-r\music\精品\乘客-王菲….m4a')
    sourcefilelist.append('D:\sync\relax-r\music\将爱情进行到底电视原声\06. CD音轨06.wav')
    sourcefilelist.append('C:\Users\tianbin\Music\XiamiMusic\VipSongsDownload\SoftGuitar.ogg')

    for wavefile in sourcefilelist:
        transaudio(wavefile, "mp3")
        transaudio(wavefile, "ogg")

对于以上代码有如下说明:

  • flac/ap3/wav都是无损音质,通过transaudio函数转换成为mp3后音质会受损,但mp3的神奇之处就在于人类听起来差别不大,但体积小易于传播。
  • Ogg全称是OGGVobis(oggVorbis)是一种音频压缩格式,类似于MP3等的音乐格式。Ogg是完全免费、开放和没有专利限制的。OggVorbis文件的扩展名是".ogg"。Ogg文件格式可以不断地进行大小和音质的改良,而不影响旧有的编码器或播放器。
  • m4a是MPEG-4 音频标准的文件的扩展名。在MPEG4标准中提到,普通的MPEG4文件扩展名是mp4。自从Apple开始在它的iTunes以及 iPod中使用m4a以区别MPEG4的视频和音频文件以来,m4a这个扩展名变得流行了。华为手机的录音文件也是m4a格式,所以有必要进行转换。

 

posted @ 2024-12-23 14:55  西安衍舆航天  阅读(7)  评论(0编辑  收藏  举报