最终效果图
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 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 "ffmpegbinffmpeg.exe" , r ".ffmpegbinffmpeg.exe" , r "C:ffmpegbinffmpeg.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 = 60 : raise ValueError segment_duration = minutes * 60 + seconds if segment_duration |
说明
MP3 分割工具
这是一个使用 Python 和 FFmpeg 开发的 MP3 分割工具,支持 MP4 转 MP3、按时长分割和按歌曲自动分割等功能。
功能特点
1.MP4 转 MP3
- 支持将 MP4 视频文件转换为 MP3 音频文件
- 保持高质量音频输出
2.按时长分割
- 默认预设 4:30 的分割时长
- 可自定义分割时长(分:秒)
- 自动跳过小于 1 秒的片段
3.按歌曲分割
- 自动检测音频中的静音部分
- 智能判断歌曲分隔点
- 自动跳过过短的片段(小于 20 秒)
安装要求
Python 3.x
FFmpeg
必需的 Python 库
1 | 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内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!