基于Python編寫一個MP3分割工具
最終效果圖

代碼
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()
# 創(chuàng)建界面元素
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)
# 分割時長輸入?yún)^(qū)域
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轉(zhuǎn)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', # 更寬松的參數(shù)
'-f', 'null', '-'
]
result = subprocess.run(cmd, capture_output=True, encoding='utf-8', errors='ignore')
# 解析靜音檢測結(jié)果
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)
# 構(gòu)建分割點列表
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) # 添加結(jié)束點
# 分割文件
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"分割過程中出現(xiàn)錯誤:{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"
# 顯示轉(zhuǎn)換中的消息
messagebox.showinfo("提示", "開始轉(zhuǎn)換,請稍候...")
# 執(zhí)行轉(zhuǎn)換
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已轉(zhuǎn)換為MP3:\n{output_file}")
except Exception as e:
messagebox.showerror("錯誤", f"轉(zhuǎn)換過程中出現(xiàn)錯誤:{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')
# 從輸出中提取持續(xù)時間
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"分割過程中出現(xiàn)錯誤:{str(e)}")
if __name__ == "__main__":
root = tk.Tk()
app = MP3SplitterApp(root)
root.mainloop() 說明
MP3 分割工具
這是一個使用 Python 和 FFmpeg 開發(fā)的 MP3 分割工具,支持 MP4 轉(zhuǎn) MP3、按時長分割和按歌曲自動分割等功能。
功能特點
1.MP4 轉(zhuǎn) MP3
- 支持將 MP4 視頻文件轉(zhuǎn)換為 MP3 音頻文件
- 保持高質(zhì)量音頻輸出
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 文件夾放在程序同目錄下
目錄結(jié)構(gòu)應如下:
你的程序目錄/
├── mp3_splitter.py
└── ffmpeg/
└── bin/
├── ffmpeg.exe
├── ffplay.exe
└── ffprobe.exe
使用說明
1.MP4 轉(zhuǎn) MP3:
- 點擊"選擇文件"選擇 MP4 文件
- 點擊"MP4轉(zhuǎn)MP3"按鈕
- 等待轉(zhuǎn)換完成
2.按時長分割:
- 選擇 MP3 文件
- 在輸入框中設置分割時長(默認 4:30)
- 點擊"按時長分割"按鈕
3.按歌曲分割:
- 選擇 MP3 文件
- 點擊"按歌曲分割"按鈕
- 程序會自動檢測歌曲分隔點并分割
輸出說明
1.MP4 轉(zhuǎn) MP3:
- 輸出文件將保存在原視頻同目錄下
- 文件名相同但擴展名改為 .mp3
2.按時長分割:
- 輸出文件保存在原文件同目錄下的 "_split" 文件夾中
- 文件名格式:segment_001.mp3, segment_002.mp3, ...
3.按歌曲分割:
- 輸出文件保存在原文件同目錄下的 "_songs" 文件夾中
- 文件名格式:song_001.mp3, song_002.mp3, ...
注意事項
確保已正確安裝 FFmpeg 并放置在正確位置
按歌曲分割功能的效果取決于音頻特征,可能并非所有音頻都能準確分割
建議在分割大文件前先進行測試
程序會自動跳過過短的片段以避免產(chǎn)生無效文件
開發(fā)說明
使用 Tkinter 構(gòu)建圖形界面
使用 subprocess 調(diào)用 FFmpeg 進行音頻處理
代碼采用面向?qū)ο蠓绞浇M織,主要類為 MP3SplitterApp
所有文件操作都有錯誤處理機制
到此這篇關于基于Python編寫一個MP3分割工具的文章就介紹到這了,更多相關Python分割MP3內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python基于paramiko庫操作遠程服務器的實現(xiàn)
本文主要介紹了使用Python的Paramiko庫來操作遠程服務器,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-01-01
Python控制臺輸出時刷新當前行內(nèi)容而不是輸出新行的實現(xiàn)
今天小編就為大家分享一篇Python控制臺輸出時刷新當前行內(nèi)容而不是輸出新行的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02
python中字典dict排序sorted的實現(xiàn)
本文主要介紹了python中字典dict排序sorted的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05
python學習筆記--將python源文件打包成exe文件(pyinstaller)
這篇文章主要介紹了通過將pyinstallerpython源文件打包成exe文件的方法,需要的朋友可以參考下2018-05-05
Python內(nèi)置函數(shù)之raise函數(shù)詳解與實戰(zhàn)案例
在 Python 中,raise?語句用于主動拋出異常,是錯誤處理機制的核心組成部分,以下是關于raise的詳細解析和實戰(zhàn)案例,感興趣的朋友一起看看吧2025-07-07
調(diào)用其他python腳本文件里面的類和方法過程解析
這篇文章主要介紹了調(diào)用其他python腳本文件里面的類和方法過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-11-11

