要求是对视频进行一系列的剪辑操作并转换成.MOV格式的视频。
平时我们用软件AE,PR都可以做这样的事情。
但是如果需要批量处理那么就需要自动化软件来运行比较方便。
下面是我写的这个软件的代码。(没有很好的封装 ^_^,大家将就看一下。)
有三个模块文件:分别是:DBD.py , MainFrame.py , movieform.py
贴上源代码:
DBD.py (数据库访问模块,主要实现对数据库用户的访问及更新操作)
#! /usr/bin/python
# _*_ coding:utf-8 _*_
import MySQLdb
import base64
linestr = "DS47lLinx=\nx|MjEIuM7TA1\n|bZG9XZ\n|ZG94\n|bWweQ==\n"
liststr = linestr.split("|")
db = MySQLdb.connect(base64.decodestring(liststr[1]), base64.decodestring(liststr[2]), base64.decodestring(liststr[3]), base64.decodestring(liststr[4]))
db.set_character_set('utf8')
cursor = db.cursor()
def insertJqm(sql):
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
def selectBysql_one(sql):
cursor.execute(sql)
info = cursor.fetchone()
return info
def selectBysql(sql):
cursor.execute(sql)
info = cursor.fetchone()
if info:
return True
else:
return False
def selectBysqlALL(sql):
cursor.execute(sql)
info = cursor.fetchall()
return info
|
MainFrame.py(GUI登陆入口界面,这里使用wxPython来实现GUI)
#! /usr/bin/python
# _*_ coding:utf-8 _*_
import six
import wx
import DBD
# import http.client
import httplib
import time
import datetime
import hashlib
import movieform
import socket
import uuid
from json import load
from urllib2 import urlopen
class ButtonFrame(wx.Frame):
def __init__(self):
mm=wx.DisplaySize()
wx.Frame.__init__(self, None, -1, u'视频批处理工具',
size=(290, 200),pos=((mm[0]-290)/2,(mm[1]-200)/2),style=wx.DEFAULT_DIALOG_STYLE)
panel = wx.Panel(self, -1)
self.icon = wx.Icon('favicon.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(self.icon)
self.isMax = False
self.Maximize(False)
wx.StaticText(panel, -1, u"用户名:", pos = (35, 32))
self.uname = wx.TextCtrl(panel, -1, "", pos = (90, 30),size=(150,25))
wx.StaticText(panel, -1, u"密 码:", pos = (35, 75))
self.upws = wx.TextCtrl(panel, -1, "", pos = (90, 72),size=(150,25),style=wx.TE_PASSWORD)
self.buttonLogin = wx.Button(panel, -1, u"登 陆", pos=(90, 115),size=(65,30))
self.Bind(wx.EVT_BUTTON, self.OnclickLogin, self.buttonLogin)
self.buttonLogin.SetDefault()
self.buttonReset = wx.Button(panel, -1, u"重 填", pos=(175, 115),size=(65,30))
self.Bind(wx.EVT_BUTTON, self.OnclickReset, self.buttonReset)
#self.buttonReset.SetDefault()
def getdatetime(self,host):
conn = httplib.HTTPConnection(host)
conn.request("GET", "/")
r = conn.getresponse()
ts = r.getheader('date')
#将GMT时间转换成北京时间
ltime= time.strptime(ts[5:25], "%d %b %Y %H:%M:%S")
ttime=time.localtime(time.mktime(ltime)+8*60*60)
dat="%u-%02u-%02u"%(ttime.tm_year,ttime.tm_mon,ttime.tm_mday)
tm="%02u:%02u:%02u"%(ttime.tm_hour,ttime.tm_min,ttime.tm_sec)
return datetime.datetime.strptime(dat+' '+tm, '%Y-%m-%d %H:%M:%S')
def getipmacname(self):
def get_mac_address():
mac=uuid.UUID(int = uuid.getnode()).hex[-12:]
return ":".join([mac[e:e+2] for e in range(0,11,2)])
myname = socket.getfqdn(socket.gethostname())
mymacaddr = get_mac_address()
#myip = load(urlopen('http://jsonip.com'))['ip']
h2 = hashlib.md5()
#h2.update(myname+mymacaddr+myip)
h2.update(myname+mymacaddr)
return h2.hexdigest()
def OnclickLogin(self,event):
u_name = self.uname.GetValue()
u_pws = self.upws.GetValue()
if u_name == "":
dlg1 = wx.MessageDialog(None, u"请填写用户名!", u"温馨提示", wx.OK)
if dlg1.ShowModal() == wx.ID_OK:
dlg1.Destroy()
return
if u_pws == "":
dlg2 = wx.MessageDialog(None, u"请填写密码!", u"温馨提示", wx.OK)
if dlg2.ShowModal() == wx.ID_OK:
dlg2.Destroy()
return
hl = hashlib.md5()
hl.update(u_pws)
u_pws = hl.hexdigest()
sql = "selects userid,username,userpws,user_jqm,usercnt,userregtime,userendtime from usertab where username='"+u_name+"' and userpws='"+u_pws+"'"
flag = DBD.selectBysql(sql)
if not flag:
dlg = wx.MessageDialog(None, u"用户名或密码不正确,请重新填写.", u"温馨提示", wx.OK | wx.ICON_ERROR )
if dlg.ShowModal() == wx.ID_OK:
#self.OnclickReset(event)
pass
dlg.Destroy()
else:
info = DBD.selectBysql_one(sql)
userid = info[0]
username = info[1]
userpws = info[2]
user_jqm = info[3]
usercnt = info[4]
userregtime = info[5]
userendtime = info[6]
currentdatetime = self.getdatetime("www.baidu.com")
if(currentdatetime > userendtime):
dlg = wx.MessageDialog(None, u"软件授权已过期!请联系管理员重新获取授权!", u"温馨提示", wx.OK | wx.ICON_ERROR )
if dlg.ShowModal() == wx.ID_OK:
pass
dlg.Destroy()
else:
ipmacname = self.getipmacname()
nowdatetime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if not user_jqm:
sql = "UPDATEs usertab SET user_jqm='"+ipmacname+"' where username='"+u_name+"' and userpws='"+u_pws+"'"
DBD.insertJqm(sql)
sql1 = "UPDATEs usertab SET user_logintime='"+nowdatetime+"' where username='"+u_name+"' and userpws='"+u_pws+"'"
DBD.insertJqm(sql1)
mbf = movieform.ButtonFrame(userid,username,userpws,ipmacname,usercnt,userregtime,userendtime)
mbf.Show()
DBD.db.close()
self.Close()
self.Destroy()
else:
if ipmacname == user_jqm:
sql1 = "UPDATEs usertab SET user_logintime='"+nowdatetime+"' where username='"+u_name+"' and userpws='"+u_pws+"'"
DBD.insertJqm(sql1)
mbf = movieform.ButtonFrame(userid,username,userpws,user_jqm,usercnt,userregtime,userendtime)
mbf.Show()
DBD.db.close()
self.Close()
self.Destroy()
else:
dlg = wx.MessageDialog(None, u"暂未授权!请联系管理员获取授权!", u"温馨提示", wx.OK | wx.ICON_ERROR )
if dlg.ShowModal() == wx.ID_OK:
#self.OnclickReset(event)
pass
dlg.Destroy()
def OnclickReset(self,event):
self.uname.SetValue("")
self.upws.SetValue("")
pass
if __name__ == '__main__':
app = wx.App()
frame = ButtonFrame()
frame.SetSize((290,200))
frame.Show(True)
app.MainLoop()
|
movieform.py(这个模块主要完成视频的批处理操作)
#! /usr/bin/python
# _*_ coding:utf-8 _*_
#import http.client
import httplib
import time
import datetime
import socket
import uuid
import hashlib
from json import load
from urllib2 import urlopen
import os
import wx
# import imageio
# imageio.plugins.ffmpeg.download()
import moviepy
from moviepy.editor import *
# from moviepy.config import change_settings
# 32位
# change_settings({"IMAGEMAGICK_BINARY": r"ffmpeg\convert.exe"})
# 64位
# change_settings({"IMAGEMAGICK_BINARY": r"ffmpeg\convert_64.exe"})
class ButtonFrame(wx.Frame):
def __init__(self,userid,username,userpws,user_jqm,usercnt,userregtime,userendtime):
self.userid = userid
self.username = username
self.userpws = userpws
self.user_jqm = user_jqm
self.usercnt = usercnt
self.userregtime = userregtime
self.userendtime = userendtime
mm=wx.DisplaySize()
title_str = u"批量视频工具|截止时间:"+str(self.userendtime)
wx.Frame.__init__(self, None, -1, title_str,
size=(350, 224),pos=((mm[0]-350)/2,(mm[1]-200)/2),style=wx.DEFAULT_DIALOG_STYLE)
panel = wx.Panel(self, -1)
self.isMax = False
self.Maximize(False)
self.icon = wx.Icon('favicon.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(self.icon)
# self.icon = wx.EmptyIcon()
# self.icon.CopyFromBitmap(wx.BitmapFromImage(wx.Image(("favicon.ico"), wx.BITMAP_TYPE_ICO)))
# self.SetIcon(self.icon)
wx.StaticText(panel, -1, u"源目录:", pos = (10, 32))
self.sourceurl = wx.TextCtrl(panel, -1, "", pos = (65, 30),size=(200,25))
self.buttonsource = wx.Button(panel, -1, u"选择目录", pos=(275, 30),size=(60,25))
self.Bind(wx.EVT_BUTTON, self.OnclickSource, self.buttonsource)
self.buttonsource.SetDefault()
wx.StaticText(panel, -1, u"目标目录:", pos = (10, 80))
self.targeturl = wx.TextCtrl(panel, -1, "", pos = (65, 75),size=(200,25))
self.buttontarget = wx.Button(panel, -1, u"选择目录", pos=(275, 75),size=(60,25))
self.Bind(wx.EVT_BUTTON, self.OnclickTarget, self.buttontarget)
self.buttontarget.SetDefault()
self.buttonLogin = wx.Button(panel, -1, u"开始任务", pos=(90, 125),size=(165,30))
self.Bind(wx.EVT_BUTTON, self.OnclickLogin, self.buttonLogin)
self.buttonLogin.SetDefault()
bottomtitle_str = u"欢迎使用!版权解释权归小牛软件所有!"
if self.usercnt:
bottomtitle_str = bottomtitle_str+u"[请获取正式版授权]"
self.txt_tips = wx.TextCtrl(panel, -1, bottomtitle_str, pos = (0, 170),size=(344,25),style=wx.TE_READONLY | wx.TE_CENTER)
def getdatetime(self,host):
conn = httplib.HTTPConnection(host)
conn.request("GET", "/")
r = conn.getresponse()
ts = r.getheader('date')
#将GMT时间转换成北京时间
ltime = time.strptime(ts[5:25], "%d %b %Y %H:%M:%S")
ttime = time.localtime(time.mktime(ltime)+8*60*60)
dat="%u-%02u-%02u"%(ttime.tm_year,ttime.tm_mon,ttime.tm_mday)
tm="%02u:%02u:%02u"%(ttime.tm_hour,ttime.tm_min,ttime.tm_sec)
return datetime.datetime.strptime(dat+' '+tm, '%Y-%m-%d %H:%M:%S')
def getipmacname(self):
def get_mac_address():
mac = uuid.UUID(int = uuid.getnode()).hex[-12:]
return ":".join([mac[e:e+2] for e in range(0,11,2)])
myname = socket.getfqdn(socket.gethostname())
mymacaddr = get_mac_address()
#myip = load(urlopen('http://jsonip.com'))['ip']
h2 = hashlib.md5()
#h2.update(myname+mymacaddr+myip)
h2.update(myname+mymacaddr)
return h2.hexdigest()
def OnclickLogin(self,event):
u_sourceurl = self.sourceurl.GetValue()
u_targeturl = self.targeturl.GetValue()
if u_sourceurl == "":
dlg1 = wx.MessageDialog(None, u"请选择视频源目录!", u"温馨提示", wx.OK)
if dlg1.ShowModal() == wx.ID_OK:
dlg1.Destroy()
return
if u_targeturl == "":
dlg1 = wx.MessageDialog(None, u"请选择视频目标目录!", u"温馨提示", wx.OK)
if dlg1.ShowModal() == wx.ID_OK:
dlg1.Destroy()
return
self.txt_tips.SetValue(u"视频正在处理中.....请稍等......")
time.sleep(2)
currentdatetime = self.getdatetime("www.baidu.com")
if(currentdatetime > self.userendtime):
dlg = wx.MessageDialog(None, u"软件授权已过期!请联系管理员重新获取授权!", u"温馨提示", wx.OK | wx.ICON_ERROR )
if dlg.ShowModal() == wx.ID_OK:
pass
dlg.Destroy()
self.Close()
self.Destroy()
else:
if self.getipmacname() != self.user_jqm:
print("xxxx")
dlg = wx.MessageDialog(None, u"暂未授权!请联系管理员获取授权!", u"温馨提示", wx.OK | wx.ICON_ERROR )
if dlg.ShowModal() == wx.ID_OK:
pass
dlg.Destroy()
self.Close()
self.Destroy()
else:
self.clip = Clips()
self.clip.processclip(u_sourceurl,u_targeturl,self.txt_tips,self.usercnt)
def OnclickSource(self,event):
dlg1 = wx.DirDialog(None, u"选择视频源文件夹!", u"温馨提示", wx.OK)
if dlg1.ShowModal() == wx.ID_OK:
sourceurl_ = dlg1.GetPath()
self.sourceurl.SetValue(sourceurl_)
dlg1.Destroy()
return
def OnclickTarget(self,event):
dlg1 = wx.DirDialog(None, u"选择视频目标文件夹!", u"温馨提示", wx.OK)
if dlg1.ShowModal() == wx.ID_OK:
targeturl_ = dlg1.GetPath()
self.targeturl.SetValue(targeturl_)
dlg1.Destroy()
return
class Clips(object):
def __init__(self):
pass
def processclip(self,source,target,txt_obj,usercnt):
num = 0
for root,dirs,files in os.walk(source):
for file in files:
clip = VideoFileClip(source+"\\"+file)
if clip.duration>=2:
w,h = clip.size
clip = clip.subclip(0.5, clip.duration-0.5)
clip = moviepy.video.fx.all.mirror_x(clip)
clip = moviepy.video.fx.all.supersample(clip,2,5)
clip2 = VideoFileClip(source+"\\"+file)
clip2 = clip2.subclip(0.5, clip2.duration-0.5)
clip2 = moviepy.video.fx.all.mirror_x(clip2)
clip2 = clip2.resize((w-120, h-120))
clip2 = moviepy.video.fx.all.margin(clip2,left=60, right=60,top=60, bottom=60, color=(0, 0, 0), opacity=0)
clip_target = CompositeVideoClip([clip, clip2],bg_color=0,use_bgclip=True)
clip_target.write_videofile(target+"\\"+file,fps=25, codec=None,audio=False,rewrite_audio=False)
newfilename = file.split('.')
os.rename(os.path.join(target,file),os.path.join(target,newfilename[0]+".MOV"))
num += 1
txt_obj.SetValue(u"视频总个数:"+str(len(files))+u"个, 已成功完成 "+str(num)+u" 个")
if usercnt:
if num >= int(usercnt):
break
|
效果图如下:




总结:
这个批处理软件主要使用了MoviePy模块。结合了数据库。获取用户计算机名及MAC地址生成机器码,来进行授权访问。
代码很多地方处理的不太好。还需要优化一下。代码贴出来了。仅供大家参考学习。
有需要源码和软件的朋友可以找我。
我的邮箱: robinn#163.com (把#改为@)