Thursday, January 24, 2019

codingdirectional: The final user interface of this video editing application

Sorry for not posting anything yesterday as I had suffered from the flu and today although I still feel a little bit tired and sick I need to at least post a post on this site. After a day of hard work I have finally finished to tidy up the user interface of this video editing application. I wish there is no bug in the logic part of this revised program. If you find any bug in the below program do let me know about it.

from tkinter import *
from tkinter import filedialog
import os
import subprocess
import tkinter.ttk as tk

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_h_varable = StringVar()
#to_t_h = Entry(animatedFrame, width=3,textvariable=to_t_h_varable)
#to_t_h.pack(side=BOTTOM)
#to_t_h.pack(side=LEFT)
#to_m = Label(animatedFrame, text=" : ")
#to_m.pack(side = BOTTOM)
#to_m.pack(side = LEFT)
#to_t_m_varable = StringVar()
#to_t_m = Entry(animatedFrame, width=3,textvariable=to_t_m_varable)
#to_t_m.pack(side=BOTTOM)
#to_t_m.pack(side=LEFT)
#to_s = Label(animatedFrame, text=" : ")
#to_s.pack(side = BOTTOM)
#to_s.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

# Open a video file
def openVideo():
        
        fullfilename = filedialog.askopenfilename(initialdir="/", title="Select a file", filetypes=[("Video file", "*.mp4; *.avi ")]) # select a video file from the hard drive
        audiofilename = ''
         
        if(fullfilename != ''): 

                global count # access the global count variable
                scale_vid = preferSize.get() # retrieve value from the comno box
                new_size = str(scale_vid)
                dir_path = os.path.dirname(os.path.realpath(fullfilename))

                trim_video = False # set the trim video flag to false

                file_extension = fullfilename.split('.')[-1] # extract the video format from the original video

                os.chdir(dir_path) # change the directory to the original file's directory

                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_hour = to_t_h_varable.get()
                #animi_to_minute = to_t_m_varable.get()
                animi_to_second = to_t_s_varable.get()

                # if the time areas are not empty and they have a digit then only the animated gif will be created 
                if((animi_from_hour != '' and animi_from_hour.isdigit()) and (animi_from_minute != '' and animi_from_minute.isdigit()) and (animi_from_second != '' and animi_from_second.isdigit()) and (animi_to_second != '' and animi_to_second.isdigit())):
                        subprocess.call(['ffmpeg', '-i', fullfilename, '-vf', 'scale=' + new_size + ':-1', '-y', f]) # resize video
                        subprocess.call(['ffmpeg', '-i', f, '-vf', 'eq=contrast=' + str(contrast_variable.get()) +':brightness='+ str(brightness_variable.get()) +':saturation=' + str(saturation_variable.get()) +':gamma='+ str(gamma_variable.get()), '-y', f2]) # adjust the saturation, gamma, contrast and brightness of video
                        subprocess.call(['ffmpeg', '-i', f2, '-ss', animi_from_hour + ':' + animi_from_minute + ':' + animi_from_second, '-t',  animi_to_second, '-y', f_gif]) # creating animated gif from starting point to end point
                        os.remove(f)
                        os.remove(f2)
                        return 0

                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
           
                # video editing part start here
                noAudio = removeAudioVal.get() # get the checkbox state for audio 

                subprocess.call(['ffmpeg', '-stream_loop', str(loop_variable.get()), '-i', fullfilename, '-vf', 'scale=' + new_size + ':-1', '-y', '-r', str(fr_variable.get()), f]) # resize, speedup and loop the video with ffmpeg
                subprocess.call(['ffmpeg', '-i', f, '-vf', 'eq=contrast=' + str(contrast_variable.get()) +':brightness='+ str(brightness_variable.get()) +':saturation=' + str(saturation_variable.get()) +':gamma='+ str(gamma_variable.get()), '-y', f2]) # adjust the saturation, gamma, contrast and brightness of video

                # 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()

                # if the time areas are not empty and they have a digit then trim the video 
                if((trim_from_hour != '' and trim_from_hour.isdigit()) and (trim_from_minute != '' and trim_from_minute.isdigit()) and (trim_from_second != '' and trim_from_second.isdigit()) and (trim_to_second != '' and trim_to_second.isdigit()) and (trim_to_minute != '' and trim_to_minute.isdigit()) and (trim_to_hour != '' and trim_to_hour.isdigit())):
                        subprocess.call(['ffmpeg', '-i', f2, '-ss', trim_from_hour + ':' + trim_from_minute + ':' + trim_from_second, '-t',  trim_to_hour + ':' + trim_to_minute + ':' + trim_to_second, '-y', '-c:v', 'copy', '-c:a', 'copy', f]) # trim the video from start to end point
                        trim_video = True

                if(noAudio == 1 and trim_video == True):
                        subprocess.call(['ffmpeg', '-i', f, '-c', 'copy', '-y', '-an', f2]) # remove audio from the original video
                        
                elif(noAudio == 1 and trim_video == False):
                        subprocess.call(['ffmpeg', '-i', f2, '-c', 'copy', '-y', '-an', f]) # remove audio from the original video
               
                if(audiofilename != '' and noAudio == 1 and newAudio.get() == 1 and trim_video == False):
                        subprocess.call(['ffmpeg', '-i', f, '-i', audiofilename, '-shortest', '-c:v', 'copy', '-b:a', '256k', '-y', f2]) # add audio to the original video, trim either the audio or video depends on which one is longer
                elif(audiofilename != '' and noAudio == 1 and newAudio.get() == 1 and trim_video == True):
                        subprocess.call(['ffmpeg', '-i', f2, '-i', audiofilename, '-shortest', '-c:v', 'copy',  '-b:a', '256k', '-y', f]) # add audio to the original video, trim either the audio or video depends on which one is longer

                f3 = f + vid_format.get() # The final video format

                if(f3.split('.')[-1] != f2.split('.')[-1] and trim_video == True and noAudio == 1 and newAudio.get() == 1 and audiofilename != ''):
                        subprocess.call(['ffmpeg', '-i', f, '-y', f3]) # converting the video with ffmpeg
                        os.remove(f2) # remove two videos
                        os.remove(f)
                elif(f3.split('.')[-1] != f2.split('.')[-1] and trim_video == False and noAudio == 1 and newAudio.get() == 1 and audiofilename != ''):
                        subprocess.call(['ffmpeg', '-i', f2, '-y', f3]) # converting the video with ffmpeg
                        os.remove(f2) # remove two videos
                        os.remove(f)
                elif(f3.split('.')[-1] != f2.split('.')[-1] and trim_video == False and noAudio != 1 and newAudio.get() != 1 and audiofilename == ''):
                        subprocess.call(['ffmpeg', '-i', f2, '-y', f3]) # converting the video with ffmpeg
                        os.remove(f2) # remove two videos
                        os.remove(f)
                elif(f3.split('.')[-1] == f2.split('.')[-1] and trim_video == True and noAudio == 1 and audiofilename != ''):
                        os.remove(f2) # remove one video
                elif(f3.split('.')[-1] == f2.split('.')[-1] and trim_video == True and noAudio != 1):
                        os.remove(f2) # remove one video
                elif(f3.split('.')[-1] == f2.split('.')[-1] and trim_video == False and noAudio != 1):
                        os.remove(f) # remove one video
                elif(f3.split('.')[-1] == f2.split('.')[-1] and trim_video == False and noAudio == 1):
                        os.remove(f2) # remove one video
                else:
                        os.remove(f) # remove one video

                trim_video = False # reset the trim video flag to false
                
action_vid = tk.Button(buttonFrame, text="Open Video", command=openVideo)
action_vid.pack(fill=X)

win.mainloop()

The above program has included these two features, 1) Allows the user to trim the video from one point to another. 2) Includes the equalizer feature for the image as well as video. Below is one of the animated image which has been created with the above program.

We have one more thing needs to deal with which is the thread issue then we will be able to enjoy this application online together!



from Planet Python
via read more

No comments:

Post a Comment

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...