Abmacode12 commited on
Commit
898a131
·
verified ·
1 Parent(s): df47c2a

CODE D'INTÉGRATION POUR LA BALEINE IA

Browse files

1. HTML - Interface de La Baleine (à ajouter dans la section appropriée) :
html
<!-- Interface La Baleine IA -->
<div id="interface-baleine" style="display: none;" class="interface-ia">

<!-- En-tête -->
<div class="ia-header" style="padding: 20px; background: linear-gradient(135deg, #1a237e, #4fc3f7); color: white; border-radius: 12px 12px 0 0;">
<h2 style="margin: 0;">🐋 La Baleine IA - Générateur Multimédia</h2>
<p style="margin: 5px 0 0 0; opacity: 0.9;">Génération d'images et vidéos par IA - Explications en temps réel</p>
</div>

<!-- Contenu principal -->
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding: 20px; height: 70vh;">

<!-- Colonne gauche : Chat et explications -->
<div class="colonne-gauche" style="display: flex; flex-direction: column;">
<div id="chat-baleine" style="flex-grow: 1; overflow-y: auto; background: #f8f9fa; border-radius: 10px; padding: 15px; margin-bottom: 15px;">
<div class="message-ia">
<strong>🐋 La Baleine :</strong> Bonjour ! Je suis votre générateur IA multimédia. Décrivez une scène, et je créerai l'image ou la vidéo correspondante tout en vous expliquant le processus.
</div>
</div>

<div id="explications-baleine" style="background: #e8f5e9; border: 1px solid #c8e6c9; border-radius: 8px; padding: 12px; font-size: 14px; color: #2e7d32;">
<strong>📊 Explications en direct :</strong> En attente de votre demande...
</div>
</div>

<!-- Colonne droite : Résultats visuels -->
<div class="colonne-droite" style="display: flex; flex-direction: column;">
<div id="resultats-baleine" style="flex-grow: 1; background: #263238; border-radius: 10px; padding: 20px; overflow-y: auto; text-align: center;">
<h4 style="color: #4fc3f7; margin-top: 0;">🎬 Zone de Génération</h4>
<div id="media-container" style="min-height: 300px; display: flex; align-items: center; justify-content: center; color: #78909c;">
<p>Votre média généré apparaîtra ici</p>
</div>
</div>

<div class="controles-baleine" style="margin-top: 15px; display: flex; gap: 10px;">
<button onclick="telechargerMediaBaleine()" class="btn-success" style="flex: 1;">
📥 Télécharger
</button>
<button onclick="regenererMediaBaleine()" class="btn-warning" style="flex: 1;">
🔄 Regénérer
</button>
</div>
</div>
</div>

<!-- Zone de saisie et contrôles -->
<div style="padding: 15px 20px; background: #f5f5f5; border-radius: 0 0 12px 12px; border-top: 1px solid #ddd;">
<div style="display: flex; gap: 10px; align-items: center;">
<input type="text"
id="input-baleine"
placeholder="Décrivez votre image ou vidéo (ex: 'un dragon volant au coucher du soleil')"
style="flex-grow: 1; padding: 12px; border: 2px solid #4fc3f7; border-radius: 8px; font-size: 16px;">

<button onclick="envoyerPromptBaleine()"
style="background: #4fc3f7; color: white; border: none; padding: 12px 25px; border-radius: 8px; font-weight: bold; cursor: pointer;">
🚀 Générer
</button>

<button onclick="activerMicroBaleine()"
id="btn-micro-baleine"
style="background: #ff4081; color: white; border: none; padding: 12px; border-radius: 8px; cursor: pointer;">
🎤 Micro
</button>
</div>

<div style="margin-top: 10px; display: flex; gap: 15px; font-size: 14px;">
<label>
<input type="radio" name="type-media" value="image" checked> 🖼️ Image
</label>
<label>
<input type="radio" name="type-media" value="video"> 🎬 Vidéo
</label>
<label>
<input type="radio" name="type-media" value="animation"> ✨ Animation
</label>
</div>
</div>
</div>
2. JavaScript - Moteur de La Baleine :
javascript
// ============================================
// 🐋 MOTEUR DE LA BALEINE IA - GÉNÉRATEUR MULTIMÉDIA
// ============================================

