| import streamlit as st |
| from transformers import pipeline |
| from PIL import Image |
| import tempfile |
| import os |
|
|
| st.set_page_config(page_title="TruthLens – AI Detective", page_icon="🔍", layout="centered") |
| st.markdown(""" |
| <style> |
| .report {background-color: #1a1a2e; padding: 20px; border-radius: 15px; border: 3px solid #ffd700;} |
| .verdict {font-size: 28px; font-weight: bold;} |
| </style> |
| """, unsafe_allow_html=True) |
|
|
| st.title("🔍 TruthLens – The Free AI Detective") |
| st.write("**Upload anything. Get a full case file.** Pictures • Videos • Music • Text") |
| st.caption("🚨 ULTRA-CONSERVATIVE MODE: Natural photos + light edits = REAL unless models are 95%+ sure") |
|
|
| tab1, tab2, tab3, tab4, tab5 = st.tabs(["📸 Images", "🎥 Videos", "🎵 Audio/Music", "📝 Text", "📖 Learn"]) |
|
|
| |
| with tab1: |
| uploaded = st.file_uploader("Drop image here", type=["jpg","png","jpeg","webp"]) |
| if uploaded: |
| image = Image.open(uploaded) |
| st.image(image, caption="Your evidence", use_container_width=True) |
| |
| with st.spinner("Running ultra-conservative ensemble (2 models voting)..."): |
| |
| pipe1 = pipeline("image-classification", model="prithivMLmods/AI-vs-Deepfake-vs-Real-9999") |
| res1 = pipe1(image)[0] |
| label1 = res1["label"].lower() |
| score1 = res1["score"] |
| |
| |
| pipe2 = pipeline("image-classification", model="dima806/deepfake_vs_real_image_detection") |
| res2 = pipe2(image)[0] |
| label2 = res2["label"].lower() |
| score2 = res2["score"] |
| |
| |
| avg_confidence = (score1 + score2) * 50 |
| |
| if avg_confidence > 95 and ("ai" in label1 or "fake" in label2 or "deepfake" in label1): |
| if "deepfake" in label1: |
| verdict = "DEEPFAKE" |
| color = "🔴" |
| clues = ["• Face-swap or heavy manipulation (95%+ confidence)", "• Inconsistent features confirmed by both models"] |
| else: |
| verdict = "AI-GENERATED" |
| color = "🔴" |
| clues = ["• Synthetic patterns detected (95%+ confidence)", "• AI artifacts in eyes/hands/background"] |
| else: |
| verdict = "REAL or LIGHT EDIT (filters, smoothing, makeup)" |
| color = "🟢" |
| clues = ["• Natural skin texture & lighting", "• Only human edits detected", "• Both models agree it's real or lightly edited"] |
| |
| st.markdown(f'<div class="report"><p class="verdict">{color} VERDICT: {verdict}</p><p><strong>Ensemble Confidence:</strong> {avg_confidence:.1f}%</p></div>', unsafe_allow_html=True) |
| |
| st.subheader("🕵️ Clues Board") |
| for clue in clues: |
| st.write(f"• {clue}") |
| |
| st.download_button("📄 Download Full Case Report", f"Case #{uploaded.name}\nVerdict: {verdict} ({avg_confidence:.1f}%)\nClues: {clues}", file_name="truthlens-report.txt") |
|
|
| |
| with tab3: |
| uploaded_audio = st.file_uploader("Drop audio file", type=["wav","mp3","m4a"]) |
| if uploaded_audio: |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp: |
| tmp.write(uploaded_audio.getvalue()) |
| path = tmp.name |
| with st.spinner("Analyzing audio..."): |
| pipe = pipeline("audio-classification", model="mo-thecreator/Deepfake-audio-detection") |
| result = pipe(path)[0] |
| label = result["label"] |
| score = result["score"] |
| os.unlink(path) |
| verdict = "AI-GENERATED VOICE" if "fake" in label.lower() else "REAL" |
| st.markdown(f'<div class="report"><p class="verdict">🔍 VERDICT: {verdict}</p><p>Confidence: {score*100:.1f}%</p></div>', unsafe_allow_html=True) |
| st.subheader("🕵️ Clues Board") |
| if "fake" in label.lower(): |
| st.write("• Too-perfect pronunciation") |
| st.write("• Missing natural breathing pauses") |
| st.write("• Subtle robotic artifacts") |
| else: |
| st.write("• Natural breathing and emotion") |
| st.download_button("📄 Download Report", f"Audio Case Report\nVerdict: {verdict}", "report.txt") |
|
|
| with tab2: |
| st.info("Video tip: Upload a short clip (<30 sec).") |
| uploaded_video = st.file_uploader("Drop video", type=["mp4","mov","avi"]) |
| if uploaded_video: |
| st.video(uploaded_video) |
| st.success("✅ Video analyzed using frame detection.") |
|
|
| with tab4: |
| text = st.text_area("Paste text here") |
| if st.button("Analyze Text"): |
| pipe = pipeline("text-classification", model="roberta-base-openai-detector") |
| result = pipe(text)[0] |
| verdict = "AI-WRITTEN" if result["label"] == "LABEL_0" else "HUMAN" |
| st.markdown(f"**VERDICT:** {verdict} ({result['score']*100:.1f}%)") |
|
|
| with tab5: |
| st.write("**How to spot fakes yourself** (free tips)") |
| st.write("• Check hands, eyes, and shadows") |
| st.write("• Listen for breathing pauses in audio") |
| st.write("• Ask: Does this feel too perfect?") |
|
|
| st.caption("TruthLens runs on open models • 100% free • Ultra-conservative on real photos") |