@@ -12433,38 +12433,6 @@ class FastSearchCard extends HTMLElement {
1243312433 }
1243412434 }
1243512435
12436- // 🕒 ENHANCED DURATION CALCULATION
12437- calculateEnhancedTTSDuration(text) {
12438- if (!text) return 3000;
12439-
12440- const charCount = text.length;
12441- const wordCount = text.split(/\s+/).filter(word => word.length > 0).length;
12442- const punctuationCount = (text.match(/[.!?;,]/g) || []).length;
12443- const complexityFactor = text.match(/[A-ZÄÖÜ]/g)?.length || 0; // Großbuchstaben
12444-
12445- let baseDuration;
12446-
12447- if (charCount < 50) {
12448- // Kurze Texte: LÄNGER machen
12449- baseDuration = (charCount * 150) + 1500; // 🆕 War: 100 + 800
12450- } else {
12451- // Längere Texte: auch länger
12452- baseDuration = (wordCount / 2.0 * 1000) + (punctuationCount * 500); // 🆕 War: 2.5 + 400
12453-
12454- // 🆕 Komplexitäts-Adjustierung
12455- baseDuration += (complexityFactor * 50); // Langsamer bei vielen Großbuchstaben
12456- }
12457-
12458- // 📏 Dynamische Grenzen basierend auf Text-Länge
12459- const minDuration = Math.max(3000, charCount * 40); // 🆕 War: 2000, 30
12460- const maxDuration = Math.min(45000, wordCount * 800);
12461-
12462- const finalDuration = Math.max(minDuration, Math.min(baseDuration, maxDuration));
12463-
12464- console.log(`⏱️ Enhanced TTS Duration: ${Math.round(finalDuration/1000)}s for ${wordCount} words`);
12465- return finalDuration;
12466- }
12467-
1246812436 // 🎤 SMART TTS EXECUTION (Erweiterte Service-Liste)
1246912437 async executeSmartTTS(text, entityId) {
1247012438 // 🎯 Priorisierte TTS-Services (beste Qualität zuerst)
@@ -12507,7 +12475,6 @@ class FastSearchCard extends HTMLElement {
1250712475 }
1250812476 }
1250912477
12510- // 🔄 RESTORE PLAYER CONTEXT (Event-basierte Wiederherstellung)
1251112478 async restorePlayerContext() {
1251212479 if (!this.savedPlayerContext) {
1251312480 console.log('⏭️ No saved player context to restore');
@@ -12518,63 +12485,96 @@ class FastSearchCard extends HTMLElement {
1251812485 console.log('🔄 Restoring player context:', context);
1251912486
1252012487 try {
12521- // 1️⃣ Originalinhalt wiederherstellen
12522- console.log('🎵 Restoring original media...');
12523- await this._hass.callService('media_player', 'play_media', {
12524- entity_id: context.entityId,
12525- media_content_id: context.mediaContentId,
12526- media_content_type: context.mediaContentType
12527- });
12528-
12529- // 2️⃣ Kurz warten, damit Player den neuen Inhalt lädt
12530- await new Promise(resolve => setTimeout(resolve, 800));
12531-
12532- // 3️⃣ Zur gespeicherten Position springen
12533- if (context.mediaPosition && context.mediaPosition > 0) {
12534- console.log(`⏭️ Seeking to position: ${context.mediaPosition}s`);
12535- await this._hass.callService('media_player', 'media_seek', {
12488+ // Für Music Assistant Player
12489+ if (context.entityId.includes('ma_') || context.entityId.includes('music_assistant')) {
12490+ // Music Assistant spezifische Wiederherstellung
12491+ await this._hass.callService('music_assistant', 'play_media', {
1253612492 entity_id: context.entityId,
12537- seek_position: context.mediaPosition
12493+ media_id: context.mediaContentId,
12494+ enqueue: 'play',
12495+ start_position: context.mediaPosition // Position direkt mitgeben
1253812496 });
12539- }
12540-
12541- // 4️⃣ Lautstärke wiederherstellen (falls geändert)
12542- if (context.volumeLevel && context.volumeLevel > 0) {
12543- await this._hass.callService('media_player', 'volume_set', {
12497+ } else {
12498+ // Standard Media Player
12499+ await this._hass.callService('media_player', 'play_media', {
1254412500 entity_id: context.entityId,
12545- volume_level: context.volumeLevel
12501+ media_content_id: context.mediaContentId,
12502+ media_content_type: context.mediaContentType
1254612503 });
12504+
12505+ // Warte bis Player bereit ist
12506+ await new Promise(resolve => setTimeout(resolve, 1000));
12507+
12508+ // Position setzen
12509+ if (context.mediaPosition > 0) {
12510+ await this._hass.callService('media_player', 'media_seek', {
12511+ entity_id: context.entityId,
12512+ seek_position: context.mediaPosition
12513+ });
12514+ }
1254712515 }
1254812516
12549- console.log('✅ Player context successfully restored');
12517+ console.log('✅ Player context restored');
1255012518 return true;
1255112519
1255212520 } catch (error) {
12553- console.error('❌ Failed to restore player context :', error);
12521+ console.error('❌ Failed to restore:', error);
1255412522 return false;
1255512523 } finally {
12556- // 5️⃣ Aufräumen
1255712524 this.savedPlayerContext = null;
12558- console.log('🧹 Saved player context cleared');
1255912525 }
12560- }
12526+ }
1256112527
12562- // 🎧 SIMPLE TTS TIMING (für Player die State nicht ändern)
1256312528 async startTTSMonitoring(entityId) {
12564- console.log('🎧 Starting TTS timing ...');
12529+ console.log('🎧 Starting TTS monitoring ...');
1256512530
12566- // 🕒 Warte 2 Sekunden Basis + 200ms pro Zeichen
12567- const textarea = this.shadowRoot?.querySelector('.tts-textarea');
12568- const text = textarea?.value || '';
12569- const simpleDuration = 2000 + (text.length * 200); // Sehr konservativ
12531+ let previousState = this._hass.states[entityId]?.state;
12532+ let ttsStarted = false;
12533+ let silenceCounter = 0;
1257012534
12571- console.log(`⏰ Simple TTS duration: ${simpleDuration}ms for "${text}"`);
12535+ // Überwache den Player-Status alle 100ms
12536+ this.ttsMonitorInterval = setInterval(async () => {
12537+ const currentState = this._hass.states[entityId];
12538+
12539+ if (!currentState) return;
12540+
12541+ // Erkenne wenn TTS startet (Player wird aktiv)
12542+ if (!ttsStarted && currentState.state === 'playing') {
12543+ ttsStarted = true;
12544+ silenceCounter = 0;
12545+ console.log('🎤 TTS started playing');
12546+ }
12547+
12548+ // Erkenne wenn TTS fertig ist
12549+ if (ttsStarted && currentState.state !== 'playing') {
12550+ silenceCounter++;
12551+
12552+ // Warte 3 Checks (300ms) um sicher zu sein
12553+ if (silenceCounter >= 3) {
12554+ console.log('🎉 TTS completed - player stopped');
12555+ clearInterval(this.ttsMonitorInterval);
12556+ this.ttsMonitorInterval = null;
12557+
12558+ // Sofort wiederherstellen!
12559+ await this.restorePlayerContext();
12560+ await this.finalizeTTSProcess(entityId);
12561+ }
12562+ }
12563+
12564+ previousState = currentState.state;
12565+
12566+ }, 100); // Alle 100ms prüfen
1257212567
12573- setTimeout(async () => {
12574- console.log('🎉 TTS timing completed');
12575- await this.restorePlayerContext();
12576- await this.finalizeTTSProcess(entityId);
12577- }, simpleDuration);
12568+ // Sicherheits-Timeout nach 30 Sekunden
12569+ setTimeout(() => {
12570+ if (this.ttsMonitorInterval) {
12571+ console.log('⚠️ TTS monitoring timeout');
12572+ clearInterval(this.ttsMonitorInterval);
12573+ this.ttsMonitorInterval = null;
12574+ this.restorePlayerContext();
12575+ this.finalizeTTSProcess(entityId);
12576+ }
12577+ }, 30000);
1257812578 }
1257912579
1258012580 // 🏁 TTS-PROZESS FINALISIEREN
0 commit comments