class BaleineIA {
constructor() {
this.config = {
apiKey: "hf_votre_cle_api_gratuite", // À remplacer
endpoints: {
image: "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
video: "https://api-inference.huggingface.co/models/cerspense/zeroscope_v2_576w"
},
maxSteps: 50,
guidanceScale: 7.5
};

this.mediaCourant = null;
this.recognizer = null;
this.ecouteActive = false;

this.init();
}

init() {
console.log("🐋 La Baleine IA initialisée - Version Générateur Multimédia");
this.setupEventListeners();
this.setupReconnaissanceVocale();
}

setupEventListeners() {
// Saisie clavier
const input = document.getElementById('input-baleine');
if (input) {
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') this.processerDemande(input.value);
});
}

// Activation via le menu
const menuBaleine = document.querySelector('[href*="Baleine"], [onclick*="Baleine"]');
if (menuBaleine) {
menuBaleine.addEventListener('click', (e) => {
e.preventDefault();
this.afficherInterface();
});
}
}

setupReconnaissanceVocale() {
if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
this.recognizer = new SpeechRecognition();
this.recognizer.lang = 'fr-FR';
this.recognizer.continuous = false;
this.recognizer.interimResults = false;

this.recognizer.onresult = (event) => {
const transcription = event.results[0][0].transcript;
document.getElementById('input-baleine').value = transcription;
this.processerDemande(transcription);
this.ecouteActive = false;
document.getElementById('btn-micro-baleine').style.background = '#ff4081';
};

this.recognizer.onerror = (event) => {
console.error("Erreur reconnaissance vocale:", event.error);
this.ecouteActive = false;
document.getElementById('btn-micro-baleine').style.background = '#ff4081';
};
}
}

afficherInterface() {
document.getElementById('interface-baleine').style.display = 'block';
this.afficherMessageIA("Interface activée ! Prêt à générer des médias.");
}

// ==================== PROCESSUS PRINCIPAL ====================

async processerDemande(prompt) {
if (!prompt.trim()) return;

// 1. Afficher la demande utilisateur
this.afficherMessageUtilisateur(prompt);

// 2. Déterminer le type de média
const typeMedia = this.determinerTypeMedia(prompt);

// 3. Explications étape par étape
await this.expliquerProcessus(prompt, typeMedia);

// 4. Génération réelle
try {
const resultat = await this.genererMedia(prompt, typeMedia);
this.afficherResultat(resultat, prompt, typeMedia);
this.afficherMessageIA(`✅ Génération réussie ! "${prompt}" est maintenant disponible.`);
} catch (error) {
this.afficherMessageIA(`❌ Erreur : ${error.message}. Tentative avec un modèle de secours...`);
await this.genererSecours(prompt, typeMedia);
}
}

async expliquerProcessus(prompt, typeMedia) {
const etapes = [
"Analyse sémantique de votre demande...",
"Extraction des mots-clés et contexte...",
`Préparation du modèle ${typeMedia === 'image' ? 'd\'image' : 'de vidéo'}...`,
"Configuration des paramètres de génération...",
"Lancement de l'inférence IA...",
"Post-traitement et optimisation..."
];

for (let i = 0; i < etapes.length; i++) {
this.afficherExplication(`Étape ${i+1}/${etapes.length}: ${etapes[i]}`);
await this.delai(600); // Pause pour effet réaliste
}
}

async genererMedia(prompt, type) {
this.afficherExplication("⚙️ Connexion à l'API de génération...");

const endpoint = type === 'image' ? this.config.endpoints.image : this.config.endpoints.video;

const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.config.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
inputs: prompt,
parameters: {
num_inference_steps: this.config.maxSteps,
guidance_scale: this.config.guidanceScale,
width: type === 'image' ? 768 : 576,
height: type === 'image' ? 768 : 320
}
})
});

if (!response.ok) {
throw new Error(`API non disponible (${response.status})`);
}

this.afficherExplication("✅ Génération terminée ! Traitement du résultat...");

const blob = await response.blob();
const url = URL.createObjectURL

Files changed (1) hide show
  1. baleine.html +396 -141
baleine.html CHANGED
@@ -35,172 +35,427 @@
35
  </aside>
36
  <!-- Main Content -->
37
  <main class="flex-1 bg-gray-850/50 overflow-auto">
