直接上效果图
可以使用python的pysimplegui-exemaker打包一个exe步伐
把FLAC,WAV,OGG等音频转MP3音频
在音频处置惩罚领域,我们经常需要对音频文件进行各种操纵,例如剪辑、合并、转码等。而 Python 中的 AudioSegment 是一个强大的库,可以帮助我们处置惩罚各种音频格式的文件。
1.支持的格式
- AudioSegment 是 pydub 库的一部分,通过使用 ffmpeg 库来实现对音频文件格式的支持。因此,AudioSegment 实际上支持所有 ffmpeg 支持的音频格式。
2.下面是一些常见的音频格式:
- WAV (Waveform Audio File Format,无损音频文件格式)
- MP3 (MPEG Audio Layer 3,有损音频文件格式)
- FLAC (Free Lossless Audio Codec,无损音频文件格式)
- OGG (Ogg Vorbis,开放音频文件格式)
- AAC (Advanced Audio Coding,高级音频编码格式)
当然,除了上述格式外,AudioSegment 还支持其他许多音频格式,例如 AMR、WMA、AIFF 等。具体介绍及使用百度自了解
上代码:python文件为audioConvert.py
- """
- 把FLAC,WAV,OGG等音频转MP3音频
- AudioSegment 支持哪个格式
- 在音频处理领域,我们经常需要对音频文件进行各种操作,例如剪辑、合并、转码等。而 Python 中的 AudioSegment 是一个强大的库,可以帮助我们处理各种音频格式的文件。
- 支持的格式
- AudioSegment 是 pydub 库的一部分,通过使用 ffmpeg 库来实现对音频文件格式的支持。因此,AudioSegment 实际上支持所有 ffmpeg 支持的音频格式。下面是一些常见的音频格式:
- WAV (Waveform Audio File Format,无损音频文件格式)
- MP3 (MPEG Audio Layer 3,有损音频文件格式)
- FLAC (Free Lossless Audio Codec,无损音频文件格式)
- OGG (Ogg Vorbis,开放音频文件格式)
- AAC (Advanced Audio Coding,高级音频编码格式)
- 当然,除了上述格式外,AudioSegment 还支持其他许多音频格式,例如 AMR、WMA、AIFF 等。
- """
- import os
- import re
- from pydub import AudioSegment
- from pydub.utils import mediainfo
- from queue import Queue
- import threading
- class AudioConverterMp3:
- """
- :param source: 源文件夹
- :param target: 输出文件夹
- :param source_type: 源格式
- :param target_type: 输出格式
- :param printlog: 输出日志对象方法 没有传值用默认print否则printlog(message)
- """
- def __init__(self, source='F:\夸克网盘\Flac音乐+歌词', target='F:\夸克网盘\MP3音乐', source_type='flac', target_type='mp3', printlog=print):
- self.source = source # 源文件夹
- self.target = target # 输出文件夹
- self.source_type = source_type # 源格式
- self.target_type = target_type # 输出格式
- self.printlog = printlog # 输出日志对象方法 没有传值用默认print否则printlog(message)
- self.count = 0 # 待转化音频文件总数
- self.queue = Queue() # 队列,为什么要用队列?因为如果不用队列,多线程处理音频文件时,会出现文件读写冲突,导致程序崩溃
- self.get_audio_files() # 获取源文件夹下所有flac音频文件
- def get_audio_files(self):
- """
- 获取源文件夹下所有音频文件,加入队列
- :return: 文件列表
- """
- for index, file in enumerate([song for song in os.listdir(self.source) if song.endswith('.' + self.source_type)]):
- self.queue.put([index, file])
- self.count += 1
- self.printlog(f'本次待转化音频文件总数:{self.count}个,开始处理...')
- def audio_to_mp3(self, index, source_file):
- """
- 把音频转MP3音频
- :param index: 序号
- :param source_file: 源文件
- :return: None
- """
- try:
- song = AudioSegment.from_file(os.path.join(self.source, source_file), self.source_type) # 读取音频文件
- target_file = source_file[:-len(self.source_type)] + self.target_type # 输出文件
- tags = mediainfo(os.path.join(self.source, source_file)).get('TAG') # 输出音频信息(元数据)
- song.export(os.path.join(self.target, target_file), format=self.target_type, bitrate='192k', tags=tags) # 保存音频为mp3格式
- self.printlog(f"{threading.current_thread().name} 提供 {source_file} 转换:{self.source_type} -> {self.target_type} 完成") # 输出结果
- except Exception as e:
- error_dir = os.path.join(os.path.dirname(self.source), "error-transfer-song")
- if not os.path.exists(error_dir):
- os.makedirs(error_dir)
- source_file = re.findall(r"from '(.+?)':", str(e))[0]
- os.rename(os.path.join(self.source, source_file), os.path.join(error_dir, source_file)) # 发生错误时,将源文件移动到error-transfer-song文件夹下
- self.printlog(f'\n\n{source_file} 转码失败,已移动到 {error_dir} 文件夹下\n\n发生错误代码:{e}\n\n')
- def multiple_thread(self):
- """
- 多线程处理音频文件
- 多线程处理音频文件,使用队列,队列中存放音频文件路径,每个线程从队列中取出一个音频文件进行处理。
- 队列的使用,可以保证多个线程同时处理音频文件,避免文件读写冲突。
- :return: None
- """
- while not self.queue.empty():
- index, file = self.queue.get()
- if os.path.exists(os.path.join(self.target, file[:-len(self.source_type)] + self.target_type)):
- self.printlog(f'{index + 1}/{self.count}: {file} 已转换,跳过...')
- continue
- self.audio_to_mp3(index, file)
- # 运行程序
- def run(self):
- """
- 运行程序
- 多线程处理,根据CPU核心数启动线程数,可以充分利用CPU资源,提高处理速度。
- :return: None
- """
- tasks = []
- for i in range(os.cpu_count()):
- t = threading.Thread(target=self.multiple_thread, name=f'线程-{i}')
- t.start()
- tasks.append(t)
- for t in tasks:
- t.join()
- self.printlog('\n全部文件处理完成!\n')
- # 程序测试用入口,,当文件直接运行时,即非模块导入调用,执行以下代码
- if __name__ == '__main__':
- audio_to_mp3 = AudioConverterMp3()
- audio_to_mp3.run()
复制代码 python图形界面教程(tkinter)
主要用到 tkinder 中Label标签显示文体,Radiobuttio 单选按钮选择源文件格式,tkinter.filedialog.askdirectory 选择文件目次,滚动文本ScrolledText等具体介绍及使用百度自了解。
在Python的Tkinter GUI中动态输出日志时,如果碰到卡顿题目,通常是因为主事件循环被过度占用,导致界面无法实时更新。为了办理这个题目,可以使用多线程或者异步编程的方式,让日志输出在另一个线程中执行,从而不影响主事件循环的运行。
上代码:python文件为main.py(主文件)
- # python图形界面:
- from threading import Thread
- from tkinter import *
- from tkinter import messagebox
- from tkinter.filedialog import askdirectory
- from tkinter.scrolledtext import ScrolledText
- from audioConvert import AudioConverterMp3
- class AudioToMP3UI(object):
- """
- 把音频转MP3格式音频
- 1. 选择源音频文件路径和目标音频文件路径
- 2. 点击“开 始 转 码”按钮,开始转码
- 3. 转码完成后,会弹出提示框,提示转码完成
- 4. 转码完成后,可以到目标音频文件路径下查看转码后的音频文件
- 5. 日志信息会实时显示在滚动文本框中
- """
- def __init__(self):
- self.et_source = None # 源文件路径输入框
- self.et_target = None # 目标文件路径输入框
- self.scrolltext = None # 滚动文本框
- self.thread = None # 线程对象
- self.root = Tk() # 创建GUI窗口
- self.root.title("把音频转MP3格式音频") # 设置窗口标题
- width = 600
- height = 500
- x = self.root.winfo_screenwidth() // 2 - width // 2 # 计算窗口宽度居中位置
- y = self.root.winfo_screenheight() // 2 - height // 2 # 计算窗口高度居中位置
- self.root.geometry(f"{width}x{height}+{x}+{y}") # 设置窗口大小和位置
- self.source_type = StringVar() # 源文件格式选择变量
- self.frame_type = Frame(self.root) # 创建Frame容器
- self.frame_type.pack() # 放置Frame容器
- self.frame_path = Frame(self.root) # 创建Frame容器
- self.frame_path.pack() # 放置Frame容器
- self.frame_info = Frame(self.root) # 创建Frame容器
- self.frame_info.pack() # 放置Frame容器 AMR、WMA、AIFF
- # 选择源文件格式
- def create_source_type_ui(self):
- lb_type = Label(self.frame_type, text="源文件格式:") # 创建标签
- lb_type.grid(column=0, row=0, padx=8, pady=4) # 放置标签
- rb_type1 = Radiobutton(self.frame_type, text="wav", variable=self.source_type, value="wav") # 创建单选按钮
- rb_type1.grid(column=1, row=0, padx=3) # 放置标签
- rb_type2 = Radiobutton(self.frame_type, text="mp3", variable=self.source_type, value="mp3") # 创建单选按钮
- rb_type2.grid(column=2, row=0, padx=3) # 放置标签
- rb_type3 = Radiobutton(self.frame_type, text="flac", variable=self.source_type, value="flac") # 创建单选按钮
- rb_type3.grid(column=3, row=0, padx=3) # 放置标签
- rb_type4 = Radiobutton(self.frame_type, text="ogg", variable=self.source_type, value="ogg") # 创建单选按钮
- rb_type4.grid(column=4, row=0, padx=3) # 放置标签
- rb_type5 = Radiobutton(self.frame_type, text="aac", variable=self.source_type, value="aac") # 创建单选按钮
- rb_type5.grid(column=5, row=0, padx=3) # 放置标签
- rb_type6 = Radiobutton(self.frame_type, text="amr", variable=self.source_type, value="amr") # 创建单选按钮
- rb_type6.grid(column=6, row=0, padx=3) # 放置标签
- rb_type7 = Radiobutton(self.frame_type, text="wma", variable=self.source_type, value="wma") # 创建单选按钮
- rb_type7.grid(column=7, row=0, padx=3) # 放置标签
- rb_type8 = Radiobutton(self.frame_type, text="aiff", variable=self.source_type, value="aiff") # 创建单选按钮
- rb_type8.grid(column=8, row=0, padx=3) # 放置标签
- self.source_type.set("flac") # 设置默认选择flac格式
- def select_type_command(self):
- print("选择源文件格式:" + self.source_type.get()) # 打印选择的源文件格式
- return self.source_type.get()
- # 设置源文件路径和目标文件路径输入框和打开文件目录按钮
- def create_source_target_dir_ui(self):
- # 设置源文件路径输入框和打开文件目录按钮
- lb_source = Label(self.frame_path, text="源音频文件路径:") # 创建标签
- lb_source.grid(column=0, row=0, pady=20) # 放置标签
- self.et_source = Entry(self.frame_path, width=60, bd=5) # 创建源目录输入框
- self.et_source.grid(column=1, row=0, padx=5) # 放置输入框
- btn_source = Button(self.frame_path, text="点选", command=self.select_source_dir_command) # 创建选择源目录按钮
- btn_source.grid(column=2, row=0) # 放置按钮
- # 设置目标文件路径输入框和打开文件目录按钮
- lb_target = Label(self.frame_path, text="导出音频文件路径:") # 创建标签
- lb_target.grid(column=0, row=1, pady=0) # 放置标签
- self.et_target = Entry(self.frame_path, width=60, bd=5) # 创建目标目录输入框
- self.et_target.grid(column=1, row=1, padx=5) # 放置输入框
- btn_target = Button(self.frame_path, text="点选", command=self.select_target_dir_command) # 创建选择目标目录按钮
- btn_target.grid(column=2, row=1) # 放置按钮
- btn_start = Button(self.frame_path, text="开 始 转 码", command=self.convert_format) # 创建开始转码按钮
- btn_start.grid(column=0, row=2, ipadx=80, padx=45, pady=15, columnspan=3)
- # 设置选择源文件目录按钮事件
- def select_source_dir_command(self):
- dirname = askdirectory(title='请选择->源音频文件路径') # 弹出选择源目录对话框
- if dirname != '':
- self.et_source.delete(0, END) # 清空输入框内容
- self.et_source.insert(0, dirname) # 显示选择的目录
- else:
- messagebox.showinfo("提醒", "您没有选择任何目录!") # 提示用户没有选择目录
- # 设置选择目标文件目录按钮事件
- def select_target_dir_command(self):
- dirname = askdirectory(title='请选择->导出音频文件路径') # 弹出选择目标目录对话框
- if dirname != '':
- self.et_target.delete(0, END) # 清空输入框内容
- self.et_target.insert(0, dirname) # 显示选择的目录
- else:
- messagebox.showinfo("提醒", "您没有选择任何目录!") # 提示用户没有选择目录
- # 设置滚动文本框
- def create_scrolltext_ui(self):
- self.scrolltext = ScrolledText(self.frame_info, width=78, height=21, padx=10, pady=8) # 创建滚动文本框
- self.scrolltext.pack() # 放置滚动文本框
- self.scrolltext.insert(END, "1. 选择源音频文件路径和目标音频文件路径\n"
- "2. 点击“开 始 转 码”按钮,开始转码\n"
- "3. 转码完成后,会弹出提示框,提示转码完成\n"
- "4. 转码完成后,可以到目标音频文件路径下查看转码后的音频文件\n") # 设置提示信息
- # 设置开始转码按钮事件
- def convert_format(self):
- source_path = self.et_source.get() # 获取源文件路径
- target_path = self.et_target.get() # 获取目标文件路径
- if source_path == '' or target_path == '':
- messagebox.showinfo("提醒", "请选择源文件路径和目标文件路径!") # 提示用户没有选择目录
- else:
- self.scrolltext.insert(END, f'源文件路径:《{source_path}》 \n') # 显示源文件路径
- self.scrolltext.insert(END, f'目标文件路径:《{target_path}》 \n') # 显示目标文件路径
- self.scrolltext.insert(END, "开始转码!\n") # 显示开始转码信息
- self.root.update() # 更新UI显示
- # 转码代码
- audio_to_mp3 = AudioConverterMp3(source_path, target_path, self.source_type.get(), printlog=self.printlog) # 创建AudioConverterMp3对象
- # 在Python的Tkinter GUI中动态输出日志时,如果遇到卡顿问题,通常是因为主事件循环被过度占用,导致界面无法及时更新。
- # 为了解决这个问题,可以使用多线程或者异步编程的方式,让日志输出在另一个线程中执行,从而不影响主事件循环的运行。
- self.thread = Thread(target=audio_to_mp3.run) # 创建线程对象
- self.thread.start() # 启动线程
- # 输出日志信息,用于显示执行过程打印的日志信息
- def printlog(self, info):
- self.scrolltext.insert(END, info + '\n') # 显示日志信息
- self.scrolltext.see(END) # 滚动到最后一行
- self.root.update() # 更新UI显示
- # 运行GUI
- def run(self):
- self.create_source_type_ui() # 创建源文件格式选择按钮
- self.create_source_target_dir_ui() # 创建源文件路径输入框和打开文件目录按钮
- self.create_scrolltext_ui() # 创建滚动文本框
- self.root.mainloop() # 运行GUI
- if __name__ == '__main__':
- trans_mp3 = AudioToMP3UI()
- trans_mp3.run()
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |