You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
3.6 KiB
146 lines
3.6 KiB
4 years ago
|
#!/usr/bin/python3
|
||
|
|
||
|
from tkinter import *
|
||
|
from tkinter.filedialog import askopenfilename
|
||
|
from datetime import datetime
|
||
|
import re
|
||
|
import os
|
||
|
import sys
|
||
|
|
||
|
# see man (1)ffmpeg-utils
|
||
|
# Time must be in format [-][<HH>:]<MM>:<SS>[.<m>...]
|
||
|
# or just a decimal number of seconds
|
||
|
timestamp_matcher = re.compile('((^([0-9]{1,2}:){1,2}([0-9]{1,2})(\\.[0-9]{1,8})?$)|(^([0-9]+(\\.[0-9]+)*$)))')
|
||
|
match_seconds = re.compile('[0-9]+(\\.[0-9]+)*$')
|
||
|
window = Tk()
|
||
|
window.title("Clip Video")
|
||
|
|
||
|
use_copy = IntVar() # whether to use copy filter
|
||
|
# should probably have a dialog to explain this
|
||
|
|
||
|
filetext = Entry(window)
|
||
|
outtext = Entry(window)
|
||
|
|
||
|
def write_message(msgtext:str):
|
||
|
message.configure(text = msgtext)
|
||
|
|
||
|
|
||
|
def get_time(text):
|
||
|
fmt = ""
|
||
|
if "." in text:
|
||
|
fmt = ".%f"
|
||
|
s_end = text.split(":")
|
||
|
if len(s_end) == 2:
|
||
|
return datetime.strptime(text, "%M:%S" + fmt)
|
||
|
if len(s_end) == 3:
|
||
|
return datetime.strptime(text, "%H:%M:%S" + fmt)
|
||
|
else:
|
||
|
write_message("wot")
|
||
|
raise Exception()
|
||
|
|
||
|
def clicked():
|
||
|
# TODO:
|
||
|
# Use Exiftool / FFmpeg to get metadata to check duration
|
||
|
|
||
|
start = sttext.get()
|
||
|
end = edtext.get()
|
||
|
infile = filetext.get()
|
||
|
outfile = outtext.get()
|
||
|
if (infile == ""):
|
||
|
write_message("File not specified")
|
||
|
return
|
||
|
|
||
|
if outfile == "":
|
||
|
splitp = os.path.split(infile)[1].split(".")
|
||
|
splitp.insert(-1,"clipped")
|
||
|
outfile = ".".join(splitp)
|
||
|
|
||
|
outfile = os.path.join(os.path.split(infile)[0] , outfile)
|
||
|
|
||
|
if not timestamp_matcher.match(start) or not timestamp_matcher.match(end):
|
||
|
write_message("Start and End must\nbe in mm:ss format")
|
||
|
return
|
||
|
else:
|
||
|
write_message("")
|
||
|
if not os.path.exists(filetext.get()):
|
||
|
write_message("File doesn't exist?")
|
||
|
return
|
||
|
|
||
|
print(use_copy)
|
||
|
command = "ffmpeg "
|
||
|
if (use_copy.get() == 1):
|
||
|
command += " -c copy "
|
||
|
|
||
|
|
||
|
delta = get_time(end) - get_time(start)
|
||
|
if (delta.total_seconds() < 0):
|
||
|
write_message("Start is after end")
|
||
|
return
|
||
|
|
||
|
dur = str(delta)
|
||
|
command += f" -i \"{infile}\" -ss {start} -t {dur} \"{outfile}\""
|
||
|
print(command)
|
||
|
result = os.system(command)
|
||
|
write_message("Converting")
|
||
|
if (result != 0):
|
||
|
write_message("Failed")
|
||
|
else:
|
||
|
write_message("Success!")
|
||
|
|
||
|
def get_file():
|
||
|
filename = askopenfilename()
|
||
|
if len(filename) != 0:
|
||
|
filetext.delete(0,END)
|
||
|
filetext.insert(0, string=filename)
|
||
|
|
||
|
|
||
|
if len(sys.argv) > 1:
|
||
|
filetext.insert(0, sys.argv[1])
|
||
|
|
||
|
|
||
|
filebtn = Button(window, text="Choose File", command=get_file)
|
||
|
filebtn.grid(row=0, column=4)
|
||
|
|
||
|
st = Label(window, text="Start Timestamp")
|
||
|
ed = Label(window, text="End Timestamp")
|
||
|
|
||
|
copyq = Checkbutton(window,text="Don't re-encode",variable=use_copy)
|
||
|
|
||
|
outfileinstr = Label(window, text="Output file (same directory as input)", anchor="w")
|
||
|
|
||
|
sttext = Entry(window,width=10)
|
||
|
edtext = Entry(window,width=10)
|
||
|
|
||
|
message = Label(window, text="", anchor="w", fg='red')
|
||
|
|
||
|
btn = Button(window, text="Submit", command=clicked)
|
||
|
|
||
|
filetext.grid(column=0, row=0, columnspan=3, sticky=W+E+N+S)
|
||
|
outfileinstr.grid(column=0, row=4, columnspan=3, sticky=W+E+N+S)
|
||
|
outtext.grid(column=0, row=5, columnspan=3, sticky=W+E+N+S)
|
||
|
|
||
|
st.grid(column=0, row=1, sticky=W)
|
||
|
ed.grid(column=0, row=2, sticky=W)
|
||
|
|
||
|
message.grid(column=0, row=6)
|
||
|
btn.grid(column=4, row=5, sticky=W+E+N+S)
|
||
|
|
||
|
copyq.grid(column=0,row=3)
|
||
|
|
||
|
sttext.grid(column=1, row=1)
|
||
|
edtext.grid(column=1, row=2)
|
||
|
|
||
|
def keypress(e):
|
||
|
if e.keycode == 36:
|
||
|
clicked()
|
||
|
if e.keycode == 9:
|
||
|
window.quit()
|
||
|
|
||
|
window.bind("<Key>", keypress)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
window.mainloop()
|