38
- <div class="interface-baleine" style="display: grid; grid-template-columns: 1fr 2fr 2fr; gap: 20px; padding: 20px; height: 80vh;">
39
-
40
- <!-- COLONNE GAUCHE (existante - projets/raccourcis) -->
41
- <div class="colonne-gauche">
42
- <!-- Laisse le contenu existant -->
43
- <h3>PROJETS</h3>
44
- <ul>
45
- <li>Espace Codage - Projet 1</li>
46
- <li>Espace Codage - Projet 2</li>
47
- </ul>
48
- <h3>RACCOURCIS</h3>
49
- <ul>
50
- <li>Rosalinda IA</li>
51
- <li>Bibliothèque</li>
52
- <li>Paramètres</li>
53
- </ul>
54
  </div>
55
-
56
- <!-- COLONNE CENTRALE : Conversation + Explications -->
57
- <div class="colonne-centrale" style="background: #f8f9fa; border-radius: 12px; padding: 20px; display: flex; flex-direction: column;">
58
- <h3>🐋 Conversation avec La Baleine</h3>
59
 
60
- <div id="chat-baleine" style="flex-grow: 1; overflow-y: auto; margin-bottom: 15px; padding: 10px; background: white; border-radius: 8px;">
61
- <!-- Messages apparaîtront ici -->
62
- <div class="message-baleine">
63
- <strong>La Baleine :</strong> Bonjour ! Je suis prête à générer des images ou vidéos pour toi. Décris-moi ce que tu veux voir.
 
 
 
 
 
 
64
  </div>
65
  </div>
66
-
67
- <div id="explications-baleine" style="background: #e3f2fd; padding: 15px; border-radius: 8px; margin-bottom: 15px; font-size: 14px;">
68
- <strong>🔄 Explications en direct :</strong> En attente de votre demande...
69
- </div>
70
-
71
- <div style="display: flex; gap: 10px;">
72
- <input
73
- type="text"
74
- id="input-message"
75
- placeholder="Ex : 'Génère une forêt magique sous la lune'"
76
- style="flex-grow: 1; padding: 12px; border: 1px solid #ccc; border-radius: 8px;"
77
- >
78
- <button onclick="envoyerMessage()" style="padding: 12px 20px; background: #007bff; color: white; border: none; border-radius: 8px;">
79
- Envoyer
80
- </button>
 
 
 
81
  </div>
82
  </div>
83
-
84
- <!-- COLONNE DROITE : Résultats images/vidéos -->
85
- <div class="colonne-droite" style="background: #1e1e1e; border-radius: 12px; padding: 20px; color: white;">
86
- <h3>🎬 Résultats générés</h3>
87
- <div id="resultats-visuels" style="margin-top: 15px; text-align: center;">
88
- <p style="color: #aaa;">Les images/vidéos générées apparaîtront ici.</p>
89
- <!-- Les médias générés s'afficheront ici -->
 
 
 
 
 
 
 
 
 
 
 
 
90
  </div>
91
- <div style="margin-top: 20px;">
92
- <label style="display: block; margin-bottom: 8px;">Type de génération :</label>
93
- <select id="type-generation" style="width: 100%; padding: 8px; border-radius: 6px; background: #333; color: white;">
94
- <option value="image">🖼️ Image</option>
95
- <option value="video">🎬 Vidéo courte</option>
96
- <option value="animation">✨ Animation</option>
97
- </select>
 
 
 
 
98
  </div>
99
  </div>
100
  </div>
101
  </main>
102
- </div>
103
  <script>
104
  feather.replace();
 
 
 
 
105
 
