Learn how to create QuickAudioCutter, a Windows desktop app for trimming audio files with drag & drop, live preview, and batch processing using Python, Tkinter, and FFmpeg.
We’ll break it down step by step so beginners can follow along.
Step 1: Set Up Your Project
First, create a project folder and install the dependencies:
mkdir QuickAudioCutter
cd QuickAudioCutter
Install the required Python packages:
pip install ttkbootstrap tkinterdnd2
Note: Tkinter comes pre-installed with standard Python.
Step 2: Import Required Modules
Start your script by importing Python modules for GUI, threading, and file handling:
import os
import sys
import threading
import subprocess
import traceback
from queue import Queue, Empty
import ttkbootstrap as tb
import tkinter as tk
from tkinterdnd2 import TkinterDnD, DND_FILES
from tkinter import filedialog, messagebox
tkinter and ttkbootstrap → for GUI elements
threading → for non-blocking audio processing
subprocess → to run FFmpeg commands
queue → to safely update the GUI from threads
Step 3: Configure Your App and FFmpeg Paths
Set basic app info and the paths to FFmpeg executables:
APP_NAME = "QuickAudioCutter – Audio Cutter"
APP_VERSION = "1.0.0"
FFMPEG_PATH = r"C:\ffmpeg\bin\ffmpeg.exe"
FFPLAY_PATH = r"C:\ffmpeg\bin\ffplay.exe"
SUPPORTED_FORMATS = ["mp3", "wav", "ogg", "m4a", "flac"]
Make sure FFmpeg is installed on your system and the paths are correct.
Step 4: Initialize the GUI
Create the main TkinterDnD window and apply a dark theme:
app = TkinterDnD.Tk()
app.title(f"{APP_NAME} v{APP_VERSION}")
app.geometry("1150x740")
tb.Style("darkly")
TkinterDnD.Tk() → allows drag & drop support
ttkbootstrap.Style("darkly") → applies a modern dark theme
Step 5: Define Helper Functions
We need functions to convert time formats and get audio duration:
def hhmmss_to_seconds(value: str) -> float:
parts = [float(p) for p in value.split(":")]
if len(parts) == 3:
h, m, s = parts
return h * 3600 + m * 60 + s
elif len(parts) == 2:
m, s = parts
return m * 60 + s
return parts[0]
def seconds_to_hhmmss(seconds: float) -> str:
h = int(seconds // 3600)
m = int((seconds % 3600) // 60)
s = int(seconds % 60)
return f"{h:02}:{m:02}:{s:02}"
def get_audio_duration(file_path):
cmd = [FFMPEG_PATH, "-i", file_path, "-hide_banner"]
proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.DEVNULL, text=True)
for line in proc.stderr:
if "Duration:" in line:
dur = line.split("Duration:")[1].split(",")[0].strip()
h, m, s = dur.split(":")
return int(float(h) * 3600 + float(m) * 60 + float(s))
return 0
Converts between HH:MM:SS and seconds
Gets audio duration using FFmpeg
Step 6: Create the File List Panel
Add a panel to display and manage audio files:
files_card = tb.Labelframe(app, text="🎵 Audio Files", padding=12)
files_card.pack(fill="x", padx=12, pady=6)
listbox = tk.Listbox(files_card, height=4)
listbox.pack(side="left", fill="x", expand=True)
scroll = tk.Scrollbar(files_card, command=listbox.yview)
scroll.pack(side="right", fill="y")
listbox.config(yscrollcommand=scroll.set)
Listbox → shows selected files
Scrollbar → scrolls when many files are added
Add buttons to add and clear audio files:
def add_audio():
files = filedialog.askopenfilenames(filetypes=[("Audio Files", "*.mp3 *.wav *.ogg *.m4a *.flac")])
for f in files:
listbox.insert("end", f)
tb.Button(files_card, text="➕ Add Files", bootstyle="success", command=add_audio).pack(side="left", padx=6)
tb.Button(files_card, text="🧹 Clear", bootstyle="danger-outline", command=lambda: listbox.delete(0, "end")).pack(side="left", padx=6)
Step 7: Add Time Inputs and Sliders
Create start/end time fields and sliders for trimming:
start_time_var = tb.StringVar(value="00:00:00")
end_time_var = tb.StringVar(value="00:00:00")
time_frame = tb.Frame(app)
time_frame.pack(pady=12)
tb.Label(time_frame, text="Start:").pack(side="left")
tb.Entry(time_frame, textvariable=start_time_var, width=10).pack(side="left", padx=4)
tb.Label(time_frame, text="End:").pack(side="left")
tb.Entry(time_frame, textvariable=end_time_var, width=10).pack(side="left", padx=4)
Later, you can link these to ttk.Scale sliders for interactive trimming.
Step 8: Implement the Audio Processing Function
Use FFmpeg to trim audio files:
def process_audio():
for idx, audio in enumerate(listbox.get(0, "end")):
start_sec_val = hhmmss_to_seconds(start_time_var.get())
end_sec_val = hhmmss_to_seconds(end_time_var.get())
base = os.path.splitext(os.path.basename(audio))[0]
out_file = f"{base}_trim.mp3"
cmd = [FFMPEG_PATH, "-y", "-ss", str(start_sec_val), "-to", str(end_sec_val), "-i", audio, out_file]
subprocess.run(cmd)
print(f"Processed: {out_file}")
-ss → start time
-to → end time
-y → overwrite output if it exists
Step 9: Add Preview Feature
Allow users to preview audio segments using FFplay:
def play_preview():
selection = listbox.curselection()
if not selection:
return
audio = listbox.get(selection[0])
start_sec_val = hhmmss_to_seconds(start_time_var.get())
end_sec_val = hhmmss_to_seconds(end_time_var.get())
cmd = [FFPLAY_PATH, "-nodisp", "-autoexit", "-ss", str(start_sec_val), "-to", str(end_sec_val), audio]
threading.Thread(target=lambda: subprocess.run(cmd), daemon=True).start()
-nodisp → no video window
-autoexit → automatically close after playback
Uses a thread to prevent GUI freezing
Step 10: Run the App
Finally, start the main loop:
tb.Button(app, text="🚀 Start", bootstyle="success", command=process_audio).pack(pady=12)
tb.Button(app, text="▶ Play Preview", bootstyle="info", command=play_preview).pack(pady=6)
app.mainloop()
Step 11: Drag & Drop Support
Enable adding files via drag & drop:
def drop(event):
files = app.tk.splitlist(event.data)
for f in files:
if os.path.isfile(f):
listbox.insert("end", f)
app.drop_target_register(DND_FILES)
app.dnd_bind("<<Drop>>", drop)
Step 12: Try It Out
Now you have a fully functional QuickAudioCutter:
Add audio files via drag & drop or “Add Files”
Set start and end times
Trim files in batch
Preview audio segments before processing
✅ Next Steps
Add a progress bar for batch processing
Save files to a custom output folder
Improve error handling and logging
GitHub Repository:
https://github.com/rogers-cyber/QuickAudioCutter
This tutorial breaks the project into smaller steps, making it beginner-friendly and easy to follow.

Top comments (3)
Helpful breakdown.
Appreciate it, Patrick! Happy to hear the step-by-step made things clearer.
Worth bookmarking.