最终效果图
代码
import tkinter as tk from tkinter import filedialog, messagebox, ttk import os import subprocess class mp3splitterapp: def __init__(self, root): self.root = root self.root.title("mp3 分割工具") self.root.geometry("600x400") # 文件路径变量 self.file_path = tk.stringvar() # 创建界面元素 self.create_widgets() # 预设分割时长为 4:30 self.minutes_entry.insert(0, "4") self.seconds_entry.insert(0, "30") # 存储分割点的列表 self.split_points = [] def create_widgets(self): # 文件选择框 file_frame = ttk.frame(self.root) file_frame.pack(pady=10, padx=10, fill=tk.x) ttk.label(file_frame, text="选择文件:").pack(side=tk.left) ttk.entry(file_frame, textvariable=self.file_path, width=50).pack(side=tk.left, padx=5) ttk.button(file_frame, text="选择文件", command=self.select_file).pack(side=tk.left) # 分割时长输入区域 split_frame = ttk.frame(self.root) split_frame.pack(pady=10, padx=10, fill=tk.both) ttk.label(split_frame, text="设置分割时长(格式:分:秒):").pack() input_frame = ttk.frame(split_frame) input_frame.pack(pady=5) self.minutes_entry = ttk.entry(input_frame, width=5) self.minutes_entry.pack(side=tk.left) ttk.label(input_frame, text=":").pack(side=tk.left) self.seconds_entry = ttk.entry(input_frame, width=5) self.seconds_entry.pack(side=tk.left) # 控制按钮 button_frame = ttk.frame(self.root) button_frame.pack(pady=10, padx=10) ttk.button(button_frame, text="mp4转mp3", command=self.convert_mp4_to_mp3).pack(side=tk.left, padx=5) ttk.button(button_frame, text="按时长分割", command=self.split_mp3).pack(side=tk.left, padx=5) ttk.button(button_frame, text="按歌曲分割", command=self.detect_songs).pack(side=tk.left, padx=5) def select_file(self): file_path = filedialog.askopenfilename(filetypes=[("视频/音频文件", "*.mp4 *.mp3")]) if file_path: self.file_path.set(file_path) def detect_songs(self): if not self.file_path.get(): messagebox.showerror("错误", "请选择mp3文件") return try: # 检查ffmpeg路径 possible_paths = [ r"ffmpeg\bin\ffmpeg.exe", r".\ffmpeg\bin\ffmpeg.exe", r"c:\ffmpeg\bin\ffmpeg.exe", "ffmpeg" ] ffmpeg_path = none for path in possible_paths: if os.path.exists(path): ffmpeg_path = path break if ffmpeg_path is none: messagebox.showerror("错误", "找不到ffmpeg,请确保已正确安装ffmpeg") return input_file = self.file_path.get() # 使用ffmpeg的silencedetect过滤器检测静音部分 cmd = [ ffmpeg_path, '-i', input_file, '-af', 'silencedetect=noise=-35db:d=1', # 更宽松的参数 '-f', 'null', '-' ] result = subprocess.run(cmd, capture_output=true, encoding='utf-8', errors='ignore') # 解析静音检测结果 silence_starts = [] silence_ends = [] if result.stderr: # 确保有输出 for line in result.stderr.split('\n'): if line: # 确保行不为空 if 'silence_start:' in line: try: parts = line.split('silence_start:') if len(parts) > 1: time = float(parts[1].strip().split()[0]) silence_starts.append(time) except: continue elif 'silence_end:' in line: try: parts = line.split('silence_end:') if len(parts) > 1: time = float(parts[1].strip().split()[0]) silence_ends.append(time) except: continue # 使用检测到的静音点进行分割 if silence_starts and silence_ends: output_dir = os.path.splitext(input_file)[0] + "_songs" os.makedirs(output_dir, exist_ok=true) # 获取总时长 probe = subprocess.run([ ffmpeg_path, '-i', input_file ], capture_output=true, encoding='utf-8', errors='ignore') duration = none if probe.stderr: for line in probe.stderr.split('\n'): if "duration:" in line: try: time_str = line.split("duration:")[1].split(",")[0].strip() h, m, s = map(float, time_str.split(":")) duration = h * 3600 + m * 60 + s break except: continue if duration is none: duration = max(silence_ends[-1] if silence_ends else 0, 3600) # 构建分割点列表 split_points = [0] # 添加开始点 for start, end in zip(silence_starts, silence_ends): # 使用静音段的中点作为分割点 split_point = (start + end) / 2 # 只有当两个分割点间隔超过20秒时才考虑这是一首新歌 if split_point - split_points[-1] > 20: split_points.append(split_point) split_points.append(duration) # 添加结束点 # 分割文件 for i in range(len(split_points) - 1): start_time = split_points[i] end_time = split_points[i + 1] if end_time - start_time < 20: # 如果片段小于20秒则跳过 continue output_path = os.path.join(output_dir, f"song_{i+1:03d}.mp3") subprocess.run([ ffmpeg_path, '-i', input_file, '-ss', str(start_time), '-t', str(end_time - start_time), '-acodec', 'copy', '-y', output_path ], capture_output=true) messagebox.showinfo("成功", f"文件已按歌曲分割完成,保存在:{output_dir}") else: messagebox.showerror("错误", "未能检测到有效的歌曲分隔点") except exception as e: messagebox.showerror("错误", f"分割过程中出现错误:{str(e)}") def convert_mp4_to_mp3(self): if not self.file_path.get(): messagebox.showerror("错误", "请选择mp4文件") return if not self.file_path.get().lower().endswith('.mp4'): messagebox.showerror("错误", "请选择mp4文件") return try: # 检查ffmpeg路径 possible_paths = [ r"ffmpeg\bin\ffmpeg.exe", r".\ffmpeg\bin\ffmpeg.exe", r"c:\ffmpeg\bin\ffmpeg.exe", "ffmpeg" ] ffmpeg_path = none for path in possible_paths: if os.path.exists(path): ffmpeg_path = path break if ffmpeg_path is none: messagebox.showerror("错误", "找不到ffmpeg,请确保已正确安装ffmpeg") return input_file = self.file_path.get() output_file = os.path.splitext(input_file)[0] + ".mp3" # 显示转换中的消息 messagebox.showinfo("提示", "开始转换,请稍候...") # 执行转换 subprocess.run([ ffmpeg_path, '-i', input_file, '-vn', '-acodec', 'libmp3lame', '-q:a', '2', '-y', output_file ], check=true) # 更新文件路径为新生成的mp3文件 self.file_path.set(output_file) messagebox.showinfo("成功", f"mp4已转换为mp3:\n{output_file}") except exception as e: messagebox.showerror("错误", f"转换过程中出现错误:{str(e)}") def split_mp3(self): if not self.file_path.get(): messagebox.showerror("错误", "请选择mp3文件") return try: # 获取用户输入的分割时长 try: minutes = int(self.minutes_entry.get() or "0") seconds = int(self.seconds_entry.get() or "0") if minutes < 0 or seconds < 0 or seconds >= 60: raise valueerror segment_duration = minutes * 60 + seconds if segment_duration <= 0: raise valueerror except valueerror: messagebox.showerror("错误", "请输入有效的分割时长") return # 检查ffmpeg路径 possible_paths = [ r"ffmpeg\bin\ffmpeg.exe", r".\ffmpeg\bin\ffmpeg.exe", r"c:\ffmpeg\bin\ffmpeg.exe", "ffmpeg" ] ffmpeg_path = none for path in possible_paths: if os.path.exists(path): ffmpeg_path = path break if ffmpeg_path is none: messagebox.showerror("错误", "找不到ffmpeg,请确保已正确安装ffmpeg") return input_file = self.file_path.get() output_dir = os.path.splitext(input_file)[0] + "_split" os.makedirs(output_dir, exist_ok=true) # 获取音频总时长 result = subprocess.run([ffmpeg_path, '-i', input_file], capture_output=true, encoding='utf-8', errors='ignore') # 从输出中提取持续时间 duration = none for line in result.stderr.split('\n'): if "duration:" in line: try: time_str = line.split("duration:")[1].split(",")[0].strip() h, m, s = map(float, time_str.split(":")) duration = h * 3600 + m * 60 + s break except: continue if duration is none: duration = 3600 messagebox.showwarning("警告", "无法获取音频时长,将使用默认时长进行分割") # 计算分割点 num_segments = int(duration // segment_duration) + 1 # 分割文件 for i in range(num_segments): start_time = i * segment_duration end_time = min((i + 1) * segment_duration, duration) if end_time - start_time < 1: # 如果片段小于1秒则跳过 continue output_path = os.path.join(output_dir, f"segment_{i+1:03d}.mp3") subprocess.run([ ffmpeg_path, '-i', input_file, '-ss', str(start_time), '-t', str(end_time - start_time), '-acodec', 'copy', '-y', output_path ], capture_output=true) messagebox.showinfo("成功", f"文件已分割完成,保存在:{output_dir}\n共分割成 {num_segments} 个文件") except exception as e: messagebox.showerror("错误", f"分割过程中出现错误:{str(e)}") if __name__ == "__main__": root = tk.tk() app = mp3splitterapp(root) root.mainloop()
说明
mp3 分割工具
这是一个使用 python 和 ffmpeg 开发的 mp3 分割工具,支持 mp4 转 mp3、按时长分割和按歌曲自动分割等功能。
功能特点
1.mp4 转 mp3
- 支持将 mp4 视频文件转换为 mp3 音频文件
- 保持高质量音频输出
2.按时长分割
- 默认预设 4:30 的分割时长
- 可自定义分割时长(分:秒)
- 自动跳过小于 1 秒的片段
3.按歌曲分割
- 自动检测音频中的静音部分
- 智能判断歌曲分隔点
- 自动跳过过短的片段(小于 20 秒)
安装要求
python 3.x
ffmpeg
必需的 python 库
pip install tkinter
ffmpeg 安装
下载 ffmpeg:
访问:releases · btbn/ffmpeg-builds
下载 "ffmpeg-master-latest-win64-gpl-shared.zip"
安装步骤:
- 解压下载的 zip 文件
- 将解压出的文件夹重命名为 "ffmpeg"
- 将 ffmpeg 文件夹放在程序同目录下
目录结构应如下:
你的程序目录/
├── mp3_splitter.py
└── ffmpeg/
└── bin/
├── ffmpeg.exe
├── ffplay.exe
└── ffprobe.exe
使用说明
1.mp4 转 mp3:
- 点击"选择文件"选择 mp4 文件
- 点击"mp4转mp3"按钮
- 等待转换完成
2.按时长分割:
- 选择 mp3 文件
- 在输入框中设置分割时长(默认 4:30)
- 点击"按时长分割"按钮
3.按歌曲分割:
- 选择 mp3 文件
- 点击"按歌曲分割"按钮
- 程序会自动检测歌曲分隔点并分割
输出说明
1.mp4 转 mp3:
- 输出文件将保存在原视频同目录下
- 文件名相同但扩展名改为 .mp3
2.按时长分割:
- 输出文件保存在原文件同目录下的 "_split" 文件夹中
- 文件名格式:segment_001.mp3, segment_002.mp3, ...
3.按歌曲分割:
- 输出文件保存在原文件同目录下的 "_songs" 文件夹中
- 文件名格式:song_001.mp3, song_002.mp3, ...
注意事项
确保已正确安装 ffmpeg 并放置在正确位置
按歌曲分割功能的效果取决于音频特征,可能并非所有音频都能准确分割
建议在分割大文件前先进行测试
程序会自动跳过过短的片段以避免产生无效文件
开发说明
使用 tkinter 构建图形界面
使用 subprocess 调用 ffmpeg 进行音频处理
代码采用面向对象方式组织,主要类为 mp3splitterapp
所有文件操作都有错误处理机制
到此这篇关于基于python编写一个mp3分割工具的文章就介绍到这了,更多相关python分割mp3内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论