广告位联系
返回顶部
分享到

用Python编写一个MP3分割工具

python 来源:互联网 作者:佚名 发布时间:2025-02-11 20:56:11 人浏览
摘要

最终效果图 代码 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

最终效果图

代码

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

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

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 库

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

所有文件操作都有错误处理机制


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 使用Python IDLE进行Debug调试的图文介绍

    使用Python IDLE进行Debug调试的图文介绍
    1.首先以我的Python版本为例为大家讲解,我的版本是Python 3.7,版本问题对使用情况影响不大。 2.接着我们可以通过新建文件夹来输入我们的
  • 树莓派启动python的实现方法介绍

    树莓派启动python的实现方法介绍
    树莓派运行Python程序的方法: 一、RaspBerry系统设置 1、首先在开发板没有通电情况下,连接硬件,以及项目中用到传感器。比如当前项目需
  • Python给Excel写入数据的四种方法介绍
    Python 在数据处理领域应用广泛,其中与 Excel 文件的交互是常见需求之一。 本文将介绍四种使用 Python 给Excel 文件写入数据的方法,并结合生
  • 用Python编写一个MP3分割工具

    用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
  • Python如何生成requirements.txt
    在 Python 项目中,requirements.txt文件通常用于列出项目依赖的库及其版本号。这样可以方便地在其他环境中安装相同的依赖。 以下是生成req
  • 10个Python Excel自动化脚本分享介绍
    在数据处理和分析的过程中,Excel文件是我们日常工作中常见的格式。通过Python,我们可以实现对Excel文件的各种自动化操作,提高工作效率
  • 基于Python编写windows电脑用户操作记录查看器

    基于Python编写windows电脑用户操作记录查看器
    软件功能 读取系统现有的日志记录: Windows系统事件日志 最近访问的文件记录 程序安装和执行记录 刷新日志、搜索记录、删除选中记录 软
  • 怎么使用Python Dotenv库管理环境变量
    使用Python Dotenv库管理环境变量 在开发Python应用程序时,管理配置信息(如API密钥、数据库连接字符串等)是一个常见的需求。为了确保安全
  • Python wxPython创建文件复制工具的方法

    Python wxPython创建文件复制工具的方法
    在 wxPython 中实现文件复制工具:如何通过 GUI 选择源文件夹与目标文件夹 wxPython 是一个功能强大的 GUI 框架,它允许开发者通过 Python 轻松构
  • Python实现文件下载、Cookie以及重定向的方法
    本文主要介绍了如何使用 Python 的requests模块进行网络请求操作,涵盖了从文件下载、Cookie 处理到重定向与历史请求等多个方面。通过详细的
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计