基于Python编写一个MP3分割工具

最终效果图

代码

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俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/code/python/14879.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部