import os import re import math import shutil import random import subprocess from datetime import datetime, timedelta, timezone import gradio as gr import spaces # ZeroGPU Desteği def get_video_duration(input_file): cmd = [ 'ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', input_file ] try: result = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode().strip() return float(result) except Exception: return None def has_audio_stream(input_file): cmd = [ 'ffprobe', '-v', 'error', '-select_streams', 'a', '-show_entries', 'stream=codec_type', '-of', 'csv=p=0', input_file ] try: result = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode().strip() return bool(result) except Exception: return False def generate_fake_metadata_args(user_date, user_loc, user_make, user_model): if user_date: creation_time_str = user_date else: days_ago = random.randint(1, 180) hours_ago = random.randint(0, 23) minutes_ago = random.randint(0, 59) random_date = datetime.now() - timedelta(days=days_ago, hours=hours_ago, minutes=minutes_ago) creation_time_str = random_date.strftime("%Y-%m-%dT%H:%M:%SZ") lat_num, lon_num = 40.7128, -74.0060 if user_loc: location_str = user_loc coords = re.findall(r'[-+]?\d*\.\d+|\d+', user_loc) if len(coords) >= 2: try: lat_num = float(coords[0]) lon_num = float(coords[1]) except ValueError: pass else: lat_num = round(random.uniform(36.0, 42.0), 4) lon_num = round(random.uniform(26.0, 45.0), 4) location_str = f"{lat_num:+.4f}{lon_num:+.4f}/" profiles = [ { "make": "Apple", "model": "iPhone 15 Pro", "lens": "iPhone 15 Pro back camera 6.86mm f/1.78", "software": "17.5.1", "handler_v": "Core Media Video", "handler_a": "Core Media Audio", "fnumber": 1.78, "focal": 6.86 }, { "make": "Apple", "model": "iPhone 14 Pro", "lens": "iPhone 14 Pro back camera 6.86mm f/1.78", "software": "17.4.1", "handler_v": "Core Media Video", "handler_a": "Core Media Audio", "fnumber": 1.78, "focal": 6.86 }, { "make": "Samsung", "model": "SM-S928B", "lens": "Galaxy S24 Ultra Main Camera 6.3mm f/1.7", "software": "UP1A.231005.007.S928BXXU1AXB5", "handler_v": "VideoHandle", "handler_a": "SoundHandle", "fnumber": 1.7, "focal": 6.3 } ] if user_make or user_model: selected_profile = { "make": user_make if user_make else "Apple", "model": user_model if user_model else "iPhone 15 Pro", "lens": "iPhone Camera Lens 6.86mm f/1.78", "software": "17.5.1", "handler_v": "Core Media Video", "handler_a": "Core Media Audio", "fnumber": 1.78, "focal": 6.86 } else: selected_profile = random.choice(profiles) selected_profile["creation_time"] = creation_time_str selected_profile["lat_num"] = lat_num selected_profile["lon_num"] = lon_num selected_profile["location_str"] = location_str metadata_args = [ '-map_metadata', '-1', '-metadata', f'location={location_str}', '-metadata', f'location-eng={location_str}', '-metadata', f'make={selected_profile["make"]}', '-metadata', f'model={selected_profile["model"]}', '-metadata', f'software={selected_profile["software"]}', '-metadata', f'creation_time={creation_time_str}', '-metadata', 'encoder=', '-metadata:s:v:0', 'encoder=', '-metadata:s:v:0', f'handler_name={selected_profile["handler_v"]}', '-metadata:s:a:0', 'encoder=', '-metadata:s:a:0', f'handler_name={selected_profile["handler_a"]}', ] return metadata_args, selected_profile def apply_exiftool_metadata(file_path, profile): exiftool_bin = shutil.which("exiftool") if not exiftool_bin: return "⚠️ UYARI: System ExifTool bulunamadı!" try: iso_val = random.choice([50, 64, 100, 125, 200]) lat = abs(profile.get("lat_num", 40.7128)) lat_ref = "N" if profile.get("lat_num", 40.7128) >= 0 else "S" lon = abs(profile.get("lon_num", -74.0060)) lon_ref = "E" if profile.get("lon_num", -74.0060) >= 0 else "W" make_val = profile.get("make", "Apple") model_val = profile.get("model", "iPhone 15 Pro") soft_val = profile.get("software", "17.5.1") c_time = profile.get("creation_time", "") exif_cmd = [ exiftool_bin, '-overwrite_original', '-XMP-all=', f'-Make={make_val}', f'-Model={model_val}', f'-Keys:Make={make_val}', f'-Keys:Model={model_val}', f'-LensModel={profile.get("lens")}', f'-Software={soft_val}', f'-ISO={iso_val}', f'-FNumber={profile.get("fnumber", 1.78)}', f'-FocalLength={profile.get("focal", 6.86)} mm', f'-CreateDate={c_time}', f'-ModifyDate={c_time}', f'-TrackCreateDate={c_time}', f'-TrackModifyDate={c_time}', f'-MediaCreateDate={c_time}', f'-MediaModifyDate={c_time}', f'-GPSLatitude={lat}', f'-GPSLatitudeRef={lat_ref}', f'-GPSLongitude={lon}', f'-GPSLongitudeRef={lon_ref}', '-CompressorName=H.264', '-video:CompressorName=H.264', '-Encoder=', '-Keys:Encoder=', '-UserData:Encoder=', '-ItemList:Encoder=', f'-HandlerName={profile.get("handler_v", "Core Media Video")}', file_path ] subprocess.run(exif_cmd, capture_output=True) return "✅ ExifTool: Derin EXIF bilgileri & H.264 mühürlemesi uygulandı." except Exception as e: return f"⚠️ ExifTool Hatası: {e}" @spaces.GPU # ZeroGPU Etiketi def process_video_web(video_file, user_date, user_loc, user_make, user_model): if video_file is None: return None, "❌ Lütfen bir video yükleyin!" # Gradio dosya nesnesinden dosya yolunu alma input_file = video_file.name if hasattr(video_file, 'name') else str(video_file) output_file = "/tmp/ozgunlestirilmis_video.mp4" if os.path.exists(output_file): os.remove(output_file) logs = [] logs.append("⚡ v10.2 Anti-Detection Engine Başlatılıyor (ZeroGPU Active)...") raw_duration = get_video_duration(input_file) or 60.0 audio_exists = has_audio_stream(input_file) trim_start = round(random.uniform(0.3, 0.6), 3) trim_end = round(random.uniform(0.3, 0.6), 3) if raw_duration > (trim_start + trim_end + 3.0): effective_dur = raw_duration - trim_start - trim_end trim_end_pts = raw_duration - trim_end else: trim_start, trim_end_pts = 0.0, raw_duration effective_dur = raw_duration cut_duration = round(random.uniform(0.3, 0.5), 3) cut_start_relative = round(effective_dur * random.uniform(0.4, 0.6), 3) cut_end_relative = cut_start_relative + cut_duration logs.append(f"✂️ Jump-Cut: {cut_start_relative}s anından {cut_duration}s kesildi.") target_fps = random.choice([29.97, 30.0, 59.94, 60.0]) gop_size = "30" if target_fps in [29.97, 30.0] else "60" brightness = round(random.uniform(-0.012, 0.018), 3) contrast = round(random.uniform(1.01, 1.03), 3) speed = round(random.uniform(0.98, 1.02), 3) p1_start = trim_start p1_end = trim_start + cut_start_relative p2_start = trim_start + cut_end_relative p2_end = trim_end_pts filter_parts = [] filter_parts.append(f"[0:v]trim=start={p1_start:.3f}:end={p1_end:.3f},setpts=PTS-STARTPTS[v1]") filter_parts.append(f"[0:v]trim=start={p2_start:.3f}:end={p2_end:.3f},setpts=PTS-STARTPTS[v2]") filter_parts.append("[v1][v2]concat=n=2:v=1:a=0[v_jumped]") cbh_val = random.choice([-1, 1]) chroma_shift = f"chromashift=cbh={cbh_val}:cbv={-cbh_val}:crh={-cbh_val}:crv={cbh_val}" unsharp_val = round(random.uniform(0.35, 0.60), 3) v_fx = ( f"[v_jumped]hflip[v_flipped]; " f"[v_flipped]scale=1120:1980,rotate=0.005:c=black[v_rot]; " f"[v_rot]crop=iw-4:ih-4:'2+1.2*sin(n*0.15)':'2+1.2*cos(n*0.15)'," f"{chroma_shift}," f"unsharp=luma_msize_x=5:luma_msize_y=5:luma_amount={unsharp_val}," f"eq=brightness={brightness}:contrast={contrast}:saturation=1.01," f"colorbalance=rs=0.01:bs=-0.01,vignette=PI/6," f"crop=1080:1920:(iw-1080)/2+12*sin(n*0.025):(ih-1920)/2+12*cos(n*0.025)," f"noise=alls=7:allf=t+u," f"setpts=(PTS-STARTPTS)/{speed}," f"fps={target_fps},scale=1080:1920,setsar=1,format=yuv420p[vout_final]" ) filter_parts.append(v_fx) map_args = ['-map', '[vout_final]'] audio_codec_args = [] if audio_exists: filter_parts.append(f"[0:a]atrim=start={p1_start:.3f}:end={p1_end:.3f},asetpts=PTS-STARTPTS[a1]") filter_parts.append(f"[0:a]atrim=start={p2_start:.3f}:end={p2_end:.3f},asetpts=PTS-STARTPTS[a2]") filter_parts.append("[a1][a2]concat=n=2:v=0:a=1[a_jumped]") pitch_factor = round(random.choice([0.97, 0.98, 1.02, 1.03]), 3) inv_pitch = round(1 / pitch_factor, 6) new_rate = int(48000 * pitch_factor) audio_delay_ms = random.randint(15, 30) a_fx = ( f"[a_jumped]atempo={speed}," f"asetrate={new_rate},atempo={inv_pitch}," f"highpass=f=80,equalizer=f=850:width_type=q:width=1:g=-5," f"aecho=0.8:0.85:12:0.08,bass=g=2:f=80,treble=g=1.5:f=12000," f"adelay={audio_delay_ms}|{audio_delay_ms},volume=1.02,aresample=48000,apad[aout_final]" ) filter_parts.append(a_fx) map_args += ['-map', '[aout_final]'] audio_codec_args = ['-c:a', 'aac', '-b:a', '192k', '-ac', '2', '-ar', '48000'] filter_complex = "; ".join(filter_parts) metadata_args, profile_data = generate_fake_metadata_args(user_date, user_loc, user_make, user_model) cmd = [ 'ffmpeg', '-i', input_file, '-filter_complex', filter_complex, *map_args, '-c:v', 'libx264', '-crf', '22', '-preset', 'fast', '-g', gop_size, '-bf', '0', '-bsf:v', 'filter_units=remove_types=6', '-brand', 'mp42', '-color_primaries', 'bt709', '-color_trc', 'bt709', '-colorspace', 'bt709', '-color_range', 'tv', *audio_codec_args, '-pix_fmt', 'yuv420p', '-movflags', '+faststart', '-shortest', *metadata_args, '-y', output_file ] res = subprocess.run(cmd, capture_output=True, text=True) if res.returncode == 0: exif_log = apply_exiftool_metadata(output_file, profile_data) logs.append(exif_log) logs.append("🎉 Video Başarıyla Özgünleştirildi!") return output_file, "\n".join(logs) else: logs.append("❌ FFmpeg Hatası:") logs.append(res.stderr[-400:]) return None, "\n".join(logs) # Gradio Mobil Uyumlu Arayüz Tasarımı with gr.Blocks(title="Sosyal Medya Video Özgünleştirici Pro v10.2") as demo: gr.Markdown( """ # ⚡ Sosyal Medya Video Özgünleştirici Pro (v10.2 ZeroGPU) """ ) with gr.Row(): with gr.Column(): video_input = gr.File(label="📹 Videonuzu Yükleyin (.mp4, .mov)", file_types=[".mp4", ".mov", ".mkv"]) with gr.Accordion("📝 Özel Metadata & Cihaz Ayarları (Opsiyonel)", open=False): user_date = gr.Textbox(label="Tarih", placeholder="YYYY-MM-DDTHH:MM:SSZ") user_loc = gr.Textbox(label="GPS Konum", placeholder="+40.7128-74.0060/") user_make = gr.Textbox(label="Marka", placeholder="Apple / Samsung") user_model = gr.Textbox(label="Model", placeholder="iPhone 15 Pro") btn_submit = gr.Button("🚀 Videoyu Özgünleştir", variant="primary") with gr.Column(): video_output = gr.Video(label="✅ Özgünleştirilmiş Video") log_output = gr.Textbox(label="📋 İşlem Logları", lines=8) btn_submit.click( fn=process_video_web, inputs=[video_input, user_date, user_loc, user_make, user_model], outputs=[video_output, log_output] ) if __name__ == "__main__": demo.queue().launch(ssr_mode=False)