darkmedia-x-api / docs /RUST_REFACTOR_PLAN.md
cybermedia's picture
Upload folder using huggingface_hub
343eed9 verified

A newer version of the Gradio SDK is available: 6.16.0

Upgrade

Plan de Refonte Rust - DarkMedia-X Studio

Contexte

Le projet utilise actuellement un mix Python/Rust. L'objectif est de migrer le maximum de logique Python vers Rust pour la performance et la fiabilite. Le code compile et fonctionne sur la branche main.

Etat Actuel

Deja en Rust (Engine/src/)

  • main.rs - Point d'entree, decouverte des histoires, boucle principale
  • scene.rs - Extraction des scenes depuis les fichiers markdown
  • config.rs - Configuration depuis variables d'environnement
  • generators/ - Wrappers Rust qui appellent Python via Command::new("python")
    • wan2.rs, ssd.rs, open_sora.rs, ollama.rs, api_router.rs, moviepy.rs
  • renderer/ - Squelettes non-utilises (image_processor, vfx, depth, animation, postprocessing)
  • progress_tracker.rs, optimization.rs, orchestrator.rs, ml_backend.rs

Encore en Python (a migrer)

  • story_to_video.py (47KB) - Orchestrateur principal video
  • asset_generator.py (24KB) - Generation d'assets
  • renderers/moviepy_renderer.py - Rendu video MoviePy
  • audio_analyzer.py - Analyse BPM avec librosa
  • prompt_remixer.py - Remix de prompts
  • chroma_store.py / qdrant_store.py - Stores vectoriels
  • vfx/opencv_effects.py - Effets visuels OpenCV
  • optimizations/memory_manager.py - Gestion memoire

StudioHub (Rust - GUI)

  • StudioHub/src/main.rs (55KB) - Application egui complete, deja en Rust

Etapes de Migration (par priorite)

Phase 1: Rendu Video Natif Rust (Remplacer MoviePy)

Fichiers concernes: Engine/src/generators/moviepy.rs, Engine/renderers/moviepy_renderer.py

Objectif: Remplacer l'appel Python MoviePy par du Rust natif.

Implementation:

  1. Ajouter ces dependances dans Engine/Cargo.toml:
ffmpeg-next = "7"  # ou ffmpeg-cli-wrapper si ffmpeg-next pose probleme
image = "0.25"
  1. Creer Engine/src/video_assembler.rs:
// Assembler les images PNG en video MP4 via ffmpeg CLI
// Input: dossier assets/images/ avec scene_1.png, scene_2.png, etc.
// Output: output.mp4 dans le dossier de l'histoire
//
// Algorithme:
// 1. Lister toutes les images scene_*.png triees par numero
// 2. Pour chaque image, appliquer un effet Ken Burns (zoom lent) via ffmpeg
// 3. Concatener les clips en une seule video
// 4. Ajouter la musique si presente (fichier music.mp3 dans le dossier)
// 5. Ajouter les sous-titres si texte overlay present
//
// Commande ffmpeg type pour chaque scene:
// ffmpeg -loop 1 -i scene_1.png -vf "zoompan=z='min(zoom+0.001,1.5)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=150:s=1080x1920" -t 5 -c:v libx264 clip_1.mp4
//
// Concatenation:
// ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
//
// Ajout musique:
// ffmpeg -i output.mp4 -i music.mp3 -c:v copy -c:a aac -shortest final.mp4
  1. Dans main.rs, remplacer MoviePyRenderer par VideoAssembler dans TOUS les modes (wan2, ssd, opensora, etc.)

Note importante: L'approche la plus pragmatique est d'utiliser ffmpeg en CLI (deja installe sur la machine) plutot que des bindings Rust complexes. C'est ce que fait deja le code pour l'extraction de frames dans wan2.rs.


Phase 2: Effets Visuels Natifs (Remplacer OpenCV Python)

Fichiers concernes: Engine/src/renderer/vfx.rs, Engine/src/renderer/image_processor.rs, Engine/vfx/opencv_effects.py

Objectif: Les squelettes Rust existent deja mais ne sont pas utilises. Les completer.

Implementation:

  1. Les fichiers renderer/vfx.rs et renderer/image_processor.rs ont deja du code fonctionnel (grain, blur, glitch, vignette, saturation). Il faut:

    • Les connecter dans le pipeline principal (main.rs)
    • Appliquer les effets sur chaque image AVANT l'assemblage video
    • Ajouter un parametre VFX dans la config (ex: VFX_PROFILE=cinematic_dark)
  2. Dans main.rs, apres generation de chaque image:

// Charger l'image
let img = image::open(&img_file)?;
// Appliquer les effets selon le profil
let processed = renderer::vfx::apply_vfx(img, vfx_profile)?;
// Sauvegarder
processed.save(&img_file)?;

Phase 3: Analyse Audio Rust (Remplacer librosa)

Fichiers concernes: Engine/audio_analyzer.py, nouveau Engine/src/audio_analyzer.rs

Objectif: Extraire BPM et beats en Rust natif.

Implementation:

  1. Ajouter dans Engine/Cargo.toml:
rodio = "0.19"
symphonia = { version = "0.5", features = ["mp3", "wav", "ogg"] }
rustfft = "6"
  1. Creer Engine/src/audio_analyzer.rs:
