<reponame>Akascape/Datamosher-Pro<filename>Python Version/Datamosher-Pro.py
import os
from tkinter import *
from tkinter import ttk, messagebox, filedialog
import tkinter
import sys
import random
import re
import struct
import time
import webbrowser
from itertools import chain, repeat, islice
import subprocess
import pkg_resources
import json
import shutil
#Note that this program is optimised for only windows, for other systems you may have to adjust some parameters
required = {'imageio', 'imageio-ffmpeg', 'numpy'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed
missingset=[*missing,]
if missing:
    res=messagebox.askquestion("Module Error","Some modules are not installed \nDo you want to download and install them?")
    if res=="yes":
        try:
            for x in range(len(missingset)):
                y=missingset[x]
                subprocess.Popen('python -m pip install '+y, shell=True)
            messagebox.showinfo("Installing modules...","Modules are being installed...\nPlease restart the program once its done! \n(Make sure you are connected to internet)")
        except:
            messagebox.showerror("Error downloading modules","Please download the neccessary modules separately! \nRequired: Imageio, Imageio-ffmpeg, Numpy")
            sys.exit()
    elif res=="no":
        messagebox.showerror("Error","Required modules not available!\nWithout the modules you can't use this program. Please install them first! \nRequired: Imageio, Imageio-ffmpeg, Numpy")
        sys.exit()
    sys.exit()
else:
    import imageio
    import imageio_ffmpeg
    import numpy as np
if os.path.isdir("pymosh") and os.path.isdir("ffglitch") and os.path.isdir("Assets"):
    from pymosh import Index
    from pymosh.codec.mpeg4 import is_iframe
else:
    messagebox.showerror("Missing Folder!","Some folder(s) are not available! Please download it from our github page.")
    sys.exit()
def resource_path0(relative_path):
    base_path = getattr(
        sys,
        '_MEIPASS',
        os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, relative_path)
global resource, ffgac, ffedit
ffdir=os.path.dirname(imageio_ffmpeg.__file__).replace(os.sep, '/')+"/binaries/"
fileff=''.join([idx for idx in os.listdir(ffdir) if idx[0].lower()=='f'.lower()])
resource=resource_path0(ffdir+fileff)
ffgac=resource_path0("ffglitch/ffgac")
ffedit=resource_path0("ffglitch/ffedit")
def openfile():
    global file
    file=tkinter.filedialog.askopenfilename(filetypes =[('Video', ['*.mp4','*.avi','*.mov','*.mkv','*wmv','*gif']),('All Files', '*.*')])
    if(len(file)>1):
        LocationError.config(text=file, fg="green")
        if (len(file)>80):
            LocationError.config(text=file[:77]+"...", fg="green")
        OpeningFile['text']='Open Again'
        OpeningFile['bg']='#D0CECE'
    else:
        LocationError.config(text="Choose Video To Datamosh", fg="red")
        OpeningFile['text']="OPEN"
        OpeningFile['bg']='#82CC6C'
def datafile():
    global vecfile
    vecfile=tkinter.filedialog.askopenfilename(filetypes =[('Video', ['*.mp4','*.avi','*.mov','*.mkv','*wmv','*gif']),('All Files', '*.*')])
    if(len(vecfile)>1):
        Opening_vector['text']='Open Again'
        Opening_vector['bg']='#D0CECE'
    else:
        Opening_vector['text']="OPEN"
        Opening_vector['bg']='#82CC6C'
def convertffmpeg(inputpath):
    Wait.config(text="Converting the Video...", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
    root.update()
    fps=30
    targetformat='.avi'
    outputpath=os.path.splitext(inputpath)[0]+'_datamoshed'+targetformat
    if var5.get()==1:
        subprocess.call(f'"{resource}" -loglevel error -y -i "{inputpath}" -crf 0 -bf 0 -b 10000k -r {fps} "{outputpath}"', shell=True)
    else:
        subprocess.call(f'"{resource}" -loglevel error -y -i "{inputpath}" -crf 0 -bf 0 -r {fps} "{outputpath}"', shell=True)
    try:
        choice=modechoices.get()
        if (choice==modes[16]):
            Wait.config(text="Applying Effect: Repeat", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            repeat(outputpath,inputpath)
        else:
            Wait.config(text="Applying Effect: Classic", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            Datamoshclassic(outputpath,inputpath)
    except:
        messagebox.showerror("FAILED","The video file or the input data have \n some issues!")
        os.remove(outputpath)
        end()
def convert(inputpath,targetformat):
    global outputpath, highest
    try:
        Wait.config(text="Converting the Video...", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        outputpath=os.path.splitext(inputpath)[0]+'_datamoshed'+targetformat
        x=os.path.splitext(file)[1]
        choice = modechoices.get()
        if ((x==".gif") or (choice==modes[17]) or (choice==modes[18])or (choice==modes[19])
        or (choice==modes[20]) or (choice==modes[21]) or (choice==modes[22]) or (choice==modes[23])
        or (choice==modes[24]) or (choice==modes[25]) or (choice==modes[26]) or (choice==modes[27])
        or (choice==modes[28]) or (choice==modes[29])):
            highest="no"
        else:
            pass
        if highest=="yes":
            reader=imageio.get_reader(inputpath)
            fps=reader.get_meta_data()['fps']
            writer= imageio.get_writer(outputpath, fps=fps)
            for frames in reader:
                writer.append_data(frames)
            writer.close()
            if var5.get()==1:
                highest="yes"
            else:
                highest="no"
        elif highest=="no":
            if ((choice==modes[17]) or (choice==modes[18]) or (choice==modes[19]) or
            (choice==modes[20]) or (choice==modes[21]) or (choice==modes[22]) or
            (choice==modes[23]) or (choice==modes[24]) or (choice==modes[25]) or
            (choice==modes[26]) or (choice==modes[27]) or (choice==modes[28]) or
            (choice==modes[29])):
                if targetformat==".gif":
                    subprocess.call(f'"{resource}" -i "{inputpath}" "{outputpath}"', shell=True)
                else:   
                    subprocess.call(f'"{resource}" -hwaccel auto -i "{inputpath}" -c:v libx264 -preset medium -b:v 2M -minrate 2M -maxrate 2M -bufsize 2M -y "{outputpath}"', shell=True)
            else:
                subprocess.call(f'"{resource}" -loglevel error -y -i "{inputpath}" "{outputpath}"', shell=True)
        try:
            Datamosh(outputpath)
        except:
            pass   
    except:
        choice = modechoices.get()
        if (choice==modes[30]):
            messagebox.showerror("FAILED","The kill value is invalid for this video so it failed to convert!")
        else:
            messagebox.showerror("FAILED","The video file or the input data have \n some issues!")
        os.remove(outputpath)
        end()
def validate():
    try:
        choice = modechoices.get()
        float(Countframe.get())
        float(Positframe.get())
        float(firstframes.get())
        float(killframe.get())
        x=float(killframe.get())
        if ((choice==modes[30]) or (choice==modes[31])):
            pass
        elif x>1:
            var4.set(1)
    except ValueError:
        messagebox.showerror("Invalid Input","Please enter some valid values")
        sys.exit()
def checkexist(file):
    mode = modechoices.get()
    tformat=exportbox.get()
    f=os.path.splitext(file)[0]
    exfile=f+"_datamoshed"+"-"+mode+"_datamoshed."+tformat
    if os.path.exists(exfile):
        warn=messagebox.askquestion("Warning","Do you want to replace the old file?")
        if warn=='yes':
            os.remove(exfile)
        elif warn=='no':
            os.kill(checkesist())
    pass
def end():
    datamoshbtn['state']=NORMAL
    modechoices['state']="readonly"
    exportbox['state']="readonly"
    OpeningFile['state']=NORMAL
    Highbox['state']=NORMAL
    advancedbox['state']=NORMAL
    Opening_vector['state']=NORMAL
    root.config(cursor="")
    Wait.config(text=" ", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
    root.update()  
def Step1():
    try:
        if (OpeningFile['text']=='Open Again'):
            Wait.place(relx=0.5,rely=0.85,anchor='center')
            root.update()
            datamoshbtn['state']=DISABLED
            modechoices['state']=DISABLED
            exportbox['state']=DISABLED
            OpeningFile['state']=DISABLED
            Highbox['state']=DISABLED
            advancedbox['state']=DISABLED
            Opening_vector['state']=DISABLED
            extension=os.path.splitext(file)[1]
            validate()
            checkexist(file)
            root.config(cursor="")
            choice = modechoices.get()
            if(choice==modes[7]) or (choice==modes[16]):         
                    if extension==".mp4":
                        convertffmpeg(file)
                    else:
                        targetformat=".mp4"
                        convert(file,targetformat)
                        convertffmpeg(file)
            elif(choice==modes[8]) or (choice==modes[9]) or (choice==modes[11]):
                    pymosh_library(file)
            elif((choice==modes[13]) or (choice==modes[14]) or (choice==modes[15]) or (choice==modes[17])
            or (choice==modes[18]) or (choice==modes[19]) or (choice==modes[20]) or (choice==modes[21])
            or (choice==modes[22]) or (choice==modes[23]) or (choice==modes[24]) or (choice==modes[25])
            or (choice==modes[26]) or (choice==modes[27]) or (choice==modes[28]) or (choice==modes[29])
            or (choice==modes[30]) or (choice==modes[31])) :
                    if (choice==modes[15]):
                        if (Opening_vector['text']=='Open Again'):
                            wrong.place_forget()
                            pass
                        elif (Opening_vector['text']=="OPEN"):
                            wrong.place(x=250,y=235)
                            os.kill(Step1)
                    ffglitch_library(file)
            else:
                targetformat=".avi"
                convert(file,targetformat)
        else:
            os.kill(Step1)
    except:
        messagebox.showerror("","Please choose the video file again!")
        end()
def get_vectors(input_video):
    subprocess.call(f'"{ffgac}" -i "{input_video}" -an -mpv_flags +nopimb+forcemv -qscale:v 0 -g 1000' +
                    ' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True)
    subprocess.call(f'"{ffedit}" -i tmp.mpg -f mv:0 -e tmp.json', shell=True)
    os.remove('tmp.mpg')
    f = open('tmp.json', 'r')
    raw_data = json.load(f)
    f.close()
    os.remove('tmp.json')
    frames = raw_data['streams'][0]['frames']
    vectors = []
    for frame in frames:
        try:
            vectors.append(frame['mv']['forward'])
        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 1000' +
                    ' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True)
    to_add = '+' if method == 'add' else ''
    script_path = 'apply_vectors.js'
    script_contents = '''
    var vectors = [];
    var n_frames = 0;
    function glitch_frame(frame) {
        let fwd_mvs = frame["mv"]["forward"];
        if (!fwd_mvs || !vectors[n_frames]) {
            n_frames++;
            return;
        }
        for ( let i = 0; i < fwd_mvs.length; i++ ) {
            let row = fwd_mvs[i];
            for ( let j = 0; j < row.length; j++ ) {
                let mv = row[j];
                try {
                    mv[0] ''' + to_add + '''= vectors[n_frames][i][j][0];
                    mv[1] ''' + to_add + '''= vectors[n_frames][i][j][1];
                } catch {}
            }
        }
        n_frames++;
    }
    '''
    with open(script_path, 'w') as f:
        f.write(script_contents.replace('var vectors = [];', f'var vectors = {json.dumps(vectors)};'))
    subprocess.call(f'"{ffedit}" -i tmp.mpg -f mv -s "{script_path}" -o "{output_video}"', shell=True)
    os.remove('apply_vectors.js')
    os.remove('tmp.mpg')
def shuffle(output_video):
    siz=int(Countframe.get())
    kil=float(killframe.get())
    if os.path.isdir("cache"):
        shutil.rmtree("cache")
    os.mkdir("cache")
    base=os.path.basename(file)
    fin="cache/"+base[:-4]+".mpg"
    subprocess.call(f'"{ffgac}" -i "{file}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -g 90 -s 1280x720 -y "{fin}"', shell=True)
    os.mkdir("cache/raws")
    framelist=[]
    subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache/raws/frames_%04d.raw', shell=True)
    frames=os.listdir("cache/raws")
    if kil<=1:
        kil=1
    else:
        if kil>30:
            var4.set(30)
            kil=30.0
        kil=int(kil)
    x=random.sample(frames,kil)      
    for i in x:
        os.remove("cache/raws/"+i)
    frames.clear()
    frames=os.listdir("cache/raws")
    if siz>=(len(frames)):
        siz=(len(frames))
    framelist.extend(frames)
    if siz>=1:
        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)
        framelist.clear()
        for i in chunked_list:
            for j in i:
                framelist.append(j)
    out_data = b''
    for fn in framelist:
       with open("cache/raws/"+fn, 'rb') as fp:
           out_data += fp.read()
    with open(output_video, 'wb') as fp:
          fp.write(out_data)
          fp.close()
    shutil.rmtree("cache")
def rise(output):
    if os.path.isdir("cache"):
        shutil.rmtree("cache")
    os.mkdir("cache")
    base=os.path.basename(file)
    fin="cache/"+base[:-4]+".mpg"
    if var5.get()==1:
        qua='1920x1080'
    else:
        qua="1280x720"
    subprocess.call(f'"{ffgac}" -i "{file}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -g 90 -s "{qua}" -y "{fin}"', shell=True)
    os.mkdir("cache/raws")
    framelist=[]
    subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache/raws/frames_%04d.raw', shell=True)
    kil=float(killframe.get())
    frames=os.listdir("cache/raws")
    if kil<=1:
        kil=10
    else:
        if kil>=(len(frames)):
            kil=len(frames)/2
        kil=int(kil)
    po=int(firstframes.get())
    if po>=(len(frames)):
        po=len(frames)-3
    frames.clear()
    frames=os.listdir("cache/raws")  
    for i in frames[po:(po+kil)]:
        os.remove("cache/raws/"+i)
    frames=os.listdir("cache/raws")
    framelist.extend(frames)
    out_data = b''
    for fn in framelist:
       with open("cache/raws/"+fn, 'rb') as fp:
           out_data += fp.read()
    with open(output, 'wb') as fp:
          fp.write(out_data)
          fp.close()
    shutil.rmtree("cache")
def average(frames):
    if not frames:
        return []
    return np.mean(np.array([x for x in frames if x != []]), axis=0).tolist()
def fluid(frames):
    average_length = int(Positframe.get())
    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:
            continue
        for row in frame:
            for col in row:
                col[0] = 0
    return frames
def external_scripts(output_video):
    choice = modechoices.get()
    gop_period = int(Countframe.get())
    if (gop_period==1):
        gop_period=1000
    script_path =resource_path0( "ffglitch/jscripts/"+modechoices.get()+".js")
    input_video = file
    subprocess.call(f'"{ffgac}" -i "{input_video}" -an -mpv_flags +nopimb+forcemv -qscale:v 0  -b:v 20M -minrate 20M -maxrate 20M -bufsize 2M -g "{gop_period}"' +
                        ' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True)
    subprocess.call(f'"{ffedit}" -i tmp.mpg -f mv -s "{script_path}" -o "{output_video}"', shell=True)
    os.remove('tmp.mpg')
def ffglitch_library(file):
    choice = modechoices.get()
    outpath=os.path.dirname(file)
    outx=os.path.basename(file).split('.')[0]
    if(choice==modes[15]):
        Wait.config(text="Applying Effect: Motion Transfer", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        output=outpath+"/"+outx+"_datamoshed-motion transfer.mp4"
        extract_from=vecfile
        transfer_to=file
        vectors = []
        if extract_from:
            vectors = get_vectors(extract_from)
            if transfer_to == '':
                with open(output, 'w') as f:
                    json.dump(vectors, f)
        apply_vectors(vectors, transfer_to, output)
    elif(choice==modes[14]):
        Wait.config(text="Applying Effect: Stretch", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        input_video = file
        output= outpath+"/"+outx+"_datamoshed-stretch.mp4"
        apply_vectors(movement(get_vectors(input_video)), input_video, output, method='')
    elif(choice==modes[13]):
        Wait.config(text="Applying Effect: Fluid", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        input_video = file
        output= outpath+"/"+outx+"_datamoshed-fluid.mp4"
        apply_vectors(fluid(get_vectors(input_video)), input_video, output, method='')
    elif((choice==modes[13]) or (choice==modes[14]) or (choice==modes[15]) or (choice==modes[17])
        or (choice==modes[18]) or (choice==modes[19]) or (choice==modes[20]) or (choice==modes[21])
        or (choice==modes[22]) or (choice==modes[23]) or (choice==modes[24]) or (choice==modes[25])
        or (choice==modes[26]) or (choice==modes[27]) or (choice==modes[28]) or (choice==modes[29])):
        Wait.config(text="Applying Effect: "+modechoices.get(), fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        output= outpath+"/"+outx+"_datamoshed-"+(modechoices.get()).lower()+".mpg"
        external_scripts(output)
    elif(choice==modes[30]):
        Wait.config(text="Applying Effect: Shuffle", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        output= outpath+"/"+outx+"_datamoshed-"+(modechoices.get()).lower()+".mpg"
        shuffle(output)
    elif(choice==modes[31]):
        Wait.config(text="Applying Effect: Rise", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        output= outpath+"/"+outx+"_datamoshed-"+(modechoices.get()).lower()+".mpg"
        rise(output)
    export(output)
def pymosh_library(file):
    global final
    outpath=os.path.dirname(file)
    outx=os.path.basename(file).split('.')[0]
    infile=os.path.dirname(file)+"/"+outx+"_datamoshed.avi"
    if os.path.exists(infile):
        os.remove(infile)
    fps=30
    Wait.config(text="Converting the Video...", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
    root.update()
    subprocess.call(f'"{resource}" -loglevel error -y -i "{file}" -crf 0 -bf 0 -r {fps} "{infile}"', shell=True)
    def glide(interval, filename, outfile):
        f = Index.from_file(filename)
        buf = [None]
        def process_frame(frame):
            if buf[0] == None or not is_iframe(frame):
                buf[0] = frame
            else:
                frame = buf[0]
            return frame
        for stream in f.video:
            newstream = []
            newstream.append(stream[0])
            ix = 0
            jx = 0
            for i in stream[1:]:
                ix += 1
                jx += 1
                if ix < interval:
                    newstream.append(process_frame(stream[jx]))
                else:
                    newstream.append(newstream[-1])
                if ix > interval * 2:
                    ix = 0
        stream.replace(newstream)
        f.rebuild()
        with open(outfile, 'wb') as out:
            f.write(out)
    def avi_sort(filename, outfile):
        f = Index.from_file(filename)
        for stream in f.video:
            sorted_stream = sorted(stream, key=len, reverse=True)
            stream.replace(sorted_stream)
        f.rebuild()
        with open(outfile, 'wb') as out:
            f.write(out)
    def process_streams(in_filename, out_filename, func, *args, **kwargs):
            f = Index.from_file(in_filename)
            for stream in f.video:
                midpoint=float(firstframes.get())
                if midpoint>1:
                    midpoint=1
                drifted = list(func(stream, midpoint,*args, **kwargs))
                stream.replace(drifted)
            f.rebuild()
            with open(out_filename, 'wb') as out:
                f.write(out)
    def echo(stream, midpoint):
        all_frames = list(stream)
        pframes = [f for f in all_frames if not is_iframe(f)]
        midpoint_idx = int(len(all_frames)*midpoint)
        frames = all_frames[:midpoint_idx]
        while len(frames) < len(all_frames):
            frames += pframes[:(len(all_frames) - len(frames))]
        return frames
    choice = modechoices.get()
    if(choice==modes[8]):
        Wait.config(text="Applying Effect: Glide", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        time.sleep(2)
        interval=int(Positframe.get())
        if (interval==1):
            interval=2
        outfile=outpath+"/"+os.path.basename(infile).split('.')[0]+"-glide.avi"
        if os.path.exists(outfile):
            os.remove(outfile)
        glide(interval, infile, outfile)
    elif (choice==modes[9]):
        Wait.config(text="Applying Effect: Sort", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        time.sleep(2)
        outfile=outpath+"/"+os.path.basename(infile).split('.')[0]+"-sort.avi"
        if os.path.exists(outfile):
            os.remove(outfile)
        avi_sort(infile, outfile)
    elif (choice==modes[11]):
        Wait.config(text="Applying Effect: Echo", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
        root.update()
        time.sleep(2)
        outfile=outpath+"/"+os.path.basename(infile).split('.')[0]+"-echo.avi"
        if os.path.exists(outfile):
            os.remove(outfile)
        process_streams(infile, outfile, echo)
    final=outpath+"/"+os.path.basename(outfile).split('.')[0]+".mp4"
    if os.path.exists(final):
            os.remove(final)
    subprocess.call(f'"{resource}" -loglevel error -y -i "{outfile}" "{final}"', shell=True)
    export2=exportbox.get()
    os.remove(infile)
    export(final)
    os.remove(outfile)
def repeat(filename, mainfile):
    def write_frame(frame):
        out_file.write(frame_start + frame)
    def mosh_delta_repeat(n_repeat):
        if n_repeat=="1":
            n_repeat=2
        repeat_frames = []
        repeat_index = 0
        for index, frame in enumerate(frames):
            if (frame[5:8] != iframe and frame[5:8] != pframe) or not start_frame <= index < end_frame:
                write_frame(frame)
                continue
            if len(repeat_frames) < n_repeat and frame[5:8] != iframe:
                repeat_frames.append(frame)
                write_frame(frame)
            elif len(repeat_frames) == n_repeat:
                write_frame(repeat_frames[repeat_index])
                repeat_index = (repeat_index + 1) % n_repeat
            else:
                write_frame(frame)
    fps=30
    start_frame = int(firstframes.get())
    end_frame = int(Countframe.get())
    if end_frame==1:
        end_frame=1000
    input_avi = filename
    delta = int(Positframe.get())
    in_file = open(input_avi, 'rb')
    outx=os.path.basename(filename).split('.')[0]
    outpath=os.path.dirname(mainfile) 
    output_avi=outpath+"/"+outx+"-repeat.avi"
    in_file_bytes = in_file.read()
    out_file = open(output_avi, 'wb')
    frame_start = bytes.fromhex('30306463')
    frames = in_file_bytes.split(frame_start)
    out_file.write(frames[0])
    frames = frames[1:]
    iframe = bytes.fromhex('0001B0')
    pframe = bytes.fromhex('0001B6')
    n_video_frames = len([frame for frame in frames if frame[5:8] == iframe or frame[5:8] == pframe])
    if end_frame < 0:
        end_frame = n_video_frames
    mosh_delta_repeat(delta)
    out=outpath+"/"+outx+"-repeat.mp4"
    subprocess.call(f'"{resource}" -loglevel error -y -i "{output_avi}" "{out}"', shell=True)
    export2=exportbox.get()
    in_file.close()
    out_file.close()
    if(export2==exportchoices[0]):
        pass
    else:
        os.remove(output_avi)
    os.remove(filename)
    export(out)
def Datamoshclassic(filename,mainfile):   
    global outf
    END_FRAME_HEX = b'00dc'
    I_FRAME_HEX = b'\x00\x01\xb0'
    fps=30
    outx=os.path.basename(filename).split('.')[0]
    outpath=os.path.dirname(mainfile) 
    outf=outpath+"/"+outx+"-classic_datamoshed.avi"
    def main2(filename, effect_sec_list, p_frames_mult):
        magic(effect_sec_list, p_frames_mult)
        out=outpath+"/"+outx+"-classic.mp4"
        subprocess.call(f'"{resource}" -loglevel error -y -i "{outf}" "{out}"', shell=True)
        os.remove(filename)
        export(out)
        export2=exportbox.get()
        if(export2==exportchoices[0]):
            pass
        else:
            os.remove(outf)
    def magic(effect_sec_list, p_frames_mult):
        with open(filename, 'rb') as in_file, open(outf, 'wb') as out_file:
            frames = split_file(in_file, END_FRAME_HEX)
            for index, frame in enumerate(frames):
                if not is_need_effect_here(index / fps, effect_sec_list):
                    out_file.write(frame + END_FRAME_HEX)
                    continue
                if not is_iframe(frame):
                    out_file.write((frame + END_FRAME_HEX) * p_frames_mult)
    def split_file(fp, marker, blocksize=4096):
        buffer = b''
        for block in iter(lambda: fp.read(blocksize), b''):
            buffer += block
            while True:
                markerpos = buffer.find(marker)
                if markerpos == -1:
                    break
                yield buffer[:markerpos]
                buffer = buffer[markerpos + len(marker):]
        yield buffer
    def is_need_effect_here(curr_sec, effect_sec_list):
        return any(start < curr_sec < end for start, end in effect_sec_list)
    def is_iframe(frame):
        return frame[5:8] == I_FRAME_HEX
    start=float(firstframes.get())
    make=float(Countframe.get())
    timer=int(Positframe.get())
    main2(filename,[(start,make)],timer)
def Datamosh(Inputfile):
  global fileout
  checkinput=os.path.splitext(file)[0]+"_datamoshed.avi"
  if os.path.exists(checkinput):
    filein = Inputfile
    countframes = int(Countframe.get())
    positframes = int(Positframe.get())
    firstframe = int(firstframes.get())
    choice = modechoices.get()
    kill = float(killframe.get())
    audio=0
    if(choice==modes[0]):
            mode="bloom"
    elif(choice==modes[1]):
            mode="invert"
    elif(choice==modes[2]):
            mode="jiggle"
    elif(choice==modes[3]):
            mode="overlap"
    elif(choice==modes[4]):
            mode="pulse"
    elif(choice==modes[5]):
            mode="reverse"
    elif(choice==modes[6]):
            mode="random"
    elif(choice==modes[10]):
            mode="shake"
    elif(choice==modes[12]):
            mode="void"
    else:
        messagebox.showerror("Error!","Please select a valid mode!")
        os.remove(outputpath)
        end()
        os.kill(Datamosh())
    temp_nb = random.randint(10000, 99999)
    temp_dir = "temp-" + str(temp_nb)
    temp_hdrl = temp_dir +"/hdrl.bin"
    temp_movi = temp_dir +"/movi.bin"
    temp_idx1 = temp_dir +"/idx1.bin"    
    os.mkdir(temp_dir)
    def constrain(val, min_val, max_val):
        return min(max_val, max(min_val, val))
    def bstream_until_marker(bfilein, bfileout, marker=0, startpos=0):
            chunk = 1024
            filesize = os.path.getsize(bfilein)
            if marker :
                    marker = str.encode(marker)

            with open(bfilein,'rb') as rd:
                    with open(bfileout,'ab') as wr:
                            for pos in range(startpos, filesize, chunk):
                                    rd.seek(pos)
                                    buffer = rd.read(chunk)

                                    if marker:
                                            if buffer.find(marker) > 0 :
                                                    marker_pos = re.search(marker, buffer).start()
                                                    marker_pos = marker_pos + pos
                                                    split = buffer.split(marker, 1)
                                                    wr.write(split[0])
                                                    return marker_pos
                                            else:
                                                    wr.write(buffer)
                                    else:
                                            wr.write(buffer)
    movi_marker_pos = bstream_until_marker(filein, temp_hdrl, "movi")
    idx1_marker_pos = bstream_until_marker(filein, temp_movi, "idx1", movi_marker_pos)
    bstream_until_marker(filein, temp_idx1, 0, idx1_marker_pos)
    with open(temp_movi,'rb') as rd:
            chunk = 1024
            filesize = os.path.getsize(temp_movi)
            frame_table = []
            for pos in range(0, filesize, chunk):
                    rd.seek(pos)
                    buffer = rd.read(chunk)
                    for m in (re.finditer(b'\x30\x31\x77\x62', buffer)):
                                    if audio : frame_table.append([m.start() + pos, 'sound'])		
                    for m in (re.finditer(b'\x30\x30\x64\x63', buffer)):
                            frame_table.append([m.start() + pos, 'video'])
                    frame_table.sort(key=lambda tup: tup[0])
            l = []
            l.append([0,0, 'void'])
            max_frame_size = 0
            for n in range(len(frame_table)):
                    if n + 1 < len(frame_table):
                            frame_size = frame_table[n + 1][0] - frame_table[n][0]
                    else:
                            frame_size = filesize - frame_table[n][0]
                    max_frame_size = max(max_frame_size, frame_size)
                    l.append([frame_table[n][0],frame_size, frame_table[n][1]])
    clean = []
    final = []
    if firstframe :
            for x in l :
                    if x[2] == 'video':
                            clean.append(x)
                            break
    for x in l:
            if x[1] <= (max_frame_size * kill) :
                    clean.append(x)
    if mode == "void":
            Wait.config(text="Applying Effect: Void", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            final = clean
    if mode == "random":
            Wait.config(text="Applying Effect: Random", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            final = random.sample(clean,len(clean))
    if mode == "reverse":
            Wait.config(text="Applying Effect: Reverse", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            final = sum(zip(clean[::-1], clean[:-1]), ())
    if mode == "invert":
            Wait.config(text="Applying Effect: Invert", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            final = sum(zip(clean[1::2], clean[::2]), ())
    if mode == 'bloom':
            Wait.config(text="Applying Effect: Bloom", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            repeat = int(countframes)
            frame = int(positframes)
            lista = clean[:frame]
            listb = clean[frame:]
            final = lista + ([clean[frame]]*repeat) + listb
    if mode == 'pulse':
            Wait.config(text="Applying Effect: Pulse", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            pulselen = int(countframes)
            pulseryt = int(positframes)
            j = 0
            for x in clean:
                    i = 0
                    if(j % pulselen == 0):
                            while i < pulselen :
                                    final.append(x)
                                    i = i + 1
                    else:
                            final.append(x)
                            j = j + 1
    if mode == "jiggle":
            Wait.config(text="Applying Effect: Jiggle", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            amount = int(positframes)
            final = [clean[constrain(x+int(random.gauss(0,amount)),0,len(clean)-1)] for x in range(0,len(clean))]
    if mode == "overlap":
            Wait.config(text="Applying Effect: Overlap", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            pulselen = int(countframes)
            pulseryt = int(positframes)
            clean = [clean[i:i+pulselen] for i in range(0,len(clean),pulseryt)]
            final = [item for sublist in clean for item in sublist]
    if mode == "shake":
            Wait.config(text="Applying Effect: Shake", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            def process_streams(in_filename, out_filename, func, *args, **kwargs):
                f = Index.from_file(in_filename)
                for stream in f.video:
                    drifted = list(func(stream, *args, **kwargs))
                    stream.replace(drifted)
                f.rebuild()
                with open(out_filename, 'wb') as out:
                    f.write(out)
            def shake(stream):
                def glitch(stream):
                    all_frames = iter(stream)
                    yield next(all_frames)
                    while True:
                        frame = next(all_frames)
                        if not is_iframe(frame):
                            yield frame
                            yield frame
                return islice(glitch(stream), len(stream))
            fileout= filein[:-4] + '-' + mode + '.avi'
            process_streams(filein, fileout, shake)
            fps=30
            output= fileout[:-9]+"shake.mp4"
            subprocess.call(f'"{resource}" -loglevel error -y -i "{fileout}" -crf 0 -bf 0 -r {fps} "{output}"', shell=True)
            time.sleep(2)
            os.remove(fileout)
            os.remove(filein)
            os.remove(temp_hdrl)
            os.remove(temp_movi)
            os.remove(temp_idx1)
            os.rmdir(temp_dir)
            export(output)
            os.kill(datamosh)
    time.sleep(2)
    fileout= filein[:-4] + '-' + mode + '.avi'
    if os.path.exists(fileout):
            os.remove(fileout)
    bstream_until_marker(temp_hdrl, fileout)
    with open(temp_movi,'rb') as rd:
            filesize = os.path.getsize(temp_movi)
            with open(fileout,'ab') as wr:
                    wr.write(struct.pack('<4s', b'movi'))
                    for x in final:
                            if x[0] != 0 and x[1] != 0:
                                    rd.seek(x[0])
                                    wr.write(rd.read(x[1]))
    bstream_until_marker(temp_idx1, fileout)
    if os.path.exists(outputpath):
            os.remove(outputpath)
    else:
        pass
    os.remove(temp_hdrl)
    os.remove(temp_movi)
    os.remove(temp_idx1)
    os.rmdir(temp_dir)
    export(fileout)
  else:
      Wait.config(text="Moshed Video is Ready!", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
      root.update()
def export(fileout):
    def removefileout():
        if os.path.exists(fileout):
                    os.remove(fileout)
                    messagebox.showinfo("DONE","Datamoshed video is ready!")
                    end()
        else:
            pass
    export=exportbox.get()
    if(export==exportchoices[0]):
      ask=messagebox.askquestion("?","Do you want the Raw moshed version?")
      if ask=='yes':
        choice = modechoices.get()
        if(choice==modes[7]) or (choice==modes[16]):
            os.remove(fileout)
            Wait.config(text="Moshed Video is Ready!", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            messagebox.showinfo("DONE","Datamoshed video is ready!")
            end()
        else:
            file2=os.path.splitext(fileout)[0]
            os.rename(fileout,file2+"_datamoshed.avi")
            Wait.config(text="Moshed Video is Ready!", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            messagebox.showinfo("DONE","Datamoshed video is ready!")
            end()
      elif ask=='no':
            targetformat=".avi"
            convert(fileout,targetformat)
            removefileout()
    elif(export==exportchoices[1]):
        choice = modechoices.get()
        if(choice==modes[7]) or (choice==modes[8]) or (choice==modes[9]) or (choice==modes[16]):
            nfile=os.path.splitext(fileout)[0]
            os.rename(fileout,nfile+"_datamoshed.mp4")
            Wait.config(text="Moshed Video is Ready!", fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
            root.update()
            messagebox.showinfo("DONE","Datamoshed video is ready!")
            end()
        else: 
            targetformat=".mp4"
            convert(fileout,targetformat)
            removefileout()
    elif(export==exportchoices[2]):
            targetformat=".gif"
            convert(fileout,targetformat)
            removefileout()
    elif(export==exportchoices[3]):
            targetformat=".mov"
            convert(fileout,targetformat)
            removefileout()
    elif(export==exportchoices[4]):
            targetformat=".mkv"
            convert(fileout,targetformat)
            removefileout()
    elif(export==exportchoices[5]):
            targetformat=".wmv"
            convert(fileout,targetformat)
            removefileout()
    else:
        messagebox.showerror("Error!","Please select a valid video format!")
        os.remove(fileout)
        end()
        os.kill(Datamosh())
def toggle():
    if var.get()==0:
        Disableadvanced()
        dynamiclable()
    else:
        Enableadvanced()
        dynamiclable()
def Enableadvanced():
        choice = modechoices.get()
        if(choice==modes[8]) or (choice==modes[13]):
            var2.set(6)
            var4.set(0.7)
            var1.set(1)
            if (choice==modes[13]):
                var2.set(10)
            countlabel['fg']="grey"
            positlabel['fg']="green"
            firstflabel['fg']="grey"
            killlabel['fg']="grey"
            Countframe['state']=DISABLED
            Positframe['state']=NORMAL
            firstframes['state']=DISABLED
            killframe['state']=DISABLED
        elif(choice==modes[7]) or (choice==modes[16]):
            var2.set(1)
            var1.set(1000)
            if (choice==modes[16]):
                var2.set(5)
            countlabel['fg']="green"
            positlabel['fg']="green"
            firstflabel['fg']="green"
            killlabel['fg']="grey"
            Countframe['state']=NORMAL
            Positframe['state']=NORMAL
            firstframes['state']=NORMAL
            killframe['state']=DISABLED
        elif(choice==modes[6]) or (choice==modes[10]) or (choice==modes[12]):
            var2.set(1)
            var1.set(1)
            if (choice==modes[12]):
                var4.set(0.2)
            else:
                var4.set(0.7)
            var3.set(1)
            countlabel['fg']="grey"
            positlabel['fg']="grey"
            firstflabel['fg']="green"
            killlabel['fg']="green"
            Countframe['state']=DISABLED
            Positframe['state']=DISABLED
            firstframes['state']=NORMAL
            killframe['state']=NORMAL
        elif(choice==modes[5]) or (choice==modes[1]) or (choice==modes[31]):
            var2.set(1)
            var3.set(1)
            var1.set(1)
            var4.set(0.7)
            if (choice==modes[31]):
                var4.set(50)
                var3.set(10)
            else:
                var4.set(0.7)
            countlabel['fg']="grey"
            positlabel['fg']="grey"
            firstflabel['fg']="green"
            killlabel['fg']="green"
            Countframe['state']=DISABLED
            Positframe['state']=DISABLED
            firstframes['state']=NORMAL
            killframe['state']=NORMAL
        elif(choice==modes[11]):
            var2.set(1)
            var1.set(1)
            if (choice==modes[11]):
                var3.set(0.5)
            else:
                var3.set(1)
            countlabel['fg']="grey"
            positlabel['fg']="grey"
            firstflabel['fg']="green"
            killlabel['fg']="grey"
            Countframe['state']=DISABLED
            Positframe['state']=DISABLED
            firstframes['state']=NORMAL
            killframe['state']=DISABLED
        elif(choice==modes[2]):
            var2.set(1)
            var4.set(0.7)
            var1.set(1)
            countlabel['fg']="grey"
            positlabel['fg']="green"
            firstflabel['fg']="green"
            killlabel['fg']="green"
            Countframe['state']=DISABLED
            Positframe['state']=NORMAL
            firstframes['state']=NORMAL
            killframe['state']=NORMAL
        elif(choice==modes[0]) or (choice==modes[3]) or (choice==modes[4]):
            var2.set(1)
            var4.set(0.7)
            var1.set(1)
            countlabel['fg']="green"
            positlabel['fg']="green"
            firstflabel['fg']="green"
            killlabel['fg']="green"
            Countframe['state']=NORMAL
            Positframe['state']=NORMAL
            firstframes['state']=NORMAL
            killframe['state']=NORMAL
        elif((choice==modes[17]) or (choice==modes[18])
            or (choice==modes[19]) or (choice==modes[20])
            or (choice==modes[21]) or (choice==modes[22])
            or (choice==modes[23]) or (choice==modes[24])
            or (choice==modes[25]) or (choice==modes[26])
            or (choice==modes[27]) or (choice==modes[28]) or (choice==modes[29])):
            var1.set(1000)
            countlabel['fg']="green"
            positlabel['fg']="grey"
            firstflabel['fg']="grey"
            killlabel['fg']="grey"
            Countframe['state']=NORMAL
            Positframe['state']=DISABLED
            firstframes['state']=DISABLED
            killframe['state']=DISABLED
        elif(choice==modes[30]):
            var4.set(1)
            var1.set(10)
            countlabel['fg']="green"
            positlabel['fg']="grey"
            firstflabel['fg']="grey"
            killlabel['fg']="green"
            Countframe['state']=NORMAL
            Positframe['state']=DISABLED
            firstframes['state']=DISABLED
            killframe['state']=NORMAL
        else:
            Disableadvanced()
def dynamiclable():
    choice = modechoices.get()
    if(choice==modes[7]):
       firstflabel['text']= "Start(sec)"
       countlabel['text']="End(sec)"
    elif(choice==modes[16]):
        countlabel['text']="Last Frame"
        firstflabel['text']= "First Frame"
    elif(choice==modes[11]):
        countlabel['text']="Glitch Size"
        firstflabel['text']= "Mid Point"
    elif((choice==modes[0]) or (choice==modes[1]) or (choice==modes[2])
        or (choice==modes[3]) or (choice==modes[4]) or (choice==modes[5])
        or (choice==modes[6]) or (choice==modes[12]) or (choice==modes[10])):
        countlabel['text']="Glitch Size"
        firstflabel['text']= "Ignore Frame"
    else:
       firstflabel['text']="First Frame"
       countlabel['text']="Glitch Size"
       positlabel['text']="Frames Frequency"
       killlabel['text']="Kill Frames"
def Disableadvanced():
        var1.set("1")
        var2.set(1)
        var3.set(1)
        var4.set(0.7)
        countlabel['fg']="grey"
        positlabel['fg']="grey"
        firstflabel['fg']="grey"
        killlabel['fg']="grey"
        Countframe['state']=DISABLED
        Positframe['state']=DISABLED
        firstframes['state']=DISABLED
        killframe['state']=DISABLED
def refresh(event):
    if var=="0":
        pass
    else:
        modechoices['values']=toggle()
    choice = modechoices.get()
    if (choice==modes[15]):
        vector_label.place(x=270,y=233)
        Opening_vector.place(x=350,y=233)
    else:
        vector_label.place_forget()
        Opening_vector.place_forget()
def toggle2():
    global highest
    if var5.get()==1:
        highest="yes"
    else:
        highest="yes"
def info():
    messagebox.showinfo("Help",
    "Datamosher Pro is an automatic glitching tool that can mosh/corrupt video files and gives awesome glitchy results."
    "\nHow To Use:\n➤First open the video you want to datamosh"
    "\n➤Choose the desired datamosh mode, export format and quality adjustments"
    "\n➤Use advanced options for different modes"
    "\n➤Then click on the datamosh button and wait for a few seconds"
    "\n➤After conversions, your video will be moshed and saved in the same video directory."
    "\n\nDeveloper: <NAME> (a.k.a. Akascape)\nIf you are facing any issue then contact me on reddit."
    "\nVersion-1.7")
def callback(url):
    webbrowser.open_new_tab("https://github.com/Akascape/Datamosher-Pro-GUI-.git")
root=Tk()
root.title("Datamosher Pro")
root.resizable(width=False, height=False)
root.geometry("500x450")
root.configure(bg='#FFFFFF')
root.columnconfigure(0,weight=1)
try:
    icopath=resource_path0("Assets/icon.ico")
    root.wm_iconbitmap(icopath)
except:
    pass
path=resource_path0("Assets/label.png")
LabelIMG=PhotoImage(file=path)
headlabel=Label(root,image=LabelIMG,borderwidth=0, highlightthickness=0, padx=0,pady=0)
headlabel.grid()
LocationError=Label(root,text="Choose Video To Datamosh",fg="red",bg='#FFFFFF')
LocationError.grid()
OpeningFile= Button(root, width=61,bg="#82CC6C",fg="white", text="OPEN",highlightthickness=1,borderwidth=0.2,relief="groove",command=openfile)
OpeningFile.grid()
chooselabel=Label(root,text="Select Mode:",font="Aharoni",bg='#FFFFFF')
chooselabel.place(x=80,y=115,anchor='center')
modes=["Bloom", "Invert", "Jiggle", "Overlap", "Pulse", "Reverse",
       "Random", "Classic", "Glide", "Sort", "Shake", "Echo", "Void",
       "Fluid", "Stretch", "Motion Transfer", "Repeat", "Shear", "Delay", "Sink",
       "Mirror", "Vibrate", "Slam Zoom", "Zoom","Invert-Reverse", "Shift",
       "Noise", "Stop", "Buffer", "Slice", "Shuffle", "Rise"]
modechoices=ttk.Combobox(root,values=sorted(modes), font="Verdana 12", width=10, height=10,state="readonly")
modechoices.current(0)
modechoices.bind('<FocusIn>', lambda event: refresh(event))
modechoices.place(x=130,y=104)
exportchoices=["AVI","MP4","GIF","MOV","MKV","WMV"]
exportlabel=Label(root,text="Export Format:",font="Aharoni",bg='#FFFFFF')
exportlabel.place(x=270,y=105)
exportbox=ttk.Combobox(root,values=exportchoices, font="Verdana 10", width=8, state="readonly")
exportbox.current(1)
exportbox.place(x=380,y=106)
global var
var = IntVar()
var.set(0)
advancedbox=Checkbutton(root, text="Advanced",bg="#FFFFFF", command=toggle,variable=var,onvalue=1, offvalue=0)
advancedbox.place(x=70,y=150, anchor='center')
var1=DoubleVar()
var1.set(1)
countlabel=Label(root,text="Glitch Size",fg="grey",bg='#FFFFFF')
countlabel.place(x=50,y=165)
Countframe=Entry(root,bg="#00D2FF",width=10,borderwidth=3, textvariable=var1,state=DISABLED)
Countframe.place(x=140,y=165)
var2=DoubleVar()
var2.set(1)
positlabel=Label(root,text="Frames Frequency",fg="grey",bg='#FFFFFF')
positlabel.place(x=270,y=165)
Positframe=Entry(root,bg="#00D2FF",width=10,borderwidth=3, textvariable=var2, state=DISABLED)
Positframe.place(x=380,y=165)
var3=IntVar()
var3.set(1)
firstflabel=Label(root,text="Ignore Frame",fg="grey",bg='#FFFFFF')
firstflabel.place(x=50,y=200)
firstframes=Entry(root,bg="#00D2FF",width=10,borderwidth=3, textvariable=var3,state=DISABLED)
firstframes.place(x=140,y=200)
var4=DoubleVar()
var4.set(0.7)
killlabel=Label(root,text="Kill Frames",fg="grey",bg='#FFFFFF')
killlabel.place(x=270,y=200)
killframe=Entry(root,bg="#00D2FF",width=10,borderwidth=3, textvariable=var4, state=DISABLED)
killframe.place(x=380,y=200)
global Wait
Wait=Label(root,text="",fg="#6D76CD",bg='#FFFFFF', font=("Aharoni",15))
infobtn=Button(root, width=2,bg="#FFFFFF",fg="black", text="ⓘ",font=(10),relief="sunken",cursor='hand2', highlightthickness=0,borderwidth=0,padx=0,pady=0,command=info)
infobtn.place(x=475,y=425)
dev=Label(root, text='Developed by Akascape | ',bg='#FFFFFF',fg="#6D76CD", font=("Halvetica",10))
dev.place(x=5,y=430)
link=Label(root, text="Datamosher Pro Help",font=('Halvetica',10),bg='#FFFFFF',fg="#6D76CD", cursor="hand2")
link.place(x=155,y=430)
link.bind("<Button-1>", lambda e:
callback("https://github.com/Akascape/Datamosher-Pro-GUI-.git"))
path0=resource_path0("Assets/button.png")
buttonIMG=PhotoImage(file=path0)
datamoshbtn=Button(root,image=buttonIMG,borderwidth=0, highlightthickness=0, padx=0,pady=0,command=Step1)
datamoshbtn.place(x=100,y=270)
vector_label=Label(root,text="Vector Video:",fg="green",bg='#FFFFFF')
Opening_vector= Button(root, width=15,bg="#82CC6C",fg="white", text="OPEN",highlightthickness=1,borderwidth=0.2,relief="groove",command=datafile)
global var5
var5 = IntVar()
var5.set(1)
highest="yes"
Highbox=Checkbutton(root, text="Highest Quality",bg="#FFFFFF", command=toggle2,variable=var5,onvalue=1, offvalue=0)
Highbox.place(x=85,y=240, anchor='center')
wrong=Label(root, width=2,bg="#FFFFFF",fg="red", text="ⓘ",font=(10),relief="sunken", highlightthickness=0,borderwidth=0,padx=0,pady=0)
root.mainloop()
#DEVELOPER: <NAME> (a.k.a Akascape)
#Version=1.7
