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.
145 lines
3.6 KiB
145 lines
3.6 KiB
#!/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()
|
|
|