// Analyse audio: BPM detection et beat timing
//
// Algorithme simplifie:
// 1. Decoder le fichier audio (MP3/WAV) avec symphonia
// 2. Convertir en mono, resampler a 22050 Hz
// 3. Calculer onset strength (energie spectrale frame par frame)
//    - FFT sur des fenetres de 2048 samples, hop 512
//    - Calculer la difference d'energie entre frames consecutives
// 4. Autocorrelation pour detecter le BPM dominant
// 5. Peak detection sur onset strength pour les positions de beats
//
// Struct de retour:
pub struct AudioAnalysis {
    pub bpm: f32,
    pub beat_times: Vec<f32>,      // en secondes
    pub intensity_curve: Vec<f32>, // normalise 0.0-1.0
    pub duration: f32,             // duree totale en secondes
}

Phase 4: Store Vectoriel Qdrant Natif

Fichiers concernes: Engine/qdrant_store.py, nouveau Engine/src/qdrant_client.rs

Objectif: Appels Qdrant directement depuis Rust.

Implementation:

  1. Ajouter dans Engine/Cargo.toml:
qdrant-client = "1"
  1. Creer Engine/src/qdrant_client.rs:
// Client Qdrant pour le RAG
// Variables d'env utilisees:
//   QDRANT_URL (deja dans .env racine)
//   QDRANT_API_KEY (deja dans .env racine)
//   QDRANT_COLLECTION_NAME (deja dans .env racine)
//
// Fonctions:
// - search_similar(query_vector, limit) -> Vec<StoryMetadata>
// - upsert_story(story_id, vector, metadata)
// - check_duplicate(vector, threshold) -> bool

Phase 5: Prompt Remixer Natif

Fichiers concernes: Engine/prompt_remixer.py, nouveau Engine/src/prompt_remixer.rs

Objectif: Remixer les prompts localement ou via API.

Note: Comme l'utilisateur n'utilise plus d'API externes (sauf Qdrant), cette fonctionnalite devrait utiliser Ollama en local:

// Appeler Ollama pour remixer un prompt avec un style musical
// POST http://127.0.0.1:11434/api/generate
// Body: { "model": "llama3", "prompt": "Remix this image prompt with musical energy: ..." }

Phase 6: Nettoyage et Unification

  1. Supprimer les fichiers Python redondants une fois les equivalents Rust fonctionnels
  2. Unifier la configuration - tout dans config.rs, plus de .env separes
  3. Supprimer les warnings - cargo fix --bin asset_generator (97 warnings actuels)
  4. Connecter les modules renderer/ qui sont des squelettes inutilises (postprocessing.rs, animation.rs, depth.rs)

Fichiers Cles a Modifier

Fichier Action
Engine/Cargo.toml Ajouter dependances (ffmpeg, symphonia, rustfft, qdrant-client)
Engine/src/main.rs Remplacer MoviePyRenderer par VideoAssembler, ajouter VFX pipeline
Engine/src/video_assembler.rs NOUVEAU - Assemblage video via ffmpeg CLI
Engine/src/audio_analyzer.rs NOUVEAU - Analyse BPM/beats
Engine/src/qdrant_client.rs NOUVEAU - Client Qdrant natif
Engine/src/prompt_remixer.rs NOUVEAU - Remix prompts via Ollama
Engine/src/renderer/vfx.rs Connecter dans le pipeline
Engine/src/renderer/image_processor.rs Connecter dans le pipeline
Engine/src/generators/moviepy.rs A SUPPRIMER apres Phase 1

Architecture Cible

Engine/src/
  main.rs              -- Point d'entree
  config.rs            -- Configuration unifiee
  scene.rs             -- Parsing markdown -> scenes
  video_assembler.rs   -- NEW: Images -> MP4 (ffmpeg CLI)
  audio_analyzer.rs    -- NEW: BPM/beats (natif Rust)
  qdrant_client.rs     -- NEW: RAG vectoriel
  prompt_remixer.rs    -- NEW: Remix via Ollama
  generators/
    wan2.rs            -- Generation Wan2 (appel Python - difficile a migrer)
    ssd.rs             -- Generation SSD-1B (appel Python - difficile a migrer)
    open_sora.rs       -- Generation OpenSora (appel Python - difficile a migrer)
    ollama.rs          -- LLM local
  renderer/
    vfx.rs             -- Effets visuels (grain, glitch, vignette)
    image_processor.rs -- Traitement image (resize, color grade)
    postprocessing.rs  -- Post-prod (contrast, saturation)
    depth.rs           -- Cartes de profondeur
    animation.rs       -- Ken Burns, pan, zoom

Ce Qui RESTE en Python (impossible a migrer)

Les generateurs d'images IA (wan2, ssd, open_sora) doivent rester en Python car:

  • Les modeles PyTorch/diffusers n'ont pas d'equivalent Rust mature
  • Le code Rust les appelle deja via Command::new("python") ce qui est la bonne approche
  • Migrer necessiterait des bindings ONNX/TensorRT complexes

Commandes Utiles

# Compiler
cd Engine && cargo build --release

# Tester le parseur de scenes
cargo run --release -- --test-parse "../../stories/Quebec/La Chasse-Galerie/story.md"

# Lancer le generateur
cd Engine && launch_generator.bat

# Lancer le StudioHub
cd StudioHub && cargo run --release

Fixes Deja Appliques (ne pas refaire)

  • scene.rs: Reecrit sans regex, gere "scene" et "scene" (accent)
  • main.rs: Mode wan2 a maintenant update_task_json + assemblage video
  • story_to_video.py: Fix variable scene_idx dans add_dynamic_subtitles
  • launch_generator.bat: IMAGE_GEN_MODE aligne sur wan2
  • .env racine: Nettoye, garde seulement QDRANT_*
  • current_task.json: Reset a l'etat initial