音视频转换软件
更新日志12.30
插件改为自动检测,检查不到的话会自动下载安装
新增批量处理视频以及音频
新增自由勾选多线程处理任务
就这么多没有其他的,后续更新看个人情况!!!
以下是源码
import tkinter as tk
from tkinter import filedialog, messagebox
import subprocess
import os
import requests
import zipfile
import threading
# 定义执行耗时操作的函数
def run_task_in_thread(task):
threading.Thread(target=task).start()
# 定义执行批处理脚本的函数
def run_batch_script():
ffmpeg_url = "http://valkire.cn/down.php/f4f0acdca149b604a2a9d76b4e2a4ac6.zip" # FFmpeg下载链接
ffmpeg_path = r"C:\ffmpeg\bin"
ffmpeg_zip = r"C:\ffmpeg.zip"
# 检测FFmpeg是否已安装
def is_ffmpeg_installed():
return os.path.exists(ffmpeg_path)
# 下载FFmpeg
def download_ffmpeg(url, zip_path):
response = requests.get(url, stream=True) # 使用stream=True来逐块下载
total_size = int(response.headers.get('content-length', 0))
block_size = 1024 # 1 Kibibyte
wrote = 0
with open(zip_path, 'wb') as f:
for data in response.iter_content(block_size):
wrote += len(data)
f.write(data)
# 更新日志中的进度条
progress = (wrote / total_size) * 100
log_message(f"这是下载必要插件,下载过程有点慢,请耐心等待,总共大小383MB /n 下载进度: {progress:.2f}%")
print("下载完成。") # 最后打印完成信息
# 解压FFmpeg
def unzip_ffmpeg(zip_path, extract_path):
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_path)
log_message("FFmpeg解压完成。")
# 添加到系统PATH
def add_to_path(path):
current_path = os.environ['PATH']
if path not in current_path:
os.environ["PATH"] += os.pathsep + path
subprocess.run(["setx", "PATH", f"{current_path};{path}"], shell=True)
log_message(f"{path}已添加到系统PATH。")
else:
log_message(f"{path}已在系统PATH中。")
if not is_ffmpeg_installed():
log_message("FFmpeg未检测到,开始下载...")
download_ffmpeg(ffmpeg_url, ffmpeg_zip)
log_message("FFmpeg下载完成,开始解压...")
unzip_ffmpeg(ffmpeg_zip, r"C:\ffmpeg")
log_message("FFmpeg解压完成,检查是否已添加到系统PATH...")
add_to_path(ffmpeg_path)
log_message("FFmpeg安装完成,可以继续操作!")
else:
log_message("检查到插件FFmpeg已安装,无需重复安装。")
# 定义执行单个音频处理的函数
def change_mp3_quality():
input_file = filedialog.askopenfilename(title="选择MP3文件", filetypes=[("MP3 files", "*.mp3")])
if not input_file:
return
output_file = filedialog.asksaveasfilename(title="保存音频文件", defaultextension=".mp3", filetypes=[("MP3 files", "*.mp3"), ("FLAC files", "*.flac")])
if not output_file:
return
bitrate = bitrate_var.get()
if bitrate == "无损":
output_file = os.path.splitext(output_file)[0] + '.flac'
command = f'ffmpeg -i "{input_file}" -c:a flac -b:a 1411k "{output_file}"'
else:
output_file = os.path.splitext(output_file)[0] + '.mp3' if not output_file.lower().endswith('.mp3') else output_file
command = f'ffmpeg -i "{input_file}" -b:a {bitrate} "{output_file}"'
if use_thread_var.get():
run_task_in_thread(lambda: subprocess.run(command, shell=True))
else:
subprocess.run(command, shell=True)
log_message("音频处理完成")
# 定义执行单个视频格式转换的函数
def convert_video_format():
input_file = filedialog.askopenfilename(title="选择视频文件", filetypes=[("Video files", "*.*")])
if not input_file:
return
output_file = filedialog.asksaveasfilename(title="保存视频文件", defaultextension=".mp4", filetypes=[("MP4 files", "*.mp4"), ("AVI files", "*.avi"), ("MOV files", "*.mov")])
if not output_file:
return
format = format_var.get()
output_file = os.path.splitext(output_file)[0] + '.' + format if not output_file.lower().endswith('.' + format) else output_file
command = f'ffmpeg -i "{input_file}" -codec:v libx264 -codec:a aac -crf 23 -preset fast "{output_file}"'
if use_thread_var.get():
run_task_in_thread(lambda: subprocess.run(command, shell=True))
else:
subprocess.run(command, shell=True)
log_message("视频格式转换完成")
# 定义执行音频批量处理的函数
def batch_process_audio():
file_paths = filedialog.askopenfilenames(title="选择音频文件", filetypes=[("Audio files", "*.mp3 *.wav *.flac")])
if not file_paths:
return
for file_path in file_paths:
process_audio_file(file_path)
# 定义执行视频批量处理的函数
def batch_process_video():
file_paths = filedialog.askopenfilenames(title="选择视频文件", filetypes=[("Video files", "*.mp4 *.avi *.mov")])
if not file_paths:
return
for file_path in file_paths:
process_video_file(file_path)
# 定义处理单个音频文件的函数
def process_audio_file(file_path):
output_file = os.path.splitext(file_path)[0] + '_processed.mp3'
bitrate = bitrate_var.get()
command = f'ffmpeg -i "{file_path}" -b:a {bitrate} "{output_file}"'
if use_thread_var.get():
run_task_in_thread(lambda: subprocess.run(command, shell=True))
else:
subprocess.run(command, shell=True)
log_message(f"音频文件 {os.path.basename(file_path)} 处理完成,保存为 {os.path.basename(output_file)}")
# 定义处理单个视频文件的函数
def process_video_file(file_path):
output_file = os.path.splitext(file_path)[0] + '_processed.mp4'
format = format_var.get()
command = f'ffmpeg -i "{file_path}" -codec:v libx264 -codec:a aac -crf 23 -preset fast "{output_file}"'
if use_thread_var.get():
run_task_in_thread(lambda: subprocess.run(command, shell=True))
else:
subprocess.run(command, shell=True)
log_message(f"视频文件 {os.path.basename(file_path)} 格式转换完成,保存为 {os.path.basename(output_file)}")
# 定义更新日志的函数
def log_message(message):
log_text.insert(tk.END, message + "\n")
log_text.see(tk.END) # 自动滚动到最新日志
# 创建主窗口
root = tk.Tk()
root.title("音视频处理工具")
root.geometry("400x700") # 设置窗口大小为400x600
root.iconbitmap(r"c:\Users\Administrator\Desktop\stool.ico")
# 创建日志输出框
log_text = tk.Text(root, height=10, width=50)
log_text.pack(pady=10)
# 创建线程处理选项
tk.Label(root, text="是否使用线程处理任务?线程处理会更快哦!").pack()
use_thread_var = tk.BooleanVar()
tk.Checkbutton(root, text="使用线程", variable=use_thread_var).pack()
# 检测并安装FFmpeg
run_task_in_thread(run_batch_script)
# 创建MP3音质修改部分的GUI
tk.Label(root, text="MP3音质修改").pack()
bitrate_var = tk.StringVar(value="128k")
tk.Label(root, text="选择比特率:").pack()
tk.Radiobutton(root, text="98k", variable=bitrate_var, value="98k").pack()
tk.Radiobutton(root, text="128k", variable=bitrate_var, value="128k").pack()
tk.Radiobutton(root, text="256k", variable=bitrate_var, value="256k").pack()
tk.Radiobutton(root, text="320k", variable=bitrate_var, value="320k").pack()
tk.Radiobutton(root, text="无损 (1411kbps)", variable=bitrate_var, value="无损").pack()
tk.Button(root, text="修改MP3音质", command=change_mp3_quality).pack()
#创建音频批量处理部分的GUI
tk.Label(root, text="音频批量处理").pack()
tk.Button(root, text="批量处理音频", command=batch_process_audio).pack()
# 创建视频格式转换部分的GUI
tk.Label(root, text="视频格式转换").pack()
format_var = tk.StringVar(value="mp4")
tk.Label(root, text="选择格式:").pack()
tk.Radiobutton(root, text="MP4", variable=format_var, value="mp4").pack()
tk.Radiobutton(root, text="AVI", variable=format_var, value="avi").pack()
tk.Radiobutton(root, text="MOV", variable=format_var, value="mov").pack()
tk.Button(root, text="转换视频格式", command=convert_video_format).pack()
#创建视频批量处理部分的GUI
tk.Label(root, text="视频批量处理").pack()
tk.Button(root, text="批量处理视频", command=batch_process_video).pack()
#运行主循环
root.mainloop()