From c2e98748764cc3fa219ecb20fd8f131af457ac3e Mon Sep 17 00:00:00 2001 From: Akash Bora <89206401+Akascape@users.noreply.github.com> Date: Sun, 4 Feb 2024 19:55:34 +0530 Subject: [PATCH] Version 2.2 - New mode: Combine - Python version issue fixed - Mode type description added - Auto playing the moshed video - Import moshed button added - auto-save settings updated - minor improvements in some functions --- .../Assets/CTkRangeSlider/__init__.py | 2 +- .../Assets/CTkRangeSlider/ctk_rangeslider.py | 24 +- Python Version/Assets/Icons/up_arrow.png | Bin 0 -> 7705 bytes .../DatamoshLib/FFG_effects/basic_modes.py | 90 +++++-- Python Version/DatamoshLib/Tomato/tomato.py | 9 +- Python Version/Datamosher Pro.py | 247 ++++++++++++++---- Python Version/Setup.py | 13 +- 7 files changed, 288 insertions(+), 97 deletions(-) create mode 100644 Python Version/Assets/Icons/up_arrow.png diff --git a/Python Version/Assets/CTkRangeSlider/__init__.py b/Python Version/Assets/CTkRangeSlider/__init__.py index e1b5bf4..c2d0b27 100644 --- a/Python Version/Assets/CTkRangeSlider/__init__.py +++ b/Python Version/Assets/CTkRangeSlider/__init__.py @@ -4,6 +4,6 @@ Range slider for customtkinter Author: Akash Bora """ -__version__ = '0.1' +__version__ = '0.3' from .ctk_rangeslider import CTkRangeSlider diff --git a/Python Version/Assets/CTkRangeSlider/ctk_rangeslider.py b/Python Version/Assets/CTkRangeSlider/ctk_rangeslider.py index 6e78202..6b170f6 100644 --- a/Python Version/Assets/CTkRangeSlider/ctk_rangeslider.py +++ b/Python Version/Assets/CTkRangeSlider/ctk_rangeslider.py @@ -2,13 +2,15 @@ CTkRangeSlider Range slider for customtkinter Author: Akash Bora -Version: 0.1 +Version: 0.2 """ +from __future__ import annotations + import math import tkinter import sys -from typing import Union, Tuple, Callable, Optional +from typing import Union, Tuple, Callable, Optional, List from customtkinter.windows.widgets.core_rendering import DrawEngine from customtkinter.windows.widgets.theme import ThemeManager @@ -533,7 +535,7 @@ class CTkRangeSlider(CTkBaseClass): """ set necessary bindings for functionality of widget, will overwrite other bindings """ if sequence is None or sequence == "": self._canvas.bind("", self._on_enter) - if sequence is None or sequnece == "": + if sequence is None or sequence == "": self._canvas.bind("", self._on_enter) if sequence is None or sequence == "": self._canvas.bind("", self._on_leave) @@ -740,7 +742,7 @@ class CTkRangeSlider(CTkBaseClass): def get(self) -> float: return self._output_values - def set(self, output_values: list[float], from_variable_callback=False): + def set(self, output_values: List[float], from_variable_callback=False): if self._from_ < self._to: output_values = [max(min(x, self._to), self._from_) for x in output_values] @@ -839,7 +841,19 @@ class CTkRangeSlider(CTkBaseClass): self._variables = None del kwargs["variables"] + + if "corner_radius" in kwargs: + self._corner_radius = kwargs.pop("corner_radius") + require_redraw = True + if "button_corner_radius" in kwargs: + self._button_corner_radius = kwargs.pop("button_corner_radius") + require_redraw = True + + if "button_length" in kwargs: + self._button_length = kwargs.pop("button_length") + require_redraw = True + super().configure(require_redraw=require_redraw, **kwargs) def cget(self, attribute_name: str) -> any: @@ -859,7 +873,7 @@ class CTkRangeSlider(CTkBaseClass): elif attribute_name == "progress_color": return self._progress_color elif attribute_name == "button_color": - return self._button_color + return self._button_color_0 elif attribute_name == "button_hover_color": return self._button_hover_color diff --git a/Python Version/Assets/Icons/up_arrow.png b/Python Version/Assets/Icons/up_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..54066f41db28c93a87649fcf416ab9bcb5086ce4 GIT binary patch literal 7705 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 literal 0 HcmV?d00001 diff --git a/Python Version/DatamoshLib/FFG_effects/basic_modes.py b/Python Version/DatamoshLib/FFG_effects/basic_modes.py index b4724cd..b27ecab 100644 --- a/Python Version/DatamoshLib/FFG_effects/basic_modes.py +++ b/Python Version/DatamoshLib/FFG_effects/basic_modes.py @@ -8,6 +8,7 @@ ffgac = os.path.join(str(DIRPATH.parent.parent),"FFglitch","ffgac") ffedit = os.path.join(str(DIRPATH.parent.parent),"FFglitch","ffedit") def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, e=0, vh=0, gop=1000, r=0, f=0): + def get_vectors(input_video): subprocess.call(f'"{ffgac}" -i "{input_video}" -an -mpv_flags +nopimb+forcemv -qscale:v 0 -g "{gop}"' + ' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True) @@ -25,7 +26,7 @@ def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, except: vectors.append([]) return vectors - + def apply_vectors(vectors, input_video, output_video, method='add'): subprocess.call(f'"{ffgac}" -i "{input_video}" -an -mpv_flags +nopimb+forcemv -qscale:v 0 -g "{gop}"' + ' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True) @@ -67,13 +68,13 @@ def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, fin = os.path.join("cache_ffg",base[:-4]+".mpg") subprocess.call(f'"{ffgac}" -i "{input_video}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -g "{gop}" -y "{fin}"', shell=True) os.mkdir(os.path.join("cache_ffg","raws")) - framelist=[] + framelist = [] subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache_ffg/raws/frames_%04d.raw', shell=True) - frames=os.listdir(os.path.join("cache_ffg","raws")) - siz=size + frames = os.listdir(os.path.join("cache_ffg","raws")) + siz = size framelist.extend(frames) - chunked_list=[] - chunk_size=siz + chunked_list = [] + chunk_size = siz for i in range(0, len(framelist), chunk_size): chunked_list.append(framelist[i:i+chunk_size]) random.shuffle(chunked_list) @@ -99,20 +100,20 @@ def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, os.mkdir("cache_ffg") base = os.path.basename(input_video) fin = os.path.join("cache_ffg",base[:-4]+".mpg") - qua='' + qua = '' subprocess.call(f'"{ffgac}" -i "{input_video}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -g "{gop}" -y "{fin}"', shell=True) os.mkdir(os.path.join("cache_ffg","raws")) - framelist=[] + framelist = [] subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache_ffg/raws/frames_%04d.raw', shell=True) - kil=e - po=s + kil = e + po = s if po==0: - po=1 + po = 1 frames=os.listdir(os.path.join("cache_ffg","raws")) for i in frames[po:(po+kil)]: os.remove(os.path.join("cache_ffg","raws",i)) frames.clear() - frames=os.listdir(os.path.join("cache_ffg","raws")) + frames = os.listdir(os.path.join("cache_ffg","raws")) framelist.extend(frames) out_data = b'' for fn in framelist: @@ -122,20 +123,67 @@ def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, fp.write(out_data) fp.close() shutil.rmtree("cache_ffg") + + def combine(output): + if os.path.isdir("cache_ffg"): + shutil.rmtree("cache_ffg") + os.mkdir("cache_ffg") + qua='' + num = 0 + frames = [] + converted = {} + for i in input_video: + if i in list(converted.keys()): + continue + base=os.path.basename(i) + num +=1 + fin=os.path.join("cache_ffg",base[:-4]+f"_{num}.mpg") + os.mkdir(os.path.join("cache_ffg",f"raws_{num}")) + + subprocess.call(f'"{ffgac}" -i "{i}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -s 1920x1080 -g "{gop}" -y "{fin}"', shell=True) + + subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache_ffg/raws_{num}/frames_%04d.raw', shell=True) + converted.update({i:os.path.join("cache_ffg",f"raws_{num}")}) + + num = 0 + for i in input_video: + num +=1 + raw_frames = os.listdir(converted[i]) + if num == 1: + n = 0 + else: + if len(raw_frames)>10: + n=5 + else: + n=1 + for frame in raw_frames[n:]: + frames.append(os.path.join(converted[i],frame)) + out_data = b'' + for fn in frames: + with open(os.path.join(fn), 'rb') as fp: + out_data += fp.read() + with open(output, 'wb') as fp: + fp.write(out_data) + fp.close() + try: + if os.path.isdir("cache_ffg"): + shutil.rmtree("cache_ffg") + except: pass + def water_bloom(output): if os.path.isdir("cache_ffg"): shutil.rmtree("cache_ffg") os.mkdir("cache_ffg") base = os.path.basename(input_video) fin = os.path.join("cache_ffg",base[:-4]+".mpg") - qua='' + qua = '' subprocess.call(f'"{ffgac}" -i "{input_video}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -g "{gop}" -y "{fin}"', shell=True) os.mkdir(os.path.join("cache_ffg","raws")) - framelist=[] + framelist = [] subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache_ffg/raws/frames_%04d.raw', shell=True) - repeat=r - po=f-1 + repeat = r + po = f-1 frames=os.listdir(os.path.join("cache_ffg","raws")) for i in frames[:po]: framelist.append(i) @@ -156,13 +204,13 @@ def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, if not frames: return [] return np.mean(np.array([x for x in frames if x != []]), axis=0).tolist() - + def fluid(frames): average_length = fluidity if average_length==1: average_length=2 return [average(frames[i + 1 - average_length: i + 1]) for i in range(len(frames))] - + def movement(frames): for frame in frames: if not frame: @@ -171,9 +219,9 @@ def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, for col in row: col[vh] = 0 return frames - + if(mode==1): - transfer_to=input_video + transfer_to = input_video vectors = [] if extract_from: vectors = get_vectors(extract_from) @@ -191,3 +239,5 @@ def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, rise(output) elif(mode==6): water_bloom(output) + elif(mode==7): + combine(output) diff --git a/Python Version/DatamoshLib/Tomato/tomato.py b/Python Version/DatamoshLib/Tomato/tomato.py index 04b919c..fe1fedd 100644 --- a/Python Version/DatamoshLib/Tomato/tomato.py +++ b/Python Version/DatamoshLib/Tomato/tomato.py @@ -4,14 +4,9 @@ import os, re, random, struct from itertools import chain from itertools import repeat def mosh(infile, outfile, m, c, n, a, f, k): - print (" _ _ ") - print ("| | | | ") - print ("| |_ ___ _ __ ___ __ _| |_ ___ ") - print ("| __/ _ \| '_ ` _ \ / _` | __/ _ \ ") - print ("| || (_) | | | | | | (_| | || (_) |") - print (" \__\___/|_| |_| |_|\__,_|\__\___/ ") + print ("Tomato Automosh v2.0") - print ("\\\\ Audio Video Interleave breaker") + print ("Audio Video Interleave breaker") print (" ") print ("glitch tool made with love for the glitch art community <3") print ("___________________________________") diff --git a/Python Version/Datamosher Pro.py b/Python Version/Datamosher Pro.py index d2b315e..fcff628 100644 --- a/Python Version/Datamosher Pro.py +++ b/Python Version/Datamosher Pro.py @@ -1,10 +1,14 @@ -#Author: Akash Bora -#License: MIT | Copyright (c) 2023 Akash Bora +""" +DATAMOSHER PRO Py version 2.2 +Author: Akash Bora (Akascape) +License: MIT | Copyright (c) 2024 Akash Bora +""" -currentversion = 2.1 +currentversion = 2.2 -#Import required modules +#Import installed modules import tkinter +from tkinter import messagebox, filedialog import customtkinter import sys import os @@ -25,7 +29,7 @@ from DatamoshLib.Tomato import tomato from DatamoshLib.Original import classic, repeat, pymodes from DatamoshLib.FFG_effects import basic_modes, external_script -#Get full base path +# get full base path def resource(relative_path): base_path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(base_path, relative_path) @@ -36,29 +40,34 @@ HEIGHT = 520 customtkinter.set_appearance_mode("System") customtkinter.set_default_color_theme(random.choice(["blue","green","dark-blue"])) + root = customtkinter.CTk() root.title("Datamosher Pro (python version)") root.geometry(f"{WIDTH}x{HEIGHT}") root.bind("<1>", lambda event: event.widget.focus_set()) root.grid_columnconfigure(1, weight=1) root.grid_rowconfigure(0, weight=1) -frame_left = customtkinter.CTkFrame(master=root,width=180,corner_radius=0) + +frame_left = customtkinter.CTkFrame(master=root, width=180, corner_radius=0) frame_left.grid(row=0, column=0, sticky="nswe") + frame_right = customtkinter.CTkFrame(master=root) frame_right.grid(row=0, column=1, sticky="nswe", padx=20, pady=20) + icopath = ImageTk.PhotoImage(file=resource(os.path.join("Assets","Icons","Program_icon.png"))) root.wm_iconbitmap() root.iconphoto(False, icopath) -#get FFMPEG path (using the imageio_ffmpeg plugin) +#Get FFMPEG path (using the imageio_ffmpeg plugin) ffmpeg = imageio_ffmpeg.get_ffmpeg_exe() #Effect List modelist = sorted(["Bloom", "Invert", "Jiggle", "Overlap", "Pulse", "Reverse", - "Random", "Classic", "Glide", "Sort", "Echo", "Void", - "Fluid", "Stretch", "Motion Transfer", "Repeat", "Shear", "Delay", "Sink", - "Mirror", "Vibrate", "Slam Zoom", "Zoom","Invert-Reverse", "Shift", - "Noise", "Stop", "Buffer", "Slice", "Shuffle", "Rise", "Custom Script", "Water Bloom"]) + "Random", "Classic", "Glide", "Sort", "Echo", "Void", + "Fluid", "Stretch", "Motion Transfer", "Repeat", "Shear", "Delay", "Sink", + "Mirror", "Vibrate", "Slam Zoom", "Zoom","Invert-Reverse", "Shift", + "Noise", "Stop", "Buffer", "Slice", "Shuffle", "Rise", "Custom Script", + "Water Bloom", "Combine"]) current = modelist[0] #Making the top widgets for changing the modes dynamically @@ -82,7 +91,8 @@ frame_info.pack(padx=10, pady=10, fill="x", anchor="n") play_icon = Image.open(resource(os.path.join("Assets","Icons","right_icon.png"))).resize((20, 20), Image.Resampling.LANCZOS) left_but = customtkinter.CTkButton(master=frame_info, image=customtkinter.CTkImage(play_icon.transpose(Image.Transpose.FLIP_LEFT_RIGHT)), - text="", width=50, height=50, corner_radius=10, fg_color=("white", "gray38"), hover_color=("gray90","gray25"), command=ChangeModeLeft) + text="", width=50, height=50, corner_radius=10, fg_color=("white", "gray38"), hover_color=("gray90","gray25"), + command=ChangeModeLeft) left_but.pack(padx=10, pady=10, fill="x", side="left", anchor="n") mode_info = customtkinter.CTkLabel(master=frame_info,text=current, corner_radius=10, width=320, height=50, fg_color=("white", "gray38")) @@ -92,13 +102,21 @@ right_but = customtkinter.CTkButton(master=frame_info, image=customtkinter.CTkIm corner_radius=10, fg_color=("white", "gray38"), hover_color=("gray90","gray25"), command=ChangeModeRight) right_but.pack(padx=10, pady=10, fill="x", side="right", anchor="n") +mode_type = customtkinter.CTkLabel(master=frame_right, text="") +mode_type.place(x=20, y=100) + #Open video function previous = "" +ofile = "" +sfile = "" -def open_function(): +def open_function(file=None): global ofile, vid_image2, previous, duration, vid - ofile = tkinter.filedialog.askopenfilename(filetypes =[('Video', ['*.mp4','*.avi','*.mov','*.mkv','*gif']),('All Files', '*.*')]) + if not file: + ofile = filedialog.askopenfilename(filetypes=[('Video', ['*.mp4','*.avi','*.mov','*.mkv','*gif']),('All Files', '*.*')]) + else: + ofile = file #Check the video type supported = ["mp4","avi","mov","gif","mkv","wmv","m4v"] @@ -133,7 +151,7 @@ def open_function(): rangebar.configure(from_=0, to=int(duration), number_of_steps=int(duration)) rangebar.set([0,duration]) label_seconds2.configure(text="End: "+str(int(duration))+"s") - rangebar2.configure(from_=1, to=vid.count_frames(),number_of_steps=vid.count_frames()) + rangebar2.configure(from_=1, to=vid.count_frames(), number_of_steps=vid.count_frames()) rangebar2.set([0,vid.count_frames()]) label_showframe2.configure(text="End: "+str(vid.count_frames())) shuf_slider.configure(to=vid.count_frames(), number_of_steps=vid.count_frames()) @@ -141,6 +159,14 @@ def open_function(): end_frame_mosh.set(vid.count_frames()) position_frame.set(1) position_frame._command(position_frame.get()) + video_tbox.insert("end", ofile+"\n\n") + +def reuse_video(): + if os.path.exists(sfile): + open_function(file=sfile) + else: + messagebox.showinfo("No Output", "The moshed file is not found") + button_reuse.place_forget() #Left Frame Widgets label_appname = customtkinter.CTkLabel(master=frame_left, text="DATAMOSHER PRO", font=("",14,"bold")) @@ -164,6 +190,11 @@ optionmenu_1 = customtkinter.CTkComboBox(master=frame_left, height=35, values=[" optionmenu_1.set("mp4") optionmenu_1.pack(padx=10, fill="x") +up_arrow_image = customtkinter.CTkImage(Image.open(resource(os.path.join("Assets","Icons","up_arrow.png"))), size=(20,15)) + +button_reuse = customtkinter.CTkButton(master=frame_left, image=up_arrow_image, text="Import Moshed", height=35, width=160, fg_color="transparent", + compound="right", command=reuse_video, border_width=2, text_color=["black", "white"]) + #Info Window def close_top(): window_UI.destroy() @@ -186,19 +217,18 @@ def view_info(): URL = "https://raw.githubusercontent.com/Akascape/Datamosher-Pro/Miscellaneous/VERSIONPY.txt" try: response = requests.get(URL) - open(resource(os.path.join("Assets","version","VERSIONPY.txt")), "wb").write(response.content) + new_version = float(response.content) except: - tkinter.messagebox.showinfo("Unable to connect!", "Unable to get information, please check your internet connection or visit the github repository.") + messagebox.showinfo("Unable to connect!", + "Unable to get information, please check your internet connection or visit the github repository.") return time.sleep(1) - with open(resource(os.path.join("Assets","version","VERSIONPY.txt")), 'r') as uf: - nver=float(uf.read()) - if nver>currentversion: - tkinter.messagebox.showinfo("New Version available!","A new version "+ str(nver) + - " is available, \nPlease visit the github repository or the original download page!") - else: - tkinter.messagebox.showinfo("No Updates!", "You are on the latest version!") + if new_version>currentversion: + messagebox.showinfo("New Version available!","A new version "+ str(new_version) + + " is available, \nPlease visit the github repository or the original download page!") + else: + messagebox.showinfo("No Updates!", "You are on the latest version!") def docs(): webbrowser.open_new_tab("https://github.com/Akascape/Datamosher-Pro/wiki") @@ -216,7 +246,7 @@ def view_info(): checkupdate = customtkinter.CTkButton(window_UI, text="Check For Updates", width=150, height=35, corner_radius=10, command=check) checkupdate.place(x=20,y=80) - helpbutton=customtkinter.CTkButton(window_UI, text="Help", width=150, height=35, corner_radius=10,command=docs) + helpbutton = customtkinter.CTkButton(window_UI, text="Help", width=150, height=35, corner_radius=10,command=docs) helpbutton.place(x=20,y=130) version_label = customtkinter.CTkLabel(window_UI,anchor="w",width=1, text="v"+str(currentversion), @@ -262,7 +292,7 @@ def change_param(): ff_setting.configure(state=tkinter.DISABLED) window_UI2.wm_transient(root) - text_box = customtkinter.CTkTextbox(window_UI2, border_width=3,height=140) + text_box = customtkinter.CTkTextbox(window_UI2, border_width=3, height=140, undo=True) text_box.pack(padx=10, pady=(10,0), fill="x") if len(param)>1: text_box.insert("0.0", param) ok_button = customtkinter.CTkButton(window_UI2, text="OK", command=set_param) @@ -291,6 +321,7 @@ widget_frame = customtkinter.CTkFrame(master=frame_right, fg_color="transparent" widget_frame.pack(padx=10, pady=(50,10), expand=True, fill="both") widget_frame.columnconfigure((0,1,2,3), weight=1) +widget_frame.rowconfigure(5, weight=1) #Kill Frame Widget @@ -313,8 +344,8 @@ keepframe = customtkinter.CTkCheckBox(master=widget_frame, text="Keep First Fram #Count Frame widget label_frame1 = customtkinter.CTkLabel(master=widget_frame,anchor='w',text="Position Frame: 1",width=1) -position_frame = customtkinter.CTkSlider(master=widget_frame, progress_color="black", fg_color="black", from_=1, to=1.1, - number_of_steps=1, command=lambda value: label_frame1.configure(text="Position Frame: "+str(int(value)))) +position_frame = customtkinter.CTkSlider(master=widget_frame, progress_color="black", fg_color="black", from_=1, to=1.1, number_of_steps=1, + command=lambda value: label_frame1.configure(text="Position Frame: "+str(int(value)))) position_frame.set(1) #Classic Rangebar @@ -377,7 +408,8 @@ end_frame_mosh.trace_add('write', show3) label_mid = customtkinter.CTkLabel(master=widget_frame,anchor='w',text="Start Point: 0.5",width=1) mid_point = customtkinter.CTkSlider(master=widget_frame, progress_color="black", fg_color="black", - from_=0, to=1, number_of_steps=10, command=lambda value: label_mid.configure(text="Start Point: "+str(round(value,1)))) + from_=0, to=1, number_of_steps=10, + command=lambda value: label_mid.configure(text="Start Point: "+str(round(value,1)))) mid_point.set(0.5) #Some options for sort mode @@ -408,7 +440,7 @@ v_h = customtkinter.CTkSwitch(widget_frame,text="Horizontal Stretch", onvalue=1, #Button for motion transfer mode def open_MT(): global vfile - vfile = tkinter.filedialog.askopenfilename(filetypes =[('Vector File', ['*.mp4','*.avi','*.mov','*.mkv']),('All Files', '*.*')]) + vfile = filedialog.askopenfilename(filetypes=[('Vector File', ['*.mp4','*.avi','*.mov','*.mkv']),('All Files', '*.*')]) if vfile: mt_button.configure(fg_color='grey', text=os.path.basename(vfile)) else: @@ -422,7 +454,7 @@ scriptfile = '' def open_script(): global scriptfile - scriptfile = tkinter.filedialog.askopenfilename(filetypes =[('Script File', ['*.js','*.py']),('All Files', '*.*')]) + scriptfile = filedialog.askopenfilename(filetypes=[('Script File', ['*.js','*.py']),('All Files', '*.*')]) if scriptfile: scriptbutton.configure(fg_color='grey', text=os.path.basename(scriptfile)) else: @@ -431,6 +463,20 @@ def open_script(): scriptbutton = customtkinter.CTkButton(master=widget_frame, text="OPEN SCRIPT", height=30, compound="right",command=open_script) +#Combine mode widgets + +def open_multiple_videos(): + files = filedialog.askopenfilenames(filetypes=[('Vector File', ['*.mp4','*.avi','*.mov','*.mkv']),('All Files', '*.*')]) + if files: + supported = ["mp4","avi","mov","gif","mkv","wmv","m4v"] + for i in files: + if i[-3:].lower() in supported: + video_tbox.insert("end", i+"\n\n") + +import_bt = customtkinter.CTkButton(master=widget_frame, text="Add Videos", fg_color="transparent", border_width=2, + command=open_multiple_videos, text_color=["black", "white"]) +video_tbox = customtkinter.CTkTextbox(master=widget_frame, undo=True) + #Dynamic UI functions for each widget def rangeslider(x): if x==1: @@ -443,6 +489,7 @@ def rangeslider(x): label_segment.grid_forget() label_seconds1.grid_forget() label_seconds2.grid_forget() + def rangeslider2(x): if x==1: if (current=="Rise"): @@ -460,6 +507,7 @@ def rangeslider2(x): label_showframe1.grid_forget() label_showframe2.grid_forget() label_segment2.grid_forget() + def mid(x): if x==1: mid_point.grid(row=1, columnspan=4, padx=10, sticky="ew") @@ -467,6 +515,7 @@ def mid(x): else: mid_point.grid_forget() label_mid.grid_forget() + def killoption(x): if x==1 or x==2 or x==3: label_kill.grid(row=0, column=0, sticky="w", padx=10) @@ -474,6 +523,7 @@ def killoption(x): else: label_kill.grid_forget() slider_kill.grid_forget() + def positionslider(x): if x==1: label_frame1.grid(row=2, column=0, sticky="w", padx=10, pady=(10,0)) @@ -481,6 +531,7 @@ def positionslider(x): else: label_frame1.grid_forget() position_frame.grid_forget() + def framekeep(x): if x==1: keepframe.grid(row=4, column=2, sticky="e", padx=10, pady=15) @@ -488,6 +539,7 @@ def framekeep(x): keepframe.grid(row=4, column=2, sticky="e", padx=10, pady=15) else: keepframe.grid_forget() + def audiokeep(x): if x==1: keepaudio.grid(row=4, column=3, sticky="e", padx=10, pady=15) @@ -495,6 +547,7 @@ def audiokeep(x): keepaudio.grid(row=4, column=3, sticky="e", padx=10, pady=15) else: keepaudio.grid_forget() + def ctimes(x): if x==1: ctime.grid(row=4, column=0, sticky="w", padx=(100,10), pady=10) @@ -506,6 +559,7 @@ def ctimes(x): else: ctime.grid_forget() label_ctime.grid_forget() + def pdelta(x): if x==1: delta.grid(row=3, column=0, sticky="w", padx=(120,10), pady=10) @@ -520,6 +574,7 @@ def pdelta(x): else: delta.grid_forget() label_p.grid_forget() + def sortoptions(x): if x==1: keepsort.grid(row=0, column=0,sticky="w", padx=10) @@ -527,6 +582,7 @@ def sortoptions(x): else: keepsort.grid_forget() reversesort.grid_forget() + def ffgassist(x): if x==1: hw_auto.grid(row=0, column=0, sticky="w", padx=10) @@ -536,6 +592,7 @@ def ffgassist(x): hw_auto.grid_forget() labelk.grid_forget() kf.grid_forget() + def shuf(x): if x==1: shuf_label.grid(row=1, column=0, sticky="w", padx=10, pady=(15,0)) @@ -543,6 +600,7 @@ def shuf(x): else: shuf_label.grid_forget() shuf_slider.grid_forget() + def fluidwidget(x): if x==1: fluid_label.grid(row=1, column=0, sticky="w", padx=10, pady=(15,0)) @@ -550,16 +608,27 @@ def fluidwidget(x): else: fluid_label.grid_forget() slider_fluid.grid_forget() + def h_v(x): if x==1: v_h.grid(sticky="w", pady=15, padx=10) else: v_h.grid_forget() + def mtwid(x): if x==1: mt_button.grid(row=1, columnspan=4, sticky="ew", padx=10, pady=20) else: mt_button.grid_forget() + +def cbwidget(x): + if x==1: + import_bt.grid(row=1, column=0, columnspan=4, sticky="we", padx=10, pady=10) + video_tbox.grid(row=5, column=0, columnspan=4, rowspan=3, sticky="news", padx=10) + else: + import_bt.grid_forget() + video_tbox.grid_forget() + def custom(x): if x==1: scriptbutton.grid(row=1, columnspan=4, sticky="ew", padx=10, pady=20) @@ -570,7 +639,10 @@ def custom(x): def dynamic(): global current, showwidgets allwidgets = [audiokeep, positionslider, killoption, framekeep, - ctimes, pdelta, rangeslider, rangeslider2, mid, sortoptions, ffgassist, fluidwidget, h_v, custom, mtwid, shuf] + ctimes, pdelta, rangeslider, rangeslider2, mid, + sortoptions, ffgassist, fluidwidget, h_v, custom, + mtwid, shuf, cbwidget] + for i in allwidgets: i(0) @@ -578,53 +650,88 @@ def dynamic(): if (current=="Bloom") or (current=="Pulse") or (current=="Pulse") or(current=="Overlap"): showwidgets=[audiokeep, positionslider, killoption, framekeep, ctimes] u=1 + mode_type.configure(text="Mode Type: Automosh (Tomato)") + elif (current=="Jiggle"): showwidgets=[positionslider, audiokeep, killoption, framekeep] u=1 + mode_type.configure(text="Mode Type: Automosh (Tomato)") + elif (current=="Void") or (current=="Reverse") or (current=="Invert") or (current=="Random"): showwidgets=[killoption,audiokeep, framekeep] u=2 + mode_type.configure(text="Mode Type: Automosh (Tomato)") + elif (current=="Classic"): showwidgets=[rangeslider, pdelta] u=1 + mode_type.configure(text="Mode Type: FFmpeg") + elif (current=="Glide"): showwidgets=[pdelta] u=2 + mode_type.configure(text="Mode Type: FFmpeg") + elif (current=="Repeat") or (current=="Rise"): if (current=="Rise"): showwidgets=[rangeslider2, ffgassist] else: showwidgets=[rangeslider2, pdelta] u=1 + mode_type.configure(text="Mode Type: FFmpeg") + elif (current=="Echo"): showwidgets=[mid] u=1 + mode_type.configure(text="Mode Type: FFmpeg") + elif (current=="Sort"): showwidgets=[sortoptions] u=1 + mode_type.configure(text="Mode Type: FFmpeg") + elif ((current=="Buffer") or (current=="Sink") or (current=="Mirror") or (current=="Shear") or (current=="Noise") or (current=="Delay") or (current=="Slam Zoom") or (current=="Invert-Reverse") or (current=="Shift") or (current=="Zoom") or (current=="Slice")or (current=="Vibrate") or (current=="Stop")): showwidgets=[ffgassist] u=1 + mode_type.configure(text="Mode Type: FFglitch") + elif (current=="Fluid"): showwidgets=[ffgassist, fluidwidget] u=1 + mode_type.configure(text="Mode Type: FFglitch") + elif (current=="Stretch"): showwidgets=[ffgassist, h_v] u=1 + mode_type.configure(text="Mode Type: FFglitch") + elif (current=="Motion Transfer"): showwidgets=[ffgassist, mtwid] u=1 + mode_type.configure(text="Mode Type: FFglitch") + elif (current=="Custom Script"): showwidgets=[ffgassist, custom] u=1 + mode_type.configure(text="Mode Type: FFglitch") + elif (current=="Shuffle"): showwidgets=[ffgassist, shuf] u=1 + mode_type.configure(text="Mode Type: FFglitch") + + elif (current=="Combine"): + showwidgets=[ffgassist, cbwidget] + u=1 + mode_type.configure(text="Mode Type: FFglitch") + elif (current=="Water Bloom"): showwidgets=[ffgassist, positionslider, ctimes] u=1 + mode_type.configure(text="Mode Type: FFglitch") + for widgets in showwidgets: widgets(u) @@ -637,11 +744,15 @@ def savename(): global sfile if ofile: try: - sfile = ofile[:-4]+"_datamoshed_"+current+'.'+optionmenu_1.get() + if str(ofile).find("_datamoshed_")>0: + extra_keyword = "_" + else: + extra_keyword = "_datamoshed_" + sfile = ofile[:-4]+extra_keyword+current+'.'+optionmenu_1.get() nf = 0 while os.path.exists(sfile): nf = nf+1 - sfile = ofile[:-4]+"_datamoshed_"+current+'('+str(nf)+')'+'.'+optionmenu_1.get() + sfile = ofile[:-4]+extra_keyword+current+'('+str(nf)+')'+'.'+optionmenu_1.get() except: sfile = "" @@ -663,7 +774,7 @@ def do_the_mosh(): global ofile, sfile, param last_used = current if previous=="": - tkinter.messagebox.showinfo("No Video imported!","Please import a video file!") + messagebox.showinfo("No Video imported!","Please import a video file!") return button_mosh.configure(state=tkinter.DISABLED) button_open.configure(state=tkinter.DISABLED) @@ -698,7 +809,8 @@ def do_the_mosh(): if current=="Classic": classic.Datamosh(ifile, mfile,s=int(start_mosh.get()),e=int(end_mosh.get()),p=int(varp.get()), fps=vid.get_meta_data()['fps']) elif current=="Repeat": - repeat.Datamosh(ifile, mfile, s=int(start_frame_mosh.get()), e=int(end_frame_mosh.get()), p=int(varp.get()), fps=vid.get_meta_data()['fps']) + repeat.Datamosh(ifile, mfile, s=int(start_frame_mosh.get()), e=int(end_frame_mosh.get()), + p=int(varp.get()), fps=vid.get_meta_data()['fps']) elif current=="Glide": pymodes.library.glide(int(varp.get()), ifile, mfile) elif current=="Sort": @@ -713,27 +825,41 @@ def do_the_mosh(): time.sleep(1) ProcessLabel.configure(text='STEP 2/3 MOSHING...') mfile = sfile[:-4]+"_corrupted.mpg" - if current=="Fluid": - basic_modes.library(ofile, mfile, mode=3, fluidity=int(slider_fluid.get()), gop=kf.get()) + if current=="Fluid": + basic_modes.library(ofile, mfile, mode=3, fluidity=int(slider_fluid.get()), gop=kf.get()) elif current=="Stretch": - basic_modes.library(ofile, mfile, mode=2, vh=v_h.get(), gop=kf.get()) + basic_modes.library(ofile, mfile, mode=2, vh=v_h.get(), gop=kf.get()) elif current=="Motion Transfer": - if vfile: - basic_modes.library(ofile, mfile, mode=1, extract_from=vfile, gop=kf.get()) - else: - tkinter.messagebox.showinfo("No Vector File imported!", "Please choose the video from where you want to extract the vector motion.") - button_mosh.configure(state=tkinter.NORMAL) - button_open.configure(state=tkinter.NORMAL) - ProcessLabel.configure(text='Choose any secondary video file for transfering the vectors!') - return + if vfile: + basic_modes.library(ofile, mfile, mode=1, extract_from=vfile, gop=kf.get()) + else: + messagebox.showinfo("No Vector File imported!", "Please choose the video from where you want to extract the vector motion.") + button_mosh.configure(state=tkinter.NORMAL) + button_open.configure(state=tkinter.NORMAL) + ProcessLabel.configure(text='Choose any secondary video file for transfering the vectors!') + return elif current=="Shuffle": - basic_modes.library(ofile, mfile, mode=4, size=int(shuf_slider.get()), gop=kf.get()) + basic_modes.library(ofile, mfile, mode=4, size=int(shuf_slider.get()), gop=kf.get()) elif current=="Rise": - basic_modes.library(ofile, mfile, mode=5, s=int(start_frame_mosh.get()), e=int(end_frame_mosh.get()-start_frame_mosh.get()), gop=kf.get()) + basic_modes.library(ofile, mfile, mode=5, s=int(start_frame_mosh.get()), + e=int(end_frame_mosh.get()-start_frame_mosh.get()), gop=kf.get()) elif current=="Water Bloom": - basic_modes.library(ofile, mfile, mode=6, f=int(position_frame.get()), r=int(varn.get()), gop=kf.get()) + basic_modes.library(ofile, mfile, mode=6, f=int(position_frame.get()), r=int(varn.get()), gop=kf.get()) + elif current=="Combine": + all_files = video_tbox.get('1.0', 'end').split('\n') + real_files = [] + for i in all_files: + if os.path.isfile(i): + real_files.append(i) + if len(real_files)<=1: + messagebox.showinfo("No files added", "Please import 2 or more videos to use combine mode!") + button_mosh.configure(state=tkinter.NORMAL) + button_open.configure(state=tkinter.NORMAL) + ProcessLabel.configure(text='Add 2 or more videos in combine mode!') + return + basic_modes.library(real_files, mfile, mode=7, gop=kf.get()) elif current=="Custom Script": - external_script.mosh(ofile, mfile, mode=1, scriptfile=scriptfile, gop=kf.get()) + external_script.mosh(ofile, mfile, mode=1, scriptfile=scriptfile, gop=kf.get()) else: external_script.mosh(ofile, mfile, mode=2, effect=current, gop=kf.get()) ProcessLabel.configure(text='STEP 3/3 FIXING THE CORRUPTED FILE...') @@ -745,25 +871,30 @@ def do_the_mosh(): os.remove(mfile) if not changed: param="" - except Exception as e: - warnings.warn(str(e)) + except Exception as errors: + warnings.warn(str(errors)) #Check the result and complete the task if os.path.exists(sfile): - tkinter.messagebox.showinfo("Exported!", "File exported successfully, \nFile Location:" +str(sfile)) + messagebox.showinfo("Exported!", "File exported successfully, \nFile Location: " +str(sfile)) ProcessLabel.configure(text="Last used: "+last_used) + try: os.startfile(sfile) + except: pass else: - tkinter.messagebox.showerror("Oops!", "Something went wrong! \nPlease recheck the settings and try again.") + messagebox.showerror("Oops!", "Something went wrong! \nPlease recheck the settings and try again.") ProcessLabel.configure(text='Recheck the settings and try again!') button_open.configure(state=tkinter.NORMAL) button_mosh.configure(state=tkinter.NORMAL) - + button_reuse.place(x=10, y=290) + #Bottom Widgets -ProcessLabel = customtkinter.CTkLabel(master=frame_right, width=400, height=30,corner_radius=10, text="START DATAMOSHING!", fg_color=("white", "gray38")) +ProcessLabel = customtkinter.CTkLabel(master=frame_right, width=400, height=30,corner_radius=10, + text="START DATAMOSHING!", fg_color=("white", "gray38")) ProcessLabel.pack(padx=10, pady=10, fill="x", expand=True, side="left") -button_mosh = customtkinter.CTkButton(master=frame_right, height=30,width=110,corner_radius=10, text="MOSH", command=Threadthis) +button_mosh = customtkinter.CTkButton(master=frame_right, height=30,width=110,corner_radius=10, + text="MOSH", command=Threadthis) button_mosh.pack(padx=(0,10), pady=10, fill="x", side="right") root.mainloop() diff --git a/Python Version/Setup.py b/Python Version/Setup.py index 48e602a..55d5cd6 100644 --- a/Python Version/Setup.py +++ b/Python Version/Setup.py @@ -8,6 +8,7 @@ import time import os from zipfile import ZipFile +print("Datamosher Pro Python Setup") try: import pkg_resources except ImportError: @@ -20,17 +21,17 @@ except ImportError: DIRPATH = os.path.dirname(os.path.realpath(__file__)) #Checking the required folders -folders= ["Assets","FFglitch","DatamoshLib","pymosh"] +folders = ["Assets","FFglitch","DatamoshLib","pymosh"] missingfolder=[] for i in folders: if not os.path.exists(i): missingfolder.append(i) if missingfolder: - print("These folder(s) not available: "+str(missingfolder)) + print("These folders are not available: "+str(missingfolder)) print("Download them from the repository properly") sys.exit() else: - print("All folders available!") + print("All required folders available!") #Checking required modules required = {'imageio', 'imageio-ffmpeg', 'numpy', 'customtkinter', 'pillow', 'requests', 'packaging'} @@ -114,8 +115,8 @@ else: except: print("Unable to download ffglitch from site, try again running this setup!") print("Check your connection or download it manually from: | https://github.com/Akascape/FFglitch-0.9.3-executables |") - print("Paste the files (ffgac and ffedit) inside FFglitch folder.") - time.sleep(3) + print("Then paste the files (ffgac and ffedit) inside FFglitch folder.") + time.sleep(5) sys.exit() time.sleep(1) print("Exctracting the files...") @@ -123,7 +124,7 @@ else: with ZipFile(os.path.join('FFglitch','ffglitch.zip'), 'r') as zip: zip.extractall('FFglitch/') except: - print("Failed to extract ffglitch.zip, please extract it manually in the FFglitch folder.") + print("Failed to extract ffglitch.zip, please extract it manually inside the FFglitch folder.") time.sleep(3) sys.exit() if os.path.exists(os.path.join("FFglitch","ffgac")) or os.path.exists(os.path.join("FFglitch","ffgac.exe")):