Hello and welcome back to this final part of the video editing project. After this chapter, you will be good enough to continue to develop this application by yourself and hopefully, you can come out with a better idea of how to further develop this video editing application.
In this chapter I have created a thread for this video editing application which will separate the application into two part, the user interface part and the thread part. The user interface part will take care of the user’s click event and the user’s input and the threaded part will process the user input.
There is nothing new in this chapter besides separate the application into two part. The first part is the user interface part.
from tkinter import * from tkinter import filedialog import tkinter.ttk as tk from tkinter import messagebox from NewVid import NewVid import webbrowser win = Tk() # Create tk instance win.title("NeW Vid") # Add a title win.resizable(0, 0) # Disable resizing the GUI win.configure(background='white') # change background color mainframe = Frame(win) # create a frame mainframe.pack() eqFrame = Frame(win) # create eq frame eqFrame.pack(side = TOP, fill=X) animatedFrame = Frame(win) # create animated frame animatedFrame.pack(side = TOP, fill=X) trimFrame = Frame(win) # create trim frame trimFrame.pack(side = TOP, fill=X) buttonFrame = Frame(win) # create a button frame buttonFrame.pack(side = BOTTOM, fill=X, pady = 6) # Create a label and scale box for eq contrast_variable = DoubleVar() contrast = Scale(eqFrame, from_=float(-2.00), to=float(2.00), orient=HORIZONTAL, label="CONTRAST", digits=3, resolution=0.01, variable=contrast_variable) contrast.set(1) contrast.pack(side = LEFT) brightness_variable = DoubleVar() brightness = Scale(eqFrame, from_=float(-1.00), to=float(1.00), orient=HORIZONTAL, label="BRIGHTNESS", digits=3, resolution=0.01, variable=brightness_variable) brightness.pack(side = LEFT) saturation_variable = DoubleVar() saturation = Scale(eqFrame, from_=float(0.00), to=float(3.00), orient=HORIZONTAL, label="SATURATION", digits=3, resolution=0.01, variable=saturation_variable) saturation.set(1) saturation.pack(side = LEFT) gamma_variable = DoubleVar() gamma = Scale(eqFrame, from_=float(0.10), to=float(10.00), orient=HORIZONTAL, label="GAMMA", digits=4, resolution=0.01, variable=gamma_variable) gamma.set(1) gamma.pack(side = LEFT) loop_variable = DoubleVar() loop = Scale(eqFrame, from_=float(0), to=float(10), orient=HORIZONTAL, label="REPEAT", digits=2, resolution=1, variable=loop_variable) loop.pack(side = LEFT) fr_variable = DoubleVar() fr = Scale(eqFrame, from_=float(9), to=float(60), orient=HORIZONTAL, label="FPS", digits=2, resolution=1, variable=fr_variable) fr.set(24) fr.pack(side = LEFT) #create animated gif anime = Label(animatedFrame, text="Create Animated Image from Video ") anime.pack(side = TOP) anime.pack(side = LEFT) from_ = Label(animatedFrame, text="Start From (hour : minute : second) ") from_.pack(side = BOTTOM) from_.pack(side = LEFT) from_t_h_varable = StringVar() from_t_h = Entry(animatedFrame, width=3, textvariable=from_t_h_varable) from_t_h.pack(side=BOTTOM) from_t_h.pack(side=LEFT) from_m = Label(animatedFrame, text=" : ") from_m.pack(side = BOTTOM) from_m.pack(side = LEFT) from_t_m_varable = StringVar() from_t_m = Entry(animatedFrame, width=3,textvariable=from_t_m_varable) from_t_m.pack(side=BOTTOM) from_t_m.pack(side=LEFT) from_s = Label(animatedFrame, text=" : ") from_s.pack(side = BOTTOM) from_s.pack(side = LEFT) from_t_s_varable = StringVar() from_t_s = Entry(animatedFrame, width=3,textvariable=from_t_s_varable) from_t_s.pack(side=BOTTOM) from_t_s.pack(side=LEFT) to_ = Label(animatedFrame, text=" To (in second) ") to_.pack(side = BOTTOM) to_.pack(side = LEFT) to_t_s_varable = StringVar() to_t_s = Entry(animatedFrame, width=3,textvariable=to_t_s_varable) to_t_s.pack(side=BOTTOM) to_t_s.pack(side=LEFT) #trim video trim = Label(trimFrame, text="Trim Video ") trim.pack(side = TOP) trim.pack(side = LEFT) trim_from_ = Label(trimFrame, text="Start From (hour : minute : second) ") trim_from_.pack(side = BOTTOM) trim_from_.pack(side = LEFT) trim_from_t_h_varable = StringVar() trim_from_t_h = Entry(trimFrame, width=3, textvariable=trim_from_t_h_varable) trim_from_t_h.pack(side=BOTTOM) trim_from_t_h.pack(side=LEFT) trim_from_m = Label(trimFrame, text=" : ") trim_from_m.pack(side = BOTTOM) trim_from_m.pack(side = LEFT) trim_from_t_m_varable = StringVar() trim_from_t_m = Entry(trimFrame, width=3,textvariable=trim_from_t_m_varable) trim_from_t_m.pack(side=BOTTOM) trim_from_t_m.pack(side=LEFT) trim_from_s = Label(trimFrame, text=" : ") trim_from_s.pack(side = BOTTOM) trim_from_s.pack(side = LEFT) trim_from_t_s_varable = StringVar() trim_from_t_s = Entry(trimFrame, width=3,textvariable=trim_from_t_s_varable) trim_from_t_s.pack(side=BOTTOM) trim_from_t_s.pack(side=LEFT) trim_to_ = Label(trimFrame, text=" To (in second) ") trim_to_.pack(side = BOTTOM) trim_to_.pack(side = LEFT) trim_to_t_h_varable = StringVar() trim_to_t_h = Entry(trimFrame, width=3,textvariable=trim_to_t_h_varable) trim_to_t_h.pack(side=BOTTOM) trim_to_t_h.pack(side=LEFT) trim_to_m = Label(trimFrame, text=" : ") trim_to_m.pack(side = BOTTOM) trim_to_m.pack(side = LEFT) trim_to_t_m_varable = StringVar() trim_to_t_m = Entry(trimFrame, width=3,textvariable=trim_to_t_m_varable) trim_to_t_m.pack(side=BOTTOM) trim_to_t_m.pack(side=LEFT) trim_to_s = Label(trimFrame, text=" : ") trim_to_s.pack(side = BOTTOM) trim_to_s.pack(side = LEFT) trim_to_t_s_varable = StringVar() trim_to_t_s = Entry(trimFrame, width=3,textvariable=trim_to_t_s_varable) trim_to_t_s.pack(side=BOTTOM) trim_to_t_s.pack(side=LEFT) # Create a combo box vid_size = StringVar() # create a string variable preferSize = tk.Combobox(mainframe, textvariable=vid_size) preferSize['values'] = (1920, 1280, 854, 640) # video width in pixels preferSize.current(0) # select item one preferSize.pack(side = LEFT) # Create a combo box vid_format = StringVar() # create a string variable preferFormat = tk.Combobox(mainframe, textvariable=vid_format) preferFormat['values'] = ('.mp4', '.webm', '.avi', '.wmv', '.mpg', '.ogv') # video format preferFormat.current(0) # select item one preferFormat.pack(side = LEFT) removeAudioVal = IntVar() removeAudio = tk.Checkbutton(mainframe, text="Remove Audio", variable=removeAudioVal) removeAudio.pack(side = LEFT, padx=3) newAudio = IntVar() aNewAudio = tk.Checkbutton(mainframe, text="New Audio", variable=newAudio) aNewAudio.pack(side = LEFT, padx=2) count = 0 # counter uses to create multiple videos btn_text = StringVar() # button text # Open a video file def openVideo(): audiofilename = '' fullfilename = filedialog.askopenfilename(initialdir="/", title="Select a file", filetypes=[("Video file", "*.mp4; *.avi ")]) # select a video file from the hard drive if(newAudio.get() == 1): audiofilename = filedialog.askopenfilename(initialdir="/", title="Select a file", filetypes=[("Audio file", "*.wav; *.ogg ")]) # select a new audio file from the hard drive global count # access the global count variable if(fullfilename != ''): scale_vid = preferSize.get() # retrieve value from the comno box new_size = str(scale_vid) file_extension = fullfilename.split('.')[-1] # extract the video format from the original video f = '_new_vid_' + new_size + '.' + file_extension # the new output file name f2 = str(count)+f # second video f_gif = str(count) + f + '.gif' # create animated gif count += 1 # increase video counter for new video # create animated image from video animi_from_hour = from_t_h_varable.get() animi_from_minute = from_t_m_varable.get() animi_from_second = from_t_s_varable.get() animi_to_second = to_t_s_varable.get() # video editing part start here noAudio = removeAudioVal.get() # get the checkbox state for audio # trim video starting point and end point trim_from_hour = trim_from_t_h_varable.get() trim_from_minute = trim_from_t_m_varable.get() trim_from_second = trim_from_t_s_varable.get() trim_to_hour = trim_to_t_h_varable.get() trim_to_minute = trim_to_t_m_varable.get() trim_to_second = trim_to_t_s_varable.get() f3 = f + vid_format.get() # The final video format contrast_value = str(contrast_variable.get()) brightness_value = str(brightness_variable.get()) saturation_value = str(saturation_variable.get()) gamma_value = str(gamma_variable.get()) loop_value = str(loop_variable.get()) frame_rate_value = str(fr_variable.get()) try: new_vide_thread = NewVid(contrast_value, brightness_value, saturation_value, gamma_value, loop_value, frame_rate_value, new_size, noAudio, file_extension, f, f2, f3, f_gif, audiofilename, fullfilename, animi_from_hour, animi_from_minute, animi_from_second, animi_to_second, trim_from_hour, trim_from_minute, trim_from_second, trim_to_hour, trim_to_minute, trim_to_second) new_vide_thread.start() new_vide_thread.join() except: messagebox.showinfo("Error", "You need to install FFmpeg before using this program!") webbrowser.open('https://www.ffmpeg.org/') else: messagebox.showinfo("Error", "You need to select a video file!") action_vid = tk.Button(buttonFrame, command=openVideo, text="Select Video") action_vid.pack(fill=X) win.mainloop()
The second part is the thread part,
import os import subprocess import threading class NewVid(threading.Thread): def __init__(self, contrast_value, brightness_value, saturation_value, gamma_value, loop_value, frame_rate_value, new_size, noAudio, file_extension, f, f2, f3, f_gif, audiofilename, fullfilename, animi_from_hour, animi_from_minute, animi_from_second, animi_to_second, trim_from_hour, trim_from_minute, trim_from_second, trim_to_hour, trim_to_minute, trim_to_second): threading.Thread.__init__(self) self.contrast_value = contrast_value self.brightness_value = brightness_value self.saturation_value = saturation_value self.gamma_value = gamma_value self.loop_value = loop_value self.frame_rate_value = frame_rate_value self.new_size =new_size self.noAudio = noAudio self.file_extension = file_extension self.f = f self.f2 = f2 self.f3 = f3 self.f_gif = f_gif self.audiofilename = audiofilename self.fullfilename = fullfilename self.animi_from_hour = animi_from_hour self.animi_from_minute = animi_from_hour self.animi_from_second = animi_from_second self.animi_to_second = animi_to_second self.trim_from_hour = trim_from_hour self.trim_from_minute = trim_from_minute self.trim_from_second = trim_from_second self.trim_to_hour = trim_to_hour self.trim_to_minute = trim_to_minute self.trim_to_second = trim_to_second # Processing video file def run(self): dir_path = os.path.dirname(os.path.realpath(self.fullfilename)) self.trim_video = False # set the trim video flag to false os.chdir(dir_path) # change the directory to the original file's directory # if the time areas are not empty and they have a digit then only the animated gif will be created if((self.animi_from_hour != '' and self.animi_from_hour.isdigit()) and (self.animi_from_minute != '' and self.animi_from_minute.isdigit()) and (self.animi_from_second != '' and self.animi_from_second.isdigit()) and (self.animi_to_second != '' and self.animi_to_second.isdigit())): subprocess.call(['ffmpeg', '-i', self.fullfilename, '-vf', 'scale=' + self.new_size + ':-1', '-y', self.f]) # resize video subprocess.call(['ffmpeg', '-i', self.f, '-vf', 'eq=contrast=' + self.contrast_value +':brightness='+ self.brightness_value +':saturation=' + self.saturation_value +':gamma=' + self.gamma_value, '-y', self.f2]) # adjust the saturation, gamma, contrast and brightness of video subprocess.call(['ffmpeg', '-i', self.f2, '-ss', self.animi_from_hour + ':' + self.animi_from_minute + ':' + self.animi_from_second, '-t', self.animi_to_second, '-y', self.f_gif]) # creating animated gif from starting point to end point os.remove(self.f) os.remove(self.f2) return 0 # video editing part start here subprocess.call(['ffmpeg', '-stream_loop', (self.loop_value), '-i', self.fullfilename, '-vf', 'scale=' + self.new_size + ':-1', '-y', '-r', self.frame_rate_value, self.f]) # resize, speedup and loop the video with ffmpeg subprocess.call(['ffmpeg', '-i', self.f, '-vf', 'eq=contrast=' + self.contrast_value +':brightness='+ self.brightness_value +':saturation=' + self.saturation_value +':gamma=' + self.gamma_value, '-y', self.f2]) # adjust the saturation, gamma, contrast and brightness of video # if the time areas are not empty and they have a digit then trim the video if((self.trim_from_hour != '' and self.trim_from_hour.isdigit()) and (self.trim_from_minute != '' and self.trim_from_minute.isdigit()) and (self.trim_from_second != '' and self.trim_from_second.isdigit()) and (self.trim_to_second != '' and self.trim_to_second.isdigit()) and (self.trim_to_minute != '' and self.trim_to_minute.isdigit()) and (self.trim_to_hour != '' and self.trim_to_hour.isdigit())): subprocess.call(['ffmpeg', '-i', self.f2, '-ss', self.trim_from_hour + ':' + self.trim_from_minute + ':' + self.trim_from_second, '-t', self.trim_to_hour + ':' + self.trim_to_minute + ':' + self.trim_to_second, '-y', '-c:v', 'copy', '-c:a', 'copy', self.f]) # trim the video from start to end point self.trim_video = True if(self.noAudio == 1 and self.trim_video == True): subprocess.call(['ffmpeg', '-i', self.f, '-c', 'copy', '-y', '-an', self.f2]) # remove audio from the original video elif(self.noAudio == 1 and self.trim_video == False): subprocess.call(['ffmpeg', '-i', self.f2, '-c', 'copy', '-y', '-an', self.f]) # remove audio from the original video if(self.audiofilename != '' and self.noAudio == 1 and self.trim_video == False): subprocess.call(['ffmpeg', '-i', self.f, '-i', self.audiofilename, '-shortest', '-c:v', 'copy', '-b:a', '256k', '-y', self.f2]) # add audio to the original video, trim either the audio or video depends on which one is longer elif(self.audiofilename != '' and self.noAudio == 1 and self.trim_video == True): subprocess.call(['ffmpeg', '-i', self.f2, '-i', self.audiofilename, '-shortest', '-c:v', 'copy', '-b:a', '256k', '-y', self.f]) # add audio to the original video, trim either the audio or video depends on which one is longer if(self.f3.split('.')[-1] != self.f2.split('.')[-1] and self.trim_video == True and self.noAudio == 1 and self.audiofilename != ''): subprocess.call(['ffmpeg', '-i', self.f, '-y', self.f3]) # converting the video with ffmpeg os.remove(self.f2) # remove two videos os.remove(self.f) elif(self.f3.split('.')[-1] != self.f2.split('.')[-1] and self.trim_video == False and self.noAudio == 1 and self.audiofilename != ''): subprocess.call(['ffmpeg', '-i', self.f2, '-y', self.f3]) # converting the video with ffmpeg os.remove(self.f2) # remove two videos os.remove(self.f) elif(self.f3.split('.')[-1] != self.f2.split('.')[-1] and self.trim_video == False and self.noAudio != 1 and self.audiofilename == ''): subprocess.call(['ffmpeg', '-i', self.f2, '-y', self.f3]) # converting the video with ffmpeg os.remove(self.f2) # remove two videos os.remove(self.f) elif(self.f3.split('.')[-1] == self.f2.split('.')[-1] and self.trim_video == True and self.noAudio == 1 and self.audiofilename != ''): os.remove(self.f2) # remove one video elif(self.f3.split('.')[-1] == self.f2.split('.')[-1] and self.trim_video == True and self.noAudio != 1): os.remove(self.f2) # remove one video elif(self.f3.split('.')[-1] == self.f2.split('.')[-1] and self.trim_video == False and self.noAudio != 1): os.remove(self.f) # remove one video elif(self.f3.split('.')[-1] == self.f2.split('.')[-1] and self.trim_video == False and self.noAudio == 1): os.remove(self.f2) # remove one video else: os.remove(self.f) # remove one video self.trim_video = False # reset the trim video flag to false
Well, now is your turn to edit this application then use it to edit video. How about creating a progress bar which tells the user how much time he still needs to wait for the software to finish editing the video?
from Planet Python
via read more
No comments:
Post a Comment