import imageio

imageio.plugins.ffmpeg.download()
from datetime import datetime
import os
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.video.compositing.concatenate import concatenate_videoclips
from threading import Thread
from tkinter import Tk, Label, filedialog, Button, Entry, END, Text class App(object): def __init__(self):
self.tk = Tk()
self.tk.geometry("540x350+10+10")
self.tk.resizable(False, False)
self.tk.title("视频拼接") # 显示片头路径文本框
self.head_entry = Entry(self.tk)
self.head_entry.place(x=150, y=60, width=300, height=30) # 显示需要添加片头的视频路径文本框
self.source_entry = Entry(self.tk)
self.source_entry.place(x=150, y=100, width=300, height=30) # 显示需要添加片尾头的视频路径文本框
self.tail_entry = Entry(self.tk)
self.tail_entry.place(x=150, y=140, width=300, height=30)
# 显示需要添加片尾头的视频路径文本框
self.save_entry = Entry(self.tk)
self.save_entry.place(x=150, y=180, width=300, height=30) self.log_text = Text(self.tk)
self.log_text.place(x=60, y=220, width=330, height=100) def show_log(self, info):
self.log_text.insert(END, "{} {}\n".format(datetime.now().strftime("%H:%M:%S"), info)) def add_author(self, name, company):
# 添加作者名称
L_author = Label(self.tk, text=f'作者:{name}')
L_author.config(font='Helvetica -10 bold', fg='#030303')
L_author.place(x=440, y=330) # 添加作者公司
L_title = Label(self.tk, text=f'公司:{company}')
L_title.config(font='Helvetica -10 bold', fg='blue')
L_title.place(x=350, y=330) def head_video(self):
"""获取片头视频路径""" # 按钮
s_button = Button(self.tk, text=f'选择片头', command=self.get_head_video_path)
s_button.place(x=60, y=60) def source_video(self):
# 按钮
s_button = Button(self.tk, text=f'选择视频', command=self.get_source_video_path)
s_button.place(x=60, y=100) def tail_video(self):
# 按钮
s_button = Button(self.tk, text=f'选择片尾', command=self.get_tail_video_path)
s_button.place(x=60, y=140) def save_video(self):
# 按钮
s_button = Button(self.tk, text=f'保存路径', command=self.get_save_video_path)
s_button.place(x=60, y=180) def get_head_video_path(self):
# 获取到片头路径显示到文本框
head_video_path = filedialog.askopenfilename(title="选择片头")
self.head_entry.delete(0, END)
self.head_entry.insert(0, head_video_path) def get_source_video_path(self):
# 获取到需要添加片头的视频
source_video_path = filedialog.askopenfilenames(title="选择视频")
self.source_entry.delete(0, END)
self.source_entry.insert(0, source_video_path) def get_tail_video_path(self):
# 获取到需要添加片头的视频文件夹写入到文本框
tail_video_path = filedialog.askopenfilename(title="选择片尾")
self.tail_entry.delete(0, END)
self.tail_entry.insert(0, tail_video_path) def get_save_video_path(self):
# 保存文件的路径
tail_video_path = filedialog.askdirectory(title="保存路径")
self.save_entry.delete(0, END)
self.save_entry.insert(0, tail_video_path) def get_all_path(self):
"""从文本框获取路径,并判断是否有传"""
head_video_path = self.head_entry.get()
source_video_path = [] if not self.source_entry.get() else self.source_entry.get().split(" ")
tail_video_path = self.tail_entry.get()
save_video_path = self.save_entry.get()
if not head_video_path and not tail_video_path:
self.show_log("ERROR:请选择片头或片尾")
return
if not source_video_path:
self.show_log("ERROR:请选择需要加片头或者片尾的视频")
return
if not save_video_path:
self.show_log("ERROR:请选择保存路径")
return
self.show_log("INFO:路径正确")
return head_video_path, source_video_path, tail_video_path, save_video_path def concat(self):
# 获取到路径
head_video_path, source_video_path, tail_video_path, save_video_path = self.get_all_path() # 先判断片头
if head_video_path and not head_video_path.endswith(('.mp4', '.mkv', '.avi', '.wmv', '.iso')):
self.show_log("ERROR: 片头文件不是视频格式,错误文件%s" % head_video_path)
if tail_video_path and not head_video_path.endswith(('.mp4', '.mkv', '.avi', '.wmv', '.iso')):
self.show_log("ERROR: 片尾文件不是视频格式,错误文件%s" % head_video_path)
if not os.path.exists(save_video_path):
self.show_log("ERROR: 保存文件路径不存在")
return
head_video = None
tail_video = None
if head_video_path:
head_video = VideoFileClip(head_video_path) # 加载片头
if tail_video_path:
tail_video = VideoFileClip(tail_video_path) # 加载片尾 for file in source_video_path:
th = Thread(target=self._concat,args=(file,head_video,tail_video,save_video_path))
th.start() def _concat(self,file,head_video,tail_video,save_video_path):
file_name = os.path.basename(file)
self.show_log("INFO: %s 开始拼接" % file_name)
video_list = []
if not file.endswith(('.mp4', '.mkv', '.avi', '.wmv', '.iso')):
self.show_log("ERROR: 视频格式错误,错误文件%s" % file_name)
return
video = VideoFileClip(file) # 加载正片 # 判断是否有片头或者片尾,按顺序添加
if head_video:
video_list.append(head_video)
video_list.append(video)
if tail_video:
video_list.append(tail_video)
final_clip = concatenate_videoclips(video_list) # 进行视频合并
final_clip.write_videofile(os.path.join(save_video_path, file_name))
final_clip.close()
self.show_log("INFO: %s 拼接完成" % file_name) def start(self):
# 开始拼接
s_button = Button(self.tk, text=f'开始', command=self.concat)
s_button.place(x=415, y=220) def run(self):
self.add_author("黄贵锋", "恒企教育")
self.head_video() # 片头
self.source_video()
self.tail_video() # 片尾
self.save_video() # 保存位置
self.start() # 点击启动按钮
self.tk.mainloop() if __name__ == '__main__':
app = App()
app.run()

最新文章

  1. 2016年最好的15个Web设计和开发工具
  2. POJ 2960 S-Nim<博弈>
  3. js网页滚动条滚动事件实例分析
  4. input框中value与placeholder的区别
  5. 3.MVC框架开发(Razor内嵌函数)
  6. 13个小技巧帮你征服Xcode
  7. 【LA3523】 Knights of the Round Table (点双连通分量+染色问题?)
  8. javascript String 和StringBuffer 的应用
  9. Linux权限体系总结
  10. node.js后台快速搭建在阿里云(一)(express篇)
  11. openGPS.cn - 高精度IP定位原理,定位误差说明
  12. Json操作问题总结
  13. layui之事件监听(table)
  14. php学习笔记位运算
  15. windows下为qt msvc版本配置调试器
  16. 『ice 离散化广搜』
  17. Android屏幕旋转
  18. FizzBuzz
  19. pytorch 损失函数
  20. 深入理解Proxy 及 使用Proxy实现vue数据双向绑定

热门文章

  1. DevExpress v19.1新版亮点——WinForms篇(三)
  2. CSS3——PC以及移动端页面适配方法(响应布局)
  3. delphi 10.3 控件遮挡 webbrowser
  4. mysql PRIMARY KEY约束 语法
  5. [CF938E]Max History题解
  6. .NET COM+级别的事务Transaction实现
  7. MySQL Schedule Event
  8. shell后台进程
  9. 【后台管理系统】—— Ant Design Pro组件使用(二)
  10. spark 学习网站和资料