106
- // Configuration
107
- const BALEINE_CONFIG = {
108
- imageAPI: "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-2",
109
- videoAPI: "https://api-inference.huggingface.co/models/cerspense/zeroscope_v2", // Exemple
110
- token: "TON_TOKEN_HUGGINGFACE_GRATUIT" // Obtenu sur huggingface.co
111
- };
112
-
113
- async function envoyerMessage() {
114
- const input = document.getElementById('input-message');
115
- const message = input.value.trim();
116
- if (!message) return;
117
-
118
- // Ajouter le message utilisateur au chat
119
- const chatDiv = document.getElementById('chat-baleine');
120
- chatDiv.innerHTML += `<div class="message-utilisateur" style="text-align: right; margin: 10px 0;">
121
- <strong>Vous :</strong> ${message}
122
- </div>`;
123
-
124
- // Afficher les explications en temps réel
125
- const explicationsDiv = document.getElementById('explications-baleine');
126
- explicationsDiv.innerHTML = `<strong>🔄 Explications :</strong> La Baleine analyse votre demande : "${message}"...`;
127
-
128
- // Réponse initiale de La Baleine
129
- chatDiv.innerHTML += `<div class="message-baleine" style="margin: 10px 0;">
130
- <strong>La Baleine :</strong> Je comprends ! Je vais générer "${message}" pour toi. Début de la création...
131
- </div>`;
132
-
133
- // Génération selon le type choisi
134
- const type = document.getElementById('type-generation').value;
135
- explicationsDiv.innerHTML += `<br>✓ Type sélectionné : ${type}`;
136
-
137
- try {
138
- if (type === 'image') {
139
- await genererImage(message);
140
- } else if (type === 'video') {
141
- await genererVideo(message);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
-
144
- // Message de confirmation
145
- chatDiv.innerHTML += `<div class="message-baleine" style="margin: 10px 0;">
146
- <strong>La Baleine :</strong> Génération terminée ! Regarde dans la colonne de droite.
147
- </div>`;
148
-
149
- explicationsDiv.innerHTML += `<br>✅ Génération réussie !`;
150
-
151
- } catch (error) {
152
- chatDiv.innerHTML += `<div class="message-baleine" style="color: red; margin: 10px 0;">
153
- <strong>La Baleine :</strong> Désolée, une erreur est survenue : ${error.message}
154
- </div>`;
155
  }
156
-
157
- input.value = '';
158
- chatDiv.scrollTop = chatDiv.scrollHeight;
159
  }
160
 
161
- async function genererImage(prompt) {
162
- const explicationsDiv = document.getElementById('explications-baleine');
163
- explicationsDiv.innerHTML += `<br>🖼️ Appel de l'API d'image...`;
164
 
165
- // Simulation (en production, utiliser l'API réelle)
166
- const resultatsDiv = document.getElementById('resultats-visuels');
167
- const randomSeed = Math.floor(Math.random() * 1000);
168
- const imgUrl = `https://static.photos/ai/640x360/${randomSeed}?prompt=${encodeURIComponent(prompt)}`;
169
-
170
- resultatsDiv.innerHTML = `
171
- <h4>Image générée : "${prompt}"</h4>
172
- <img src="${imgUrl}" alt="Image générée" style="max-width: 100%; border-radius: 10px; box-shadow: 0 4px 20px rgba(255,255,255,0.1);">
173
- <div style="margin-top: 15px;">
174
- <a href="${imgUrl}" download="baleine_image.png" style="background: #28a745; color: white; padding: 10px 15px; border-radius: 6px; text-decoration: none; display: inline-block;">
175
- 📥 Télécharger
176
- </a>
177
- </div>
178
- `;
179
 
180
- explicationsDiv.innerHTML += `<br>✅ Image créée et affichée à droite !`;
 
 
 
 
 
 
181
  }
182
 
183
- async function genererVideo(prompt) {
184
- const explicationsDiv = document.getElementById('explications-baleine');
185
- explicationsDiv.innerHTML += `<br>🎬 La génération vidéo peut prendre plus de temps...`;
186
 
187
- // Pour l'instant, simulation (car API vidéo sont souvent payantes)
188
- const resultatsDiv = document.getElementById('resultats-visuels');
189
- resultatsDiv.innerHTML = `
190
- <h4>Vidéo en préparation : "${prompt}"</h4>
191
- <div style="background: #333; padding: 30px; border-radius: 10px;">
192
- <p>🎥 La Baleine prépare ta vidéo... (simulation)</p>
193
- <p>En vrai, tu peux connecter une API comme Zeroscope ou Stable Video Diffusion.</p>
194
- </div>
195
- `;
 
 
 
196
 
197
- explicationsDiv.innerHTML += `<br>⚠️ Pour une vraie génération vidéo, il faut configurer une API spécifique.`;
 
 
 
 
 
 
 
 
198
  }
199
 
200
- // Permettre d'envoyer avec Entrée
201
- document.getElementById('input-message').addEventListener('keypress', (e) => {
202
- if (e.key === 'Enter') envoyerMessage();
203
- });
204
- </script>
205
  </body>
206
  </html>
 
35
  </aside>
36
  <!-- Main Content -->
37
  <main class="flex-1 bg-gray-850/50 overflow-auto">
38
+ <!-- Interface La Baleine IA -->
39
+ <div id="interface-baleine" class="interface-ia">
40
+
41
+ <!-- En-tête -->
42
+ <div class="ia-header" style="padding: 20px; background: linear-gradient(135deg, #1a237e, #4fc3f7); color: white; border-radius: 12px 12px 0 0;">
43
+ <h2 style="margin: 0;">🐋 La Baleine IA - Générateur Multimédia</h2>
44
+ <p style="margin: 5px 0 0 0; opacity: 0.9;">Génération d'images et vidéos par IA - Explications en temps réel</p>
 
 
 
 
 
 
 
 
 
45
  </div>
46
+
47
+ <!-- Contenu principal -->
48
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding: 20px; height: 70vh;">
 
49
 
50
+ <!-- Colonne gauche : Chat et explications -->
51
+ <div class="colonne-gauche" style="display: flex; flex-direction: column;">
52
+ <div id="chat-baleine" style="flex-grow: 1; overflow-y: auto; background: #f8f9fa; border-radius: 10px; padding: 15px; margin-bottom: 15px;">
53
+ <div class="message-ia">
54
+ <strong>🐋 La Baleine :</strong> Bonjour ! Je suis votre générateur IA multimédia. Décrivez une scène, et je créerai l'image ou la vidéo correspondante tout en vous expliquant le processus.
55
+ </div>
56
+ </div>
57
+
58
+ <div id="explications-baleine" style="background: #e8f5e9; border: 1px solid #c8e6c9; border-radius: 8px; padding: 12px; font-size: 14px; color: #2e7d32;">
59
+ <strong>📊 Explications en direct :</strong> En attente de votre demande...
60
  </div>
61
  </div>
62
+
63
+ <!-- Colonne droite : Résultats visuels -->
64
+ <div class="colonne-droite" style="display: flex; flex-direction: column;">
65
+ <div id="resultats-baleine" style="flex-grow: 1; background: #263238; border-radius: 10px; padding: 20px; overflow-y: auto; text-align: center;">
66
+ <h4 style="color: #4fc3f7; margin-top: 0;">🎬 Zone de Génération</h4>
67
+ <div id="media-container" style="min-height: 300px; display: flex; align-items: center; justify-content: center; color: #78909c;">
68
+ <p>Votre média généré apparaîtra ici</p>
69
+ </div>
70
+ </div>
71
+
72
+ <div class="controles-baleine" style="margin-top: 15px; display: flex; gap: 10px;">
73
+ <button onclick="telechargerMediaBaleine()" class="btn-success" style="flex: 1;">
74
+ 📥 Télécharger
75
+ </button>
76
+ <button onclick="regenererMediaBaleine()" class="btn-warning" style="flex: 1;">
77
+ 🔄 Regénérer
78
+ </button>
79
+ </div>
80
  </div>
81
  </div>
82
+
83
+ <!-- Zone de saisie et contrôles -->
84
+ <div style="padding: 15px 20px; background: #f5f5f5; border-radius: 0 0 12px 12px; border-top: 1px solid #ddd;">
85
+ <div style="display: flex; gap: 10px; align-items: center;">
86
+ <input type="text"
87
+ id="input-baleine"
88
+ placeholder="Décrivez votre image ou vidéo (ex: 'un dragon volant au coucher du soleil')"
89
+ style="flex-grow: 1; padding: 12px; border: 2px solid #4fc3f7; border-radius: 8px; font-size: 16px;">
90
+
91
+ <button onclick="envoyerPromptBaleine()"
92
+ style="background: #4fc3f7; color: white; border: none; padding: 12px 25px; border-radius: 8px; font-weight: bold; cursor: pointer;">
93
+ Générer
94
+ </button>
95
+
96
+ <button onclick="activerMicroBaleine()"
97
+ id="btn-micro-baleine"
98
+ style="background: #ff4081; color: white; border: none; padding: 12px; border-radius: 8px; cursor: pointer;">
99
+ Micro
100
+ </button>
101
  </div>
102
+
103
+ <div style="margin-top: 10px; display: flex; gap: 15px; font-size: 14px;">
104
+ <label>
105
+ <input type="radio" name="type-media" value="image" checked> 🖼️ Image
106
+ </label>
107
+ <label>
108
+ <input type="radio" name="type-media" value="video"> 🎬 Vidéo
109
+ </label>
110
+ <label>
111
+ <input type="radio" name="type-media" value="animation"> ✨ Animation
112
+ </label>
113
  </div>
114
  </div>
115
  </div>
116
  </main>
117
+ </div>
118
  <script>
119
  feather.replace();
120
+
121
+ // ============================================
122
+ // MOTEUR DE LA BALEINE IA - GÉNÉRATEUR MULTIMÉDIA
123
+ // ============================================
124
 
125
+ class BaleineIA {
126
+ constructor() {
127
+ this.config = {
128
+ apiKey: "hf_votre_cle_api_gratuite", // À remplacer
129
+ endpoints: {
130
+ image: "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
131
+ video: "https://api-inference.huggingface.co/models/cerspense/zeroscope_v2_576w"
132
+ },
133
+ maxSteps: 50,
134
+ guidanceScale: 7.5
135
+ };
136
+
137
+ this.mediaCourant = null;
138
+ this.recognizer = null;
139
+ this.ecouteActive = false;
140
+
141
+ this.init();
142
+ }
143
+
144
+ init() {
145
+ console.log("🐋 La Baleine IA initialisée - Version Générateur Multimédia");
146
+ this.setupEventListeners();
147
+ this.setupReconnaissanceVocale();
148
+ }
149
+
150
+ setupEventListeners() {
151
+ // Saisie clavier
152
+ const input = document.getElementById('input-baleine');
153
+ if (input) {
154
+ input.addEventListener('keypress', (e) => {
155
+ if (e.key === 'Enter') this.processerDemande(input.value);
156
+ });
157
+ }
158
+ }
159
+
160
+ setupReconnaissanceVocale() {
161
+ if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
162
+ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
163
+ this.recognizer = new SpeechRecognition();
164
+ this.recognizer.lang = 'fr-FR';
165
+ this.recognizer.continuous = false;
166
+ this.recognizer.interimResults = false;
167
+
168
+ this.recognizer.onresult = (event) => {
169
+ const transcription = event.results[0][0].transcript;
170
+ document.getElementById('input-baleine').value = transcription;
171
+ this.processerDemande(transcription);
172
+ this.ecouteActive = false;
173
+ document.getElementById('btn-micro-baleine').style.background = '#ff4081';
174
+ };
175
+
176
+ this.recognizer.onerror = (event) => {
177
+ console.error("Erreur reconnaissance vocale:", event.error);
178
+ this.ecouteActive = false;
179
+ document.getElementById('btn-micro-baleine').style.background = '#ff4081';
180
+ };
181
+ }
182
+ }
183
+
184
+ // ==================== PROCESSUS PRINCIPAL ====================
185
+
186
+ async processerDemande(prompt) {
187
+ if (!prompt.trim()) return;
188
+
189
+ // 1. Afficher la demande utilisateur
190
+ this.afficherMessageUtilisateur(prompt);
191
+
192
+ // 2. Déterminer le type de média
193
+ const typeMedia = this.determinerTypeMedia(prompt);
194
+
195
+ // 3. Explications étape par étape
196
+ await this.expliquerProcessus(prompt, typeMedia);
197
+
198
+ // 4. Génération réelle
199
+ try {
200
+ const resultat = await this.genererMedia(prompt, typeMedia);
201
+ this.afficherResultat(resultat, prompt, typeMedia);
202
+ this.afficherMessageIA(`✅ Génération réussie ! "${prompt}" est maintenant disponible.`);
203
+ } catch (error) {
204
+ this.afficherMessageIA(`❌ Erreur : ${error.message}. Tentative avec un modèle de secours...`);
205
+ await this.genererSecours(prompt, typeMedia);
206
+ }
207
+ }
208
+
209
+ async expliquerProcessus(prompt, typeMedia) {
210
+ const etapes = [
211
+ "Analyse sémantique de votre demande...",
212
+ "Extraction des mots-clés et contexte...",
213
+ `Préparation du modèle ${typeMedia === 'image' ? 'd\'image' : 'de vidéo'}...`,
214
+ "Configuration des paramètres de génération...",
215
+ "Lancement de l'inférence IA...",
216
+ "Post-traitement et optimisation..."
217
+ ];
218
+
219
+ for (let i = 0; i < etapes.length; i++) {
220
+ this.afficherExplication(`Étape ${i+1}/${etapes.length}: ${etapes[i]}`);
221
+ await this.delai(600); // Pause pour effet réaliste
222
+ }
223
+ }
224
+
225
+ async genererMedia(prompt, type) {
226
+ this.afficherExplication("⚙️ Connexion à l'API de génération...");
227
+
228
+ const endpoint = type === 'image' ? this.config.endpoints.image : this.config.endpoints.video;
229
+
230
+ const response = await fetch(endpoint, {
231
+ method: 'POST',
232
+ headers: {
233
+ 'Authorization': `Bearer ${this.config.apiKey}`,
234
+ 'Content-Type': 'application/json'
235
+ },
236
+ body: JSON.stringify({
237
+ inputs: prompt,
238
+ parameters: {
239
+ num_inference_steps: this.config.maxSteps,
240
+ guidance_scale: this.config.guidanceScale,
241
+ width: type === 'image' ? 768 : 576,
242
+ height: type === 'image' ? 768 : 320
243
+ }
244
+ })
245
+ });
246
+
247
+ if (!response.ok) {
248
+ throw new Error(`API non disponible (${response.status})`);
249
+ }
250
+
251
+ this.afficherExplication("✅ Génération terminée ! Traitement du résultat...");
252
+
253
+ const blob = await response.blob();
254
+ const url = URL.createObjectURL(blob);
255
+
256
+ return { type, url, blob, nom: `baleine_${type}_${Date.now()}.${type === 'image' ? 'png' : 'mp4'}` };
257
+ }
258
+
259
+ genererSecours(prompt, type) {
260
+ // Solution de secours avec API alternative
261
+ this.afficherExplication("🔄 Activation du mode secours...");
262
+
263
+ // Utiliser une API publique gratuite
264
+ const apiSecours = type === 'image'
265
+ ? `https://api.unsplash.com/photos/random?query=${encodeURIComponent(prompt)}&client_id=VOTRE_CLE_UNSPLASH`
266
+ : `https://api.pexels.com/videos/search?query=${encodeURIComponent(prompt)}&per_page=1`;
267
+
268
+ return fetch(apiSecours)
269
+ .then(res => res.json())
270
+ .then(data => {
271
+ let url;
272
+ if (type === 'image') {
273
+ url = data.urls.regular;
274
+ } else {
275
+ url = data.videos[0].video_files[0].link;
276
+ }
277
+
278
+ return {
279
+ type,
280
+ url,
281
+ nom: `baleine_${type}_secours_${Date.now()}.${type === 'image' ? 'jpg' : 'mp4'}`,
282
+ source: 'secours'
283
+ };
284
+ });
285
+ }
286
+
287
+ afficherResultat(media, prompt, type) {
288
+ this.mediaCourant = media;
289
+
290
+ const container = document.getElementById('media-container');
291
+ const typeTexte = type === 'image' ? 'Image générée' : 'Vidéo générée';
292
+
293
+ let html = `
294
+ <h5 style="color: #fff; margin-bottom: 20px;">"${prompt}"</h5>
295
+ <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;">
296
+ `;
297
+
298
+ if (media.type === 'image') {
299
+ html += `
300
+ <img src="${media.url}"
301
+ alt="${prompt}"
302
+ style="max-width: 100%; max-height: 400px; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
303
+ `;
304
+ } else {
305
+ html += `
306
+ <video controls autoplay
307
+ style="max-width: 100%; max-height: 400px; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
308
+ <source src="${media.url}" type="video/mp4">
309
+ </video>
310
+ `;
311
+ }
312
+
313
+ html += `
314
+ <div style="margin-top: 15px; color: #b0bec5;">
315
+ <small>${typeTexte} • ${new Date().toLocaleTimeString()}</small>
316
+ </div>
317
+ </div>
318
+ `;
319
+
320
+ container.innerHTML = html;
321
+
322
+ // Activer les boutons de contrôle
323
+ document.querySelector('.controles-baleine').style.display = 'flex';
324
+ }
325
+
326
+ // ==================== AFFICHAGE DES MESSAGES ====================
327
+
328
+ afficherMessageUtilisateur(texte) {
329
+ const chat = document.getElementById('chat-baleine');
330
+ const div = document.createElement('div');
331
+ div.className = 'message-utilisateur';
332
+ div.style.cssText = `
333
+ background: #007bff;
334
+ color: white;
335
+ padding: 10px 15px;
336
+ border-radius: 15px 15px 0 15px;
337
+ margin: 10px 0 10px auto;
338
+ max-width: 80%;
339
+ word-wrap: break-word;
340
+ `;
341
+ div.innerHTML = `<strong>👤 Vous :</strong> ${texte}`;
342
+ chat.appendChild(div);
343
+ chat.scrollTop = chat.scrollHeight;
344
+ }
345
+
346
+ afficherMessageIA(texte) {
347
+ const chat = document.getElementById('chat-baleine');
348
+ const div = document.createElement('div');
349
+ div.className = 'message-ia';
350
+ div.style.cssText = `
351
+ background: #e3f2fd;
352
+ color: #1565c0;
353
+ padding: 10px 15px;
354
+ border-radius: 15px 15px 15px 0;
355
+ margin: 10px 0;
356
+ max-width: 80%;
357
+ word-wrap: break-word;
358
+ `;
359
+ div.innerHTML = `<strong>🐋 La Baleine :</strong> ${texte}`;
360
+ chat.appendChild(div);
361
+ chat.scrollTop = chat.scrollHeight;
362
+ }
363
+
364
+ afficherExplication(texte) {
365
+ const explications = document.getElementById('explications-baleine');
366
+ if (explications) {
367
+ explications.innerHTML = `<strong>📊 Explications en direct :</strong> ${texte}`;
368
+ }
369
+ }
370
+
371
+ // ==================== FONCTIONS UTILITAIRES ====================
372
+
373
+ determinerTypeMedia(prompt) {
374
+ const promptLower = prompt.toLowerCase();
375
+ const motsVideo = ['vidéo', 'film', 'animation', 'mouvement', 'cinéma', 'courte', 'gif'];
376
+ const motsImage = ['image', 'photo', 'illustration', 'dessin', 'tableau', 'affiche'];
377
+
378
+ for (const mot of motsVideo) {
379
+ if (promptLower.includes(mot)) return 'video';
380
+ }
381
+
382
+ for (const mot of motsImage) {
383
+ if (promptLower.includes(mot)) return 'image';
384
+ }
385
+
386
+ // Par défaut, image
387
+ return document.querySelector('input[name="type-media"]:checked').value;
388
+ }
389
+
390
+ delai(ms) {
391
+ return new Promise(resolve => setTimeout(resolve, ms));
392
+ }
393
+
394
+ activerMicro() {
395
+ if (!this.recognizer) {
396
+ this.afficherMessageIA("⚠️ Reconnaissance vocale non supportée sur ce navigateur.");
397
+ return;
398
+ }
399
+
400
+ if (!this.ecouteActive) {
401
+ this.recognizer.start();
402
+ this.ecouteActive = true;
403
+ document.getElementById('btn-micro-baleine').style.background = '#d81b60';
404
+ this.afficherMessageIA("🎤 Micro activé - Parlez maintenant...");
405
+ } else {
406
+ this.recognizer.stop();
407
+ this.ecouteActive = false;
408
+ document.getElementById('btn-micro-baleine').style.background = '#ff4081';
409
  }
 
 
 
 
 
 
 
 
 
 
 
 
410
  }
 
 
 
411
  }
412
 
413
+ // ============================================
414
+ // FONCTIONS GLOBALES POUR LES BOUTONS
415
+ // ============================================
416
 
417
+ // Instance globale
418
+ const LaBaleine = new BaleineIA();
 
 
 
 
 
 
 
 
 
 
 
 
419
 
420
+ // Fonctions appelées par les boutons HTML
421
+ function envoyerPromptBaleine() {
422
+ const input = document.getElementById('input-baleine');
423
+ if (input.value.trim()) {
424
+ LaBaleine.processerDemande(input.value);
425
+ input.value = '';
426
+ }
427
  }
428
 
429
+ function activerMicroBaleine() {
430
+ LaBaleine.activerMicro();
431
+ }
432
 
433
+ function telechargerMediaBaleine() {
434
+ if (LaBaleine.mediaCourant) {
435
+ const a = document.createElement('a');
436
+ a.href = LaBaleine.mediaCourant.url;
437
+ a.download = LaBaleine.mediaCourant.nom;
438
+ document.body.appendChild(a);
439
+ a.click();
440
+ document.body.removeChild(a);
441
+
442
+ LaBaleine.afficherMessageIA(`📥 Téléchargement de "${LaBaleine.mediaCourant.nom}" lancé !`);
443
+ }
444
+ }
445
 
446
+ function regenererMediaBaleine() {
447
+ const dernierPrompt = document.querySelector('.message-utilisateur:last-child');
448
+ if (dernierPrompt) {
449
+ const texte = dernierPrompt.textContent.replace('👤 Vous:', '').trim();
450
+ if (texte) {
451
+ LaBaleine.afficherMessageIA("🔄 Regénération en cours...");
452
+ LaBaleine.processerDemande(texte);
453
+ }
454
+ }
455
  }
456
 
457
+ // Exporter pour DeepSite
458
+ window.LaBaleineIA = LaBaleine;
459
+ </script>
 
 
460
  </body>
461
  </html>