1. import imageio
  2.  
  3. imageio.plugins.ffmpeg.download()
  4. from datetime import datetime
  5. import os
  6. from moviepy.video.io.VideoFileClip import VideoFileClip
  7. from moviepy.video.compositing.concatenate import concatenate_videoclips
  8. from threading import Thread
  9. from tkinter import Tk, Label, filedialog, Button, Entry, END, Text
  10.  
  11. class App(object):
  12.  
  13. def __init__(self):
  14. self.tk = Tk()
  15. self.tk.geometry("540x350+10+10")
  16. self.tk.resizable(False, False)
  17. self.tk.title("视频拼接")
  18.  
  19. # 显示片头路径文本框
  20. self.head_entry = Entry(self.tk)
  21. self.head_entry.place(x=150, y=60, width=300, height=30)
  22.  
  23. # 显示需要添加片头的视频路径文本框
  24. self.source_entry = Entry(self.tk)
  25. self.source_entry.place(x=150, y=100, width=300, height=30)
  26.  
  27. # 显示需要添加片尾头的视频路径文本框
  28. self.tail_entry = Entry(self.tk)
  29. self.tail_entry.place(x=150, y=140, width=300, height=30)
  30. # 显示需要添加片尾头的视频路径文本框
  31. self.save_entry = Entry(self.tk)
  32. self.save_entry.place(x=150, y=180, width=300, height=30)
  33.  
  34. self.log_text = Text(self.tk)
  35. self.log_text.place(x=60, y=220, width=330, height=100)
  36.  
  37. def show_log(self, info):
  38. self.log_text.insert(END, "{} {}\n".format(datetime.now().strftime("%H:%M:%S"), info))
  39.  
  40. def add_author(self, name, company):
  41. # 添加作者名称
  42. L_author = Label(self.tk, text=f'作者:{name}')
  43. L_author.config(font='Helvetica -10 bold', fg='#030303')
  44. L_author.place(x=440, y=330)
  45.  
  46. # 添加作者公司
  47. L_title = Label(self.tk, text=f'公司:{company}')
  48. L_title.config(font='Helvetica -10 bold', fg='blue')
  49. L_title.place(x=350, y=330)
  50.  
  51. def head_video(self):
  52. """获取片头视频路径"""
  53.  
  54. # 按钮
  55. s_button = Button(self.tk, text=f'选择片头', command=self.get_head_video_path)
  56. s_button.place(x=60, y=60)
  57.  
  58. def source_video(self):
  59. # 按钮
  60. s_button = Button(self.tk, text=f'选择视频', command=self.get_source_video_path)
  61. s_button.place(x=60, y=100)
  62.  
  63. def tail_video(self):
  64. # 按钮
  65. s_button = Button(self.tk, text=f'选择片尾', command=self.get_tail_video_path)
  66. s_button.place(x=60, y=140)
  67.  
  68. def save_video(self):
  69. # 按钮
  70. s_button = Button(self.tk, text=f'保存路径', command=self.get_save_video_path)
  71. s_button.place(x=60, y=180)
  72.  
  73. def get_head_video_path(self):
  74. # 获取到片头路径显示到文本框
  75. head_video_path = filedialog.askopenfilename(title="选择片头")
  76. self.head_entry.delete(0, END)
  77. self.head_entry.insert(0, head_video_path)
  78.  
  79. def get_source_video_path(self):
  80. # 获取到需要添加片头的视频
  81. source_video_path = filedialog.askopenfilenames(title="选择视频")
  82. self.source_entry.delete(0, END)
  83. self.source_entry.insert(0, source_video_path)
  84.  
  85. def get_tail_video_path(self):
  86. # 获取到需要添加片头的视频文件夹写入到文本框
  87. tail_video_path = filedialog.askopenfilename(title="选择片尾")
  88. self.tail_entry.delete(0, END)
  89. self.tail_entry.insert(0, tail_video_path)
  90.  
  91. def get_save_video_path(self):
  92. # 保存文件的路径
  93. tail_video_path = filedialog.askdirectory(title="保存路径")
  94. self.save_entry.delete(0, END)
  95. self.save_entry.insert(0, tail_video_path)
  96.  
  97. def get_all_path(self):
  98. """从文本框获取路径,并判断是否有传"""
  99. head_video_path = self.head_entry.get()
  100. source_video_path = [] if not self.source_entry.get() else self.source_entry.get().split(" ")
  101. tail_video_path = self.tail_entry.get()
  102. save_video_path = self.save_entry.get()
  103. if not head_video_path and not tail_video_path:
  104. self.show_log("ERROR:请选择片头或片尾")
  105. return
  106. if not source_video_path:
  107. self.show_log("ERROR:请选择需要加片头或者片尾的视频")
  108. return
  109. if not save_video_path:
  110. self.show_log("ERROR:请选择保存路径")
  111. return
  112. self.show_log("INFO:路径正确")
  113. return head_video_path, source_video_path, tail_video_path, save_video_path
  114.  
  115. def concat(self):
  116. # 获取到路径
  117. head_video_path, source_video_path, tail_video_path, save_video_path = self.get_all_path()
  118.  
  119. # 先判断片头
  120. if head_video_path and not head_video_path.endswith(('.mp4', '.mkv', '.avi', '.wmv', '.iso')):
  121. self.show_log("ERROR: 片头文件不是视频格式,错误文件%s" % head_video_path)
  122. if tail_video_path and not head_video_path.endswith(('.mp4', '.mkv', '.avi', '.wmv', '.iso')):
  123. self.show_log("ERROR: 片尾文件不是视频格式,错误文件%s" % head_video_path)
  124. if not os.path.exists(save_video_path):
  125. self.show_log("ERROR: 保存文件路径不存在")
  126. return
  127. head_video = None
  128. tail_video = None
  129. if head_video_path:
  130. head_video = VideoFileClip(head_video_path) # 加载片头
  131. if tail_video_path:
  132. tail_video = VideoFileClip(tail_video_path) # 加载片尾
  133.  
  134. for file in source_video_path:
  135. th = Thread(target=self._concat,args=(file,head_video,tail_video,save_video_path))
  136. th.start()
  137.  
  138. def _concat(self,file,head_video,tail_video,save_video_path):
  139. file_name = os.path.basename(file)
  140. self.show_log("INFO: %s 开始拼接" % file_name)
  141. video_list = []
  142. if not file.endswith(('.mp4', '.mkv', '.avi', '.wmv', '.iso')):
  143. self.show_log("ERROR: 视频格式错误,错误文件%s" % file_name)
  144. return
  145. video = VideoFileClip(file) # 加载正片
  146.  
  147. # 判断是否有片头或者片尾,按顺序添加
  148. if head_video:
  149. video_list.append(head_video)
  150. video_list.append(video)
  151. if tail_video:
  152. video_list.append(tail_video)
  153. final_clip = concatenate_videoclips(video_list) # 进行视频合并
  154. final_clip.write_videofile(os.path.join(save_video_path, file_name))
  155. final_clip.close()
  156. self.show_log("INFO: %s 拼接完成" % file_name)
  157.  
  158. def start(self):
  159. # 开始拼接
  160. s_button = Button(self.tk, text=f'开始', command=self.concat)
  161. s_button.place(x=415, y=220)
  162.  
  163. def run(self):
  164. self.add_author("黄贵锋", "恒企教育")
  165. self.head_video() # 片头
  166. self.source_video()
  167. self.tail_video() # 片尾
  168. self.save_video() # 保存位置
  169. self.start() # 点击启动按钮
  170. self.tk.mainloop()
  171.  
  172. if __name__ == '__main__':
  173. app = App()
  174. app.run()

Python实现视频片头和片尾添加的更多相关文章

  1. Python学习笔记7 头文件的添加规则(转载)

    转载自:https://www.cnblogs.com/taurusfy/p/7605787.html ************************************************ ...

  2. [原创]使用python对视频/音频文件进行详细信息采集,并进行去重操作

    [原创]使用python对视频/音频文件进行详细信息采集,并进行去重操作 转载请注明出处 一.关于为什么用pymediainfo以及pymediainfo的安装 使用python对视频/音频文件进行详 ...

  3. Linux-NGINX 能否添加P3P头,如何添加。 - 德问:编程社交问答

    Linux-NGINX 能否添加P3P头,如何添加. - 德问:编程社交问答   您的投票让 杜鑫 声誉值增加5分. 支持投票,不仅能让提问用户获得声誉值,让好的问题有更多的曝光,更能帮助社区筛选出好 ...

  4. Python远程视频监控

    Python远程视频监控程序   老板由于事务繁忙无法经常亲临教研室,于是让我搞个监控系统,让他在办公室就能看到教研室来了多少人.o(>﹏<)o||| 最初我的想法是直接去网上下个软件,可 ...

  5. [视频]K8飞刀 WordPress XSS添加管理员 & GetShell 教程

    [视频]K8飞刀 WordPress  XSS添加管理员 & GetShell 教程 https://pan.baidu.com/s/1hq4LsmK

  6. 零基础快速掌握Python系统管理视频课程【猎豹网校】

    点击了解更多Python课程>>> 零基础快速掌握Python系统管理视频课程[猎豹网校] 课程目录 01.第01章 Python简介.mp4 02.第02章 IPython基础.m ...

  7. python全套视频十五期(116G)

    python全套视频,第十五期,从入门到精通,基础班,就业班,面试,软件包 所属网站分类: 资源下载 > python视频教程 作者:精灵 链接:http://www.pythonheidong ...

  8. Python学习教程(Python学习视频_Python学些路线):Day06 函数和模块的使用

    Python学习教程(Python学习视频_Python学些路线):函数和模块的使用 在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解. $$x_1 + x_2 + x ...

  9. [Python] 将视频转成ASCII符号形式、生成GIF图片

    一.简要说明 简述:本文主要展示将视频转成ASCII符号形式展示出来,带音频. 运行环境:Win10/Python3.5. 主要模块: PIL.numpy.shutil. [PIL]: 图像处理 [n ...

随机推荐

  1. bzoj3091 城市旅行 LCT + 区间合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3091 题解 调了整个晚自习才调出来的问题. 乍一看是个 LCT 板子题. 再看一眼还是个 LC ...

  2. bzoj4542 [Hnoi2016]大数 莫队+同余

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4542 题解 我们令 \(f_i\) 表示从 \(i\) 到 \(n\) 位组成的数 \(\bm ...

  3. 对15号夏壹队的TD信息通使用体验

    对夏壹队的APP的用户使用体验:首先下载的时候看到这个APP的大小是6M多点不算很大感觉还不错,但是占内存不大也说明了一个问题,它不会有很多的功能. 图标是一个蜜蜂,打开后会有一个登陆界面,一开始没有 ...

  4. el-select中显示图标/图片设置

    <template> <el-select ref="select_icon" v-model="addModel.icon" @change ...

  5. get和post请求方式的区别,常见状态码的整理

    get和post的区别 get和post是什么? HTTP协议中的两种发送请求的方法.get从指定的资源请求数据: post向指定的资源提交要被处理的数据. HTTP是什么? 超文本传输协议(HTTP ...

  6. 理解URL以及如何区分相对URL和绝对URL

    URL(Uniform Resource Locator 统一资源定位符)可以理解为网络地址. url 包含了关于文件储存位置和浏览器应该如何处理文件的信息. URL的第一个部分称为模式scheme, ...

  7. spring IOC(Spring 生命周期,先1.构造方式,2,初始化方法,3,目标方法,4,销毁方法)

  8. Linux内核设计与实现 总结笔记(第十四章)块I/O层

    一.剖析一个块设备 块设备最小的可寻址单元是扇区. 扇区大小一般是2的整数倍,最常见的是512字节. 因为各种软件的用途不同,所以他们都会用到自己的最小逻辑可寻址单元----块.块只能基于文件系统,是 ...

  9. 进阶1:Linux 环境准备_ 设置网络IP_安装火狐浏览器

    VM 已安装 centos6.5 Final 已安装 配置好了Linux  IP ,并能ping  通 ,例如 : ping www.baidu.com 设置LINUX 网络IP: https://j ...

  10. 笔记本连接树莓派3b(不需要屏幕)

    一.网线直连 工具:笔记本,网线,树莓派 软件:putty 过程: 将系统烧录进SD卡后,在root里添加一个名字为“ssh”的空白文件(不需后缀名)来开启ssh服务,SD卡里的cmdline.txt ...