import sys
import os
import threading
import time
import json
import numpy as np
import cv2
import face_recognition
from PIL import Image
import tkinter as tk
from tkinter import filedialog, messagebox
import webbrowser
from datetime import datetime, timedelta
import imageio
import imageio_ffmpeg
import moviepy
from moviepy import VideoFileClip, concatenate_videoclips
UCRETSIZ_BITIS = datetime(2026, 3, 8, 21, 0, 0)
ILETISIM_LINKI = 'https://t.me/zmkstudio'
LISANS_DOSYASI = os.path.join(os.getenv('APPDATA'), '.zmk_studio_license.json')
AYLIK_KODLAR = ['ZMK-AY-1111', 'ZMK-AY-2222', 'ZMK-AY-3333']
YILLIK_KODLAR = ['ZMK-YIL-4444', 'ZMK-YIL-5555', 'ZMK-YIL-6666']
SINIRSIZ_KODLAR = ['ZMK-VIP-7777', 'ZMK-VIP-8888', 'ZMK-VIP-9999', 'ZMK-A1B2C3D4E5F', 'ZMK-X9Y8Z7W6V5U', 'ZMK-M1N2B3V4C5X']
def lisans_gecerli_mi():
# irreducible cflow, using cdg fallback
# ***<module>.lisans_gecerli_mi: Failure: Compilation Error
if os.path.exists(LISANS_DOSYASI):
with open(LISANS_DOSYASI, 'r') as f:
veri = json.load(f)
bitis_tarihi = datetime.fromisoformat(veri['bitis_tarihi'])
if datetime.now() < bitis_tarihi:
return True
return False
return False
def lisans_kaydet(kod):
if kod in AYLIK_KODLAR:
bitis = datetime.now() + timedelta(days=30)
else:
if kod in YILLIK_KODLAR:
bitis = datetime.now() + timedelta(days=365)
else:
if kod in SINIRSIZ_KODLAR:
bitis = datetime.now() + timedelta(days=36500)
else:
return False
with open(LISANS_DOSYASI, 'w') as f:
json.dump({'lisans_kodu': kod, 'bitis_tarihi': bitis.isoformat()}, f)
return True
def motoru_calistir(v_yolu, f_yolu, k_yolu, turbo, sonuc_label, btn):
try:
pil_resim = Image.open(f_yolu).convert('RGB')
resim_rgb = np.ascontiguousarray(np.array(pil_resim))
yuz_kodlari = face_recognition.face_encodings(resim_rgb)
if len(yuz_kodlari) == 0:
messagebox.showerror('ZMK Studio Hata', 'Fotoğrafta yüz bulunamadı!')
btn.config(state=tk.NORMAL, bg='#ff0055')
return
else:
hedef_yuz_kod = yuz_kodlari[0]
video = cv2.VideoCapture(v_yolu)
fps = int(video.get(cv2.CAP_PROP_FPS)) or 24
bulunan_saniyeler = []
kare_sayaci = 0
toplam_kare = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
turbo_atlama = int(turbo)
while True:
basarili, kare = video.read()
if not basarili:
break
else:
kare_sayaci += 1
if kare_sayaci % (fps * turbo_atlama) == 0:
yuzde = int(kare_sayaci / toplam_kare * 100)
sonuc_label.config(text=f'AI Analiz Ediyor: %{yuzde}')
kucuk_kare = cv2.resize(kare, (0, 0), fx=0.6, fy=0.6)
rgb_kare = cv2.cvtColor(kucuk_kare, cv2.COLOR_BGR2RGB)
yuz_konumlari = face_recognition.face_locations(np.ascontiguousarray(rgb_kare))
karedeki_yuzler = face_recognition.face_encodings(rgb_kare, yuz_konumlari)
for yuz in karedeki_yuzler:
if face_recognition.compare_faces([hedef_yuz_kod], yuz, tolerance=0.62)[0]:
bulunan_saniyeler.append(kare_sayaci // fps)
break
video.release()
if bulunan_saniyeler:
sonuc_label.config(text='Sahneler Ultra Hızda Birleştiriliyor...')
ana_klip = VideoFileClip(v_yolu)
klipler = []
bas, bit = (bulunan_saniyeler[0], bulunan_saniyeler[0])
araliklar = []
for s in bulunan_saniyeler[1:]:
if s <= bit + turbo_atlama + 1:
bit = s
else:
araliklar.append((bas, bit))
bas, bit = (s, s)
araliklar.append((bas, bit))
for b, t in araliklar:
start_t = max(0, b - 2.0)
end_t = min(ana_klip.duration, t + 2.0)
klipler.append(ana_klip.subclipped(start_t, end_t))
son_video = concatenate_videoclips(klipler)
son_video.write_videofile(k_yolu, codec='libx264', audio_codec='aac', preset='ultrafast', threads=4, logger=None)
messagebox.showinfo('ZMK Studio', f'Comp Oluşturuldu!\nDosya: {k_yolu}')
else:
messagebox.showwarning('Sonuç', 'Videoda bu kişi bulunamadı.')
except Exception as e:
messagebox.showerror('Sistem Hatası', f'Hata:\n{str(e)}')
btn.config(state=tk.NORMAL, text='✂️ COMP OLUŞTUR', bg='#ff0055')
sonuc_label.config(text='Hazır')
def baslat_thread():
if v_yolu.get().endswith('...') or f_yolu.get().endswith('...') or k_yolu.get().endswith('...'):
messagebox.showwarning('Eksik', 'Lütfen video, fotoğraf ve kayıt yeri seçin!')
return None
else:
btn_basla.config(state=tk.DISABLED, text='AI İŞLİYOR...', bg='#555555')
t = threading.Thread(target=motoru_calistir, args=(v_yolu.get(), f_yolu.get(), k_yolu.get(), turbo_ayar.get(), lbl_durum, btn_basla))
t.daemon = True
t.start()
def video_sec():
d = filedialog.askopenfilename(filetypes=[('Video', '*.mp4 *.mov *.avi')])
v_yolu.set(d) if d else None
def foto_sec():
d = filedialog.askopenfilename(filetypes=[('Resim', '*.jpg *.png')])
f_yolu.set(d) if d else None
def kayit_yeri_sec():
d = filedialog.asksaveasfilename(defaultextension='.mp4', initialfile='ZMK_Comp.mp4')
k_yolu.set(d) if d else None
def ana_uygulamayi_ac():
global btn_basla
global v_yolu
global lbl_durum
global turbo_ayar
global root
global k_yolu
global f_yolu
root = tk.Tk()
root.title('AI Comp Maker v1.0 - ZMK Studio PRO')
root.geometry('540x580')
root.configure(bg='#121212')
v_yolu, f_yolu, k_yolu = (tk.StringVar(value='...'), tk.StringVar(value='...'), tk.StringVar(value='...'))
tk.Label(root, text='ZMK STUDIO', font=('Courier', 14, 'bold'), fg='#ffcc00', bg='#121212').pack(pady=(20, 0))
tk.Label(root, text='AI COMP MAKER', font=('Arial', 26, 'bold'), fg='#00ffcc', bg='#121212').pack(pady=(0, 10))
tk.Button(root, text='🎬 1. VİDEO SEÇ', command=video_sec, bg='#252525', fg='white', width=40).pack(pady=5)
tk.Label(root, text='💡 Öneri: Daha hızlı render için 5-6 GB arası dosyalar yükleyin.\n(10 GB ve üzeri dosyalar desteklenir ancak işlem süresi uzar.)', fg='#ffaa00', bg='#121212', font=('Arial', 8, 'italic')).pack()
tk.Label(root, textvariable=v_yolu, fg='#666', bg='#121212', font=('Arial', 7)).pack()
tk.Button(root, text='📸 2. OYUNCU FOTOĞRAFI SEÇ', command=foto_sec, bg='#252525', fg='white', width=40).pack(pady=5)
tk.Label(root, textvariable=f_yolu, fg='#666', bg='#121212', font=('Arial', 7)).pack()
tk.Button(root, text='💾 3. ÇIKTIYI KAYDET', command=kayit_yeri_sec, bg='#1a472a', fg='white', width=40).pack(pady=5)
tk.Label(root, textvariable=k_yolu, fg='#666', bg='#121212', font=('Arial', 7)).pack()
f_turbo = tk.Frame(root, bg='#121212')
f_turbo.pack(pady=10)
tk.Label(f_turbo, text='⚡ Turbo Hızı (1-10):', fg='white', bg='#121212').pack(side=tk.LEFT)
turbo_ayar = tk.Spinbox(f_turbo, from_=1, to=10, width=5)
turbo_ayar.delete(0, 'end')
turbo_ayar.insert(0, '2')
turbo_ayar.pack(side=tk.LEFT)
lbl_durum = tk.Label(root, text='Hazır', fg='#00ffcc', bg='#121212')
lbl_durum.pack(pady=5)
btn_basla = tk.Button(root, text='✂️ COMP OLUŞTUR', command=baslat_thread, bg='#ff0055', fg='white', font=('Arial', 14, 'bold'), width=25)
btn_basla.pack(pady=10)
root.mainloop()
def lisans_penceresini_ac():
lisans_win = tk.Tk()
lisans_win.title('ZMK Studio - Lisans Gerekli')
lisans_win.geometry('450x300')
lisans_win.configure(bg='#0a0a0a')
lisans_win.geometry(f'+{int(lisans_win.winfo_screenwidth() / 2 - 225)}+{int(lisans_win.winfo_screenheight() / 2 - 150)}')
tk.Label(lisans_win, text='ZMK STUDIO ABONELİĞİ', font=('Arial', 14, 'bold'), fg='#ff0055', bg='#0a0a0a').pack(pady=(20, 10))
tk.Label(lisans_win, text='Lütfen satın aldığınız Aylık, Yıllık veya\nSınırsız lisans kodunu girin.', fg='white', bg='#0a0a0a').pack()
anahtar_entry = tk.Entry(lisans_win, font=('Courier', 14), width=25, justify='center')
anahtar_entry.pack(pady=15)
def kontrol_et():
kod = anahtar_entry.get().strip()
if lisans_kaydet(kod):
messagebox.showinfo('Başarılı', 'Lisansınız Onaylandı! Teşekkürler.')
lisans_win.destroy()
ana_uygulamayi_ac()
else:
messagebox.showerror('Hata', 'Geçersiz Lisans Kodu!')
tk.Button(lisans_win, text='LİSANSI ONAYLA', command=kontrol_et, bg='#00ffcc', font=('Arial', 12, 'bold'), width=20).pack(pady=5)
tk.Button(lisans_win, text='Lisans Satın Al (İletişim)', command=lambda: webbrowser.open(ILETISIM_LINKI), bg='#252525', fg='#ffcc00').pack(pady=10)
lisans_win.mainloop()
splash = tk.Tk()
splash.overrideredirect(True)
splash.geometry('400x250')
splash.configure(bg='#050505')
splash.geometry(f'+{int(splash.winfo_screenwidth() / 2 - 200)}+{int(splash.winfo_screenheight() / 2 - 125)}')
tk.Label(splash, text='ZMK STUDIO', font=('Courier', 30, 'bold'), fg='#ffcc00', bg='#050505').pack(pady=(70, 5))
lbl_load = tk.Label(splash, text='Sistem Kontrol Ediliyor...', fg='#00ffcc', bg='#050505')
lbl_load.pack()
def animasyon():
for i in range(1, 101):
lbl_load.config(text=f'ZMK AI Motoru Yükleniyor... %{i}')
splash.update()
time.sleep(0.01)
splash.destroy()
su_an = datetime.now()
if su_an < UCRETSIZ_BITIS:
ana_uygulamayi_ac()
else:
if lisans_gecerli_mi():
ana_uygulamayi_ac()
else:
lisans_penceresini_ac()
splash.after(500, animasyon)
splash.mainloop()