Python工具箱系列(六十)

从视频中提取音频

有时只有MTV文件,但是很想做为MP3收藏,就需要将音频从视频中提取出来。pydub库仍然是当仁不让的选择。

import glob
from pathlib import Path

import eyed3
import mutagen
from pychorus import find_and_output_chorus
from pydub import AudioSegment
from pydub.utils import mediainfo
from tinytag import TinyTag


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 pydubinfo(mp3filename):
    """
    使用pydub库来获得mp3文件的标签信息

    Args:
        mp3filename (string): mp3文件名
    """
    song = mediainfo(mp3filename)
    print(song['TAG'])

def mutageninfo(mp3filename):
    """
    使用mutagen库来获得mp3文件的标签信息

    Args:
        mp3filename (string): mp3文件名
    """
    inf = mutagen.File(mp3filename)
    # 列出所有的标签
    for i in inf.tags:
        print(i)

    # 将图片保存为和歌曲同名,jpg格式的图片
    artwork = inf.tags['APIC:'].data  # 获取歌曲图片
    title = inf.tags["TIT2"].text[0]  # 获取歌曲名
    with open(title+'.jpg', 'wb') as img:
        img.write(artwork)

def tinytaginfo(mp3filename):
    """
    使用tinytag库获得mp3文件的标签信息

    Args:
        mp3filename (string): mp3文件名
    """
    tag = TinyTag.get(mp3filename)
    print('This track is by %s.' % tag.artist)
    print('It is %f seconds long.' % tag.duration)


def eyed3info(mp3filename):
    """
    使用eyed3库获得mp3文件的标签信息,并且写入自定义的值

    Args:
        mp3filename (string): mp3文件名
    """
    audiofile = eyed3.load(mp3filename)
    print(audiofile.tag.title)
    audiofile.tag.title = '疯狂的真实的常常的'
    audiofile.tag.save()


def takefrommovie(moviefilename, fmt):
    """
    将视频文件转成MP3文件,从而获得音频

    Args:
        moviefilename (string): 视频文件名称
        fmt (string): 要转成的格式名称
    """
    suffix = getsuffix(moviefilename)
    
    # 给MP3文件打上TAGS
    tags = {'artist': 'tianbinraindrop',
            'album': 'yello', 'comments': 'just test!'}
    
    # 给出封面
    coverfile = r'd:\test\12.jpg'
    
    if suffix in ['.mp4', '.flv']:
        print(f'convert {moviefilename} to {fmt} file')
        song = AudioSegment.from_file(moviefilename)
        song.export(gensuffix(moviefilename, fmt),
                    format=fmt, tags=tags, cover=coverfile)

def chorus(mp3filename):
    """
    从音频文件中提取出音乐的高潮部分

    Args:
        mp3filename (string): mp3文件
    """
    outputfile = gensuffix(mp3filename, 'wav')
    chorus_start_sec = find_and_output_chorus(mp3filename,outputfile)
    print(chorus_start_sec)
    
def test_takemp3():
    takefrommovie(r'd:\test\Truly Madly Deeply 中英字幕版-Savage Garden-HD.flv', 'mp3')

def test_tags():
    targetmp3 = r'D:\test\mp3\Delicate.mp3'
    mutageninfo(targetmp3)
    tinytaginfo(targetmp3)
    eyed3info(targetmp3)
    pydubinfo(targetmp3)

def test_chorus():
    files = glob.iglob(r'd:\test\mp3\*.mp3')
    for file in files:
        print(file)
        chorus(file)

在上述代码中,设置了MP3文件的封面属性。今后在播放器中就可以如图所示显示出来。这个功能是通用的,各种主流的播放器都能够做到。

python-audio-001.png

在上述代码中,使用tags这一字典生成了部分MP3文件属性,MP3文件的标签能够方便后续音乐文件的整理。使用vlc player可以看到属性如下图所示,与我们在代码中写的一致。

python-audio-002.png

很多短视频均需要使用某个曲中的最高潮部分做为BGM(Background music)。音乐高潮最普遍也是最简单的特征就是:多次循环。按这样的思路,可以从整首歌中,找出重复次数最多、间隔最长的片段。但真正做的时候,需要对音频信号处理有一定基础。在上述代码中,chorus函数直接调用pychorus库,就能够对MP3音乐文件进行高潮部分的分析,当然这个分析没有人类分析的准确。使用它的好处在于启发。

此外,上述代码提供了四种获得MP3标签信息的函数:

  • pydubinfo,使用pydub库进行获取,内容相对较少。
  • mutageninfo,使用mutagen库进行获取,内容丰富很多,代码中示范了如何提取封面信息,并且保存成图片。
  • tinytaginfo,使用tinytag库进行获取,相对功能强大许多
  • eyed3info,使用eyed3库进行获取,不仅可查,而且可以直接操作修改。

最后再整理一下安装过程:

pip install pyaudio
pip install pydub
pip install mutagen
pip install tinytag
pip install eyed3
pip install pychorus

代码中列出的MP3/FLV文件可以随便替换,不必纠结。

posted @ 2025-08-15 16:22  西安衍舆航天  阅读(5)  评论(0)    收藏  举报