The following script is working great. Il genere un tts tout en le jouant, ce qui est parfait. Le problème, c'est que dès que j'ai plusieurs tâches que je souhaite jouer à la suite de l'autre, il ne prepare pas à l'avance les futures sons, j'aimerais qu'il le fasse : #!/usr/bin/env python3

"""
Basic example of edge_tts usage.
"""

import asyncio
import os
import re
import time
import uuid
import pygame
import edge_tts

TEXT = "Assurez-vous toujours de la bonne réputation de votre tailleur. Il n'y a rien de pire que de se retrouver avec un pantalon déchiré au beau milieu de nulle part !|Toto|male|message"

class WoWTTS:
    FIRST_OVERLAP_MS = -1000
    OVERLAP_MS = 800
    MALE_VOICES = {
        "fr-FR-RemyMultilingualNeural",
        "fr-BE-GerardNeural",
        "fr-FR-HenriNeural",
        "fr-CH-FabriceNeural"
        #"fr-CA-AntoineNeural"
    }
    FEMALE_VOICES = {
        "fr-FR-VivienneMultilingualNeural",
        "fr-BE-CharlineNeural",
        "fr-FR-DeniseNeural",
        "fr-CH-ArianeNeural",
        "fr-CA-SylvieNeural"
    }
    
    RACES_PITCH = {
        'humanoïde': (-30, 20),
        'elf': (-15, 15),
        'dwarf': (-30, 10),
        'orc': (-40, -20)
        # Add more races and their corresponding pitch ranges as needed
    }
    def __init__(self):        
        self.playback_queue = asyncio.Queue()
        pygame.mixer.init()

    async def generate_tts_audio(self, text_segments, voice, formatted_pitch):
        for segment in text_segments:
            unique_id = str(uuid.uuid4())
            file_name = f"{unique_id}.mp3"
            
            communicate = edge_tts.Communicate(segment, voice, pitch=formatted_pitch)
            await communicate.save(file_name)
            
            await self.playback_queue.put(file_name)

    async def playback_loop(self):
        index = 0
        pygame.mixer.init()  # Ensure pygame mixer is initialized
        while True:
            print(index)
            file_name = await self.playback_queue.get()
            sound = pygame.mixer.Sound(file_name)
            sound.play()

            length_ms = sound.get_length() * 1000
            if index == 0:
                # Calculate wait_time considering negative overlap for the first sound
                if WoWTTS.FIRST_OVERLAP_MS < 0:
                    # Play next sound x ms before the current sound ends
                    wait_time = length_ms + WoWTTS.FIRST_OVERLAP_MS
                else:
                    wait_time = length_ms - WoWTTS.FIRST_OVERLAP_MS
            else:
                # Calculate wait_time for subsequent sounds
                if WoWTTS.OVERLAP_MS < 0:
                    # Play next sound x ms before the current sound ends
                    wait_time = length_ms + WoWTTS.OVERLAP_MS
                else:
                    wait_time = length_ms - WoWTTS.OVERLAP_MS
            
            wait_time = max(wait_time, 0) / 1000.0  # Ensure wait_time is not negative and convert to seconds

            index += 1

            await asyncio.sleep(wait_time)

            os.remove(file_name)
            self.playback_queue.task_done()  # Mark the task as done after playback

    async def play(self, text_to_read, npc_sex, npc_race, pitch_index, voice_index, voice_effect):
        voice = self.get_voice_from_index_and_sex(voice_index, npc_sex)        
        pitch = self.get_pitch_from_index_and_race(pitch_index, npc_race)
        formatted_pitch = self.format_pitch(pitch)
        
        # Split the text into segments of three words
        text_words = text_to_read.split()
        #first_segment = " ".join(text_words[:3])
        #remaining_text = " ".join(text_words[3:])

        # Split the remaining text by .!?
        text_segments = re.split(r'[.!?,]', text_to_read)
        text_segments = [seg.strip() for seg in text_segments if seg.strip()]

        print("Voice : " + voice)

        # Combine the first segment with the rest of the text segments
        #text_segments.insert(0, first_segment)

        generator_task = asyncio.create_task(self.generate_tts_audio(text_segments, voice, formatted_pitch))
        playback_task = asyncio.create_task(self.playback_loop())

        await generator_task
        await self.playback_queue.join()  # Ensure all queued audio files have been played
        playback_task.cancel()  # Stop the playback loop

    def get_voice_from_index_and_sex(self, voice_index, npc_sex):
        voices = WoWTTS.MALE_VOICES if npc_sex.lower() == 'male' else WoWTTS.FEMALE_VOICES
        voice_list = sorted(list(voices))
        index = int(voice_index * (len(voice_list) - 1))
        return voice_list[index]

    def get_pitch_from_index_and_race(self, pitch_index, npc_race):
        pitch_range = WoWTTS.RACES_PITCH.get(npc_race, (0, 0))
        min_pitch, max_pitch = pitch_range
        pitch = min_pitch + pitch_index * (max_pitch - min_pitch)
        return pitch

    def format_pitch(self, pitch):
        return f"{pitch:+.0f}Hz"

    
    

if __name__ == '__main__':
    # Example usage
    WoWTTS = WoWTTS()
    
    async def main():
        await WoWTTS.play("Savez-vous, Brahim, qu'il n'y a rien de pire que de se retrouver avec un pantalon déchiré au beau milieu de nulle part !. Bonjour ! Assurez-vous toujours de la bonne réputation de votre tailleur. Il n'y a rien de pire que de se retrouver avec un pantalon déchiré au beau milieu de nulle part !", 'male', 'humanoïde', 0, 0.5, None)
        await WoWTTS.play("Bonjour ! Ça va bien !", 'male', 'orc', 0.5, 0.8, None)
        await WoWTTS.play("Bonjour ! Ça va bien !", 'male', 'orc', 0.5, 0.8, None)
        await WoWTTS.play("Bonjour ! Ça va bien !", 'male', 'orc', 0.5, 0.8, None)
        await WoWTTS.play("Bonjour ! Ça va bien !", 'male', 'orc', 0.5, 0.8, None)
        await WoWTTS.play("Bonjour ! Ça va bien !", 'male', 'orc', 0.5, 0.8, None)
        await WoWTTS.play("Bonjour ! Ça va bien !", 'male', 'orc', 0.5, 0.8, None)

    # Run the main function in the event loop
    asyncio.run(main())