IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Raspberry Pi Discussion :

Téléphonique à cadran S63 comme lecteur de mp3 - problème de logique


Sujet :

Raspberry Pi

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2017
    Messages : 6
    Points : 3
    Points
    3
    Par défaut Téléphonique à cadran S63 comme lecteur de mp3 - problème de logique
    Bonjour à tous,
    Le but du projet est d'utiliser un téléphone à cadran S63 comme lecteur de mp3.
    Nom : S63 (Téléphone).jpeg
Affichages : 135
Taille : 25,1 Ko

    Matériel : téléphone S63, Raspberry Pi Zero W, DAC externe, Raspberry Pi OS Lite.

    Fonctionnement :
    1- au décroché dial-tone.mp3 est joué (fréquence 440Hz)
    2- lorsque l'utilisateur compose un numéro, le son s'arrête et les impulsions créées par le cadran rotatif sont comptées pour connaitre le numéro saisi par l'utilisateur.
    3- une fois les différents chiffres stockés, le numéro final sert de recherche de fichier mp3. Exemple si 42 est saisi le fichier 42_texteexemple.mp3 est joué.
    4- juste avant la lecture de 42_texteexemple.mp3 le fichier recherche.mp3 est joué.
    5- si le aucun fichier ne commence par 42 le fichier non2.mp3 est joué. L'utilisateur doit alors raccrocher pour recommencer.

    Dans mon code l'étape 1 fonctionne, mais l'étape 2 ne fonctionne pas. Le fichier lis le fichier mp3 mais ne semble pas voir les numéros du cadran.


    Voici le code avec toutes les fonctions :

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
     
    import RPi.GPIO as GPIO
    import pygame
    import os
    import time
    from typing import Optional
     
    # Constants for GPIO pins
    GPIO_PIN_OFF_HOOK = 25  # Pin GPIO pour détecter si le téléphone est décroché
    GPIO_PIN_DIAL = 17      # Pin GPIO pour lire les impulsions du cadran
     
    # Configuration des GPIO
    GPIO.setmode(GPIO.BCM)  # Utilisation du mode BCM pour la numérotation des GPIO
    GPIO.setup(GPIO_PIN_OFF_HOOK, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # Configuration du pin off-hook avec une résistance de pull-up
    GPIO.setup(GPIO_PIN_DIAL, GPIO.IN, pull_up_down=GPIO.PUD_UP)      # Configuration du pin dial avec une résistance de pull-up
     
    # Initialisation de pygame pour la lecture audio
    pygame.mixer.init()
     
    # Chemin du répertoire des sons
    SOUND_DIR = "/home/user/sounds"
     
    def play_sound(file: str) -> None:
        """Joue un fichier audio s'il existe."""
        if os.path.exists(file):
            print(f"Lecture du fichier : {file}")
            pygame.mixer.music.load(file)
            pygame.mixer.music.play()
            # Attendre que le fichier audio se termine ou que le téléphone soit raccroché
            while pygame.mixer.music.get_busy() and GPIO.input(GPIO_PIN_OFF_HOOK) == GPIO.LOW:
                time.sleep(0.1)
        else:
            print(f"Fichier {file} non trouvé.")
     
    def stop_sound() -> None:
        """Arrête la lecture audio en cours."""
        if pygame.mixer.music.get_busy():
            print("Arrêt de la lecture audio.")
            pygame.mixer.music.stop()
     
    def wait_for_off_hook() -> None:
        """Attend le signal de décroché et joue le son de la tonalité de numérotation."""
        print("En attente de décroché...")
        while GPIO.input(GPIO_PIN_OFF_HOOK):
            time.sleep(0.1)
        print("Décroché détecté.")
        play_sound(os.path.join(SOUND_DIR, "dial-tone_2.mp3"))
     
    def read_dial() -> int:
        """Lit le nombre d'impulsions du cadran et retourne le chiffre correspondant."""
        dial_count = 0
        print("Lecture du cadran...")
     
        # Attendre le début de la première impulsion
        while GPIO.input(GPIO_PIN_DIAL) == GPIO.HIGH:
            time.sleep(0.01)
     
        # Lire les impulsions
        while True:
            # Attendre que le cadran soit relâché
            while GPIO.input(GPIO_PIN_DIAL) == GPIO.LOW:
                time.sleep(0.01)
     
            # Attendre que le cadran soit de nouveau pressé ou qu'une pause plus longue se produise
            impulse_time = time.time()
            while GPIO.input(GPIO_PIN_DIAL) == GPIO.HIGH:
                time.sleep(0.01)
                if time.time() - impulse_time > 0.2:  # Temps de pause entre les chiffres
                    break
     
            # Comptabiliser une impulsion
            dial_count += 1
            impulse_time = time.time()
     
            # Vérifier s'il y a une pause plus longue, indiquant la fin de la séquence
            while GPIO.input(GPIO_PIN_DIAL) == GPIO.LOW:
                time.sleep(0.01)
                if time.time() - impulse_time > 0.2:  # Temps de pause entre les chiffres
                    break
     
            if time.time() - impulse_time > 0.2:
                break
     
        if dial_count == 10:
            return 0
        return dial_count
     
    def concatenate_digits(last_digit_time: float, new_digit: int, concatenated_digits: str) -> (float, str):
        """Concatène les chiffres s'ils sont saisis dans les 2.3 secondes."""
        current_time = time.time()
     
        if current_time - last_digit_time < 2.3:
            concatenated_digits += str(new_digit)
        else:
            if concatenated_digits:
                print(f"Numéro composé : {concatenated_digits}")
            concatenated_digits = str(new_digit)
     
        last_digit_time = current_time
        return last_digit_time, concatenated_digits
     
    def find_sound_file(concatenated_digits: str) -> Optional[str]:
        """Recherche un fichier audio correspondant aux chiffres concaténés."""
        print(f"Recherche de fichier pour le numéro composé : {concatenated_digits}")
        for file in os.listdir(SOUND_DIR):
            if file.startswith(concatenated_digits + "_"):
                print(f"Fichier trouvé : {file}")
                return file
        print("Aucun fichier trouvé pour le numéro composé.")
        return None
     
    def main() -> None:
        """Fonction principale pour gérer l'interaction téléphonique."""
        try:
            # Lecture du fichier notif.mp3 à l'initialisation
            play_sound(os.path.join(SOUND_DIR, "notif2.mp3"))
            time.sleep(5)  # Attendre 5 secondes pour que le son se termine
     
            while True:  # Boucle principale
                wait_for_off_hook()  # Attendre que le téléphone soit décroché
     
                dialed_number = ""
                concatenated_digits = ""
                composition_started = False
     
                last_digit_time = time.time()
     
                while GPIO.input(GPIO_PIN_OFF_HOOK) == GPIO.LOW:
                    digit = read_dial()
                    if digit is not None:
                        if not composition_started:
                            stop_sound()  # Arrête la tonalité une fois que la numérotation commence
                            composition_started = True
                        dialed_number += str(digit)
                        print(f"Numéro composé jusqu'à présent : {dialed_number}")
     
                        # Mettre à jour concatenated_digits avec le nouveau chiffre
                        last_digit_time, concatenated_digits = concatenate_digits(last_digit_time, digit, concatenated_digits)
     
                if concatenated_digits:
                    search_file = find_sound_file(concatenated_digits)
                    if search_file:
                        play_sound(os.path.join(SOUND_DIR, "recherche.mp3"))
                        play_sound(os.path.join(SOUND_DIR, search_file))
                    else:
                        play_sound(os.path.join(SOUND_DIR, "non3.mp3"))
     
                stop_sound()  # Arrête le son si le téléphone est raccroché
     
        except KeyboardInterrupt:
            print("Programme interrompu par l'utilisateur.")
        finally:
            stop_sound()  # Assure l'arrêt du son en cours
            GPIO.cleanup()  # Nettoie les GPIO à la fin du programme
            print("Nettoyage des GPIO et arrêt du programme.")

    Je commence tout juste en Python il doit y avoir une logique qui me manque.
    J'ai essayer avec un LLM de trouver le soucis mais sans succès.



    Merci pour votre aide.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 388
    Points : 36 938
    Points
    36 938
    Par défaut
    Salut,
    Citation Envoyé par Joe_M8 Voir le message
    Je commence tout juste en Python il doit y avoir une logique qui me manque.
    S'il faut des équipements particuliers pour reproduire le problème et essayer de le comprendre, vous comprendrez qu'il faut maîtriser un peu la programmation avant de se lancer dans ce genre de projet.
    De plus pour essayer de vous aider, il faudrait savoir où vous en êtes côté formation python: vous utilisez des construction avancées alors que vous dites juste commencer... on se base sur quoi pour essayer de vous expliquer quelque chose?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2017
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Bonjour,
    Merci d’avoir pris le temps de regarder ma demande.
    Effectivement je découvre le Python depuis moins d’une semaine mais connais les grandes lignes de la programmation avec le VBA.
    C’est justement ce type de petit projet qui permet aux amateurs de découvrir les joies de l’informatique

    Un simple aiguillage me convient, mais si vous souhaitez m’expliquer des choses plus précises je suis preneur.
    Aiguillage en cours :
    - Contrôler la ligne «128 : while GPIO.input(GPIO_PIN_OFF_HOOK) == GPIO.LOW: »
    - Ajouter des sorties consoles pour suivre de plus près ce qu’il se passe.

    Je vais regarder cela ce week-end.
    Je suis à l’écoute d'autres conseils.

  4. #4
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 777
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 777
    Points : 58 179
    Points
    58 179
    Billets dans le blog
    42
    Par défaut
    Bonjour,

    Beaucoup de choses dépendent aussi du matériel...

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # Constants for GPIO pins
    GPIO_PIN_OFF_HOOK = 25  # Pin GPIO pour détecter si le téléphone est décroché
    GPIO_PIN_DIAL = 17      # Pin GPIO pour lire les impulsions du cadran
     
    # Configuration des GPIO
    GPIO.setmode(GPIO.BCM)  # Utilisation du mode BCM pour la numérotation des GPIO
    GPIO.setup(GPIO_PIN_OFF_HOOK, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # Configuration du pin off-hook avec une résistance de pull-up
    GPIO.setup(GPIO_PIN_DIAL, GPIO.IN, pull_up_down=GPIO.PUD_UP)      # Configuration du pin dial avec une résistance de pull-up

    Es-tu sûr que les signaux sont corrects au niveau des GPIO17 et GPIO25 ? (visualisation à l'oscilloscope ou autre)

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 388
    Points : 36 938
    Points
    36 938
    Par défaut
    Citation Envoyé par Joe_M8 Voir le message
    Aiguillage en cours :
    - Contrôler la ligne «128 : while GPIO.input(GPIO_PIN_OFF_HOOK) == GPIO.LOW: »
    - Ajouter des sorties consoles pour suivre de plus près ce qu’il se passe.
    Vérifier que les conditions fonctionnent, afficher la valeur de certaines variables,.. ce sont les reflexes qu'on acquiert en essayant de mettre au point les exercices qui vont avec n'importe quel tuto.... Et si vous voulez vous lancer dans ce genre de projet sans passer plus de temps à apprendre les bases... c'est votre problème mais relisez les règles qui régissent ces forums: vous êtes supposé avoir appris à programmer avant de demander de l'aide (sauf pour comprendre comment faire les exos d'un tuto).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2017
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    @f-leb, oui j’ai testé chaque GPIO avec 2 codes simplifiés.

    Le problème de logique principal est résolu, effectivement la logique n’était pas bonne.
    Pour ceux que ça intéresse, voici donc le code fonctionnel :

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    import RPi.GPIO as GPIO
    import pygame
    import time
    import os
     
    # Configuration des GPIO et des chemins de fichiers
    GPIO_PINS = {"PIN_DECROCHE": 25, "PIN_CADRAN": 17}
    SOUND_DIR = "/home/user/sounds"
    SOUNDS = {
        "DIAL_TONE": os.path.join(SOUND_DIR, "dial_tone_20.mp3"),
        "RECHERCHE": os.path.join(SOUND_DIR, "recherche.mp3"),
        "NON_TROUVE": os.path.join(SOUND_DIR, "non3.mp3"),
        "NOTIF": os.path.join(SOUND_DIR, "notif2.mp3")
    }
     
    # Initialisation de pygame pour la lecture audio
    pygame.mixer.init()
     
    # Déclaration globale de la variable sound_stopped
    sound_stopped = False
     
    def setup_gpio():
        """Configuration des GPIO."""
        print("Configuration des GPIO...")
        GPIO.setmode(GPIO.BCM)
        for pin in GPIO_PINS.values():
            GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        print("GPIO configurés.")
     
    def play_sound(file_path):
        """Joue un fichier audio."""
        global sound_stopped  # Déclaration de l'utilisation de la variable globale
        print(f"Lecture du son : {file_path}")
        sound_stopped = False  # Réinitialiser sound_stopped à chaque nouvelle lecture
        pygame.mixer.music.load(file_path)
        pygame.mixer.music.play()
     
    def wait_for_sound_to_finish_or_raccroche():
        """Attend la fin du son ou l'action de raccrocher."""
        while pygame.mixer.music.get_busy():
            if GPIO.input(GPIO_PINS["PIN_DECROCHE"]) == GPIO.HIGH:
                print("Le combiné a été raccroché pendant la lecture.")
                pygame.mixer.music.stop()
                return False
            time.sleep(0.1)
        return True
     
    def stop_sound():
        """Arrête la lecture audio."""
        print("Arrêt de la lecture audio.")
        pygame.mixer.music.stop()
     
    def read_dial():
        """Lit les impulsions du cadran et retourne le chiffre correspondant."""
        global sound_stopped  # Déclaration de l'utilisation de la variable globale
        print("Lecture du cadran...")
        pulses = 0
        last_state = GPIO.input(GPIO_PINS["PIN_CADRAN"])
        last_pulse_time = None
        start_time = time.time()
     
        # Temps pour détection d'impulsion stable (debouncing)
        debounce_time = 0.005  # 5ms
        pulse_timeout = 0.2  # 200ms pour considérer qu'il s'agit du même chiffre
     
        while True:
            if GPIO.input(GPIO_PINS["PIN_DECROCHE"]) == GPIO.HIGH:
                print("Le combiné a été raccroché.")
                stop_sound()
                return None
     
            current_state = GPIO.input(GPIO_PINS["PIN_CADRAN"])
            if current_state != last_state:
                time.sleep(debounce_time)  # Attendre pour stabiliser la lecture
                current_state = GPIO.input(GPIO_PINS["PIN_CADRAN"])  # Relecture pour confirmation
                if current_state != last_state:
                    if not sound_stopped:
                        stop_sound()
                        sound_stopped = True
                    if current_state == GPIO.HIGH:
                        current_time = time.time()
                        if last_pulse_time is None or (current_time - last_pulse_time) >= pulse_timeout:
                            if pulses > 0:
                                break  # Le chiffre est terminé
                            pulses = 1  # Nouvelle série d'impulsions
                        else:
                            pulses += 1
                        last_pulse_time = current_time
                    last_state = current_state
            time.sleep(0.001)
     
        if pulses == 0:
            print("Aucune impulsion détectée.")
            return None
     
        pulses_mod = pulses % 10 if pulses > 0 else 10
        print(f"Nombre d'impulsions lues : {pulses}, chiffre obtenu : {pulses_mod}")
        return pulses_mod
     
    def get_dialed_number():
        """Retourne le numéro composé par l'utilisateur."""
        print("Obtention du numéro composé...")
        number = ""
        digit_timeout_long = 3.0  # Temps d'attente (en secondes) après chaque chiffre pour vérifier si un autre chiffre est composé
        last_digit_time = None
     
        while True:
            if GPIO.input(GPIO_PINS["PIN_DECROCHE"]) == GPIO.HIGH:
                print("Le combiné a été raccroché.")
                stop_sound()
                return None
     
            digit = read_dial()
     
            if digit is not None:
                digit = digit if digit != 10 else 0
                number += str(digit)
                last_digit_time = time.time()
                print(f"Numéro actuel : {number}")
     
            # Si plus de 3 secondes se sont écoulées sans nouvelle impulsion, le numéro est terminé
            if last_digit_time and (time.time() - last_digit_time >= digit_timeout_long):
                print(f"Numéro final composé : {number}")
                return number
     
            time.sleep(0.01)
     
    def find_audio_file(number):
        """Recherche un fichier audio correspondant au numéro composé."""
        print(f"Recherche du fichier audio pour le numéro : {number}")
        for file in os.listdir(SOUND_DIR):
            if file.startswith(f"{number}_") and file.endswith(".mp3"):
                file_path = os.path.join(SOUND_DIR, file)
                print(f"Fichier audio trouvé : {file_path}")
                return file_path
        print("Aucun fichier audio trouvé.")
        return None
     
    def main():
        """Boucle principale du programme."""
        setup_gpio()
     
        try:
            while True:
                if GPIO.input(GPIO_PINS["PIN_DECROCHE"]) == GPIO.LOW:
                    print("Le combiné a été décroché.")
                    play_sound(SOUNDS["DIAL_TONE"])
     
                    dialed_number = get_dialed_number()
     
                    if dialed_number:
                        print(f"Numéro composé : {dialed_number}")
                        audio_file = find_audio_file(dialed_number)
                        if audio_file and wait_for_sound_to_finish_or_raccroche():
                            play_sound(audio_file)
                            wait_for_sound_to_finish_or_raccroche()
                        else:
                            play_sound(SOUNDS["NON_TROUVE"])
                            wait_for_sound_to_finish_or_raccroche()
     
                        while GPIO.input(GPIO_PINS["PIN_DECROCHE"]) == GPIO.LOW:
                            time.sleep(0.1)
     
                    stop_sound()
     
                time.sleep(0.1)
     
        except KeyboardInterrupt:
            print("Programme arrêté par l'utilisateur.")
        finally:
            print("Nettoyage des GPIO et arrêt de pygame.")
            GPIO.cleanup()
            pygame.mixer.quit()
     
    if __name__ == "__main__":
        main()

    Axe d’amélioration de ce code :
    Une fois le premier chiffre reçu, le son dial_tone est arrêté. Cela entraine un petit délai qui fait que si l’utilisateur compose rapidement le numéro suivant, il est mal interprété.
    Pistes :
    1- Tester avec mpg321 comme lecteur audio au lieu de pygame.
    2- Baisser le son à 0 au lieu de l’arrêter
    Le raspberry pi zero W est très peu puissant, si vous avez des astuces je suis preneur.
    Je marque le sujet comme résolu.
    Merci à vous.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VS.NET] Liens relatifs et suivi des sessions ?
    Par Webman dans le forum ASP.NET
    Réponses: 6
    Dernier message: 18/11/2004, 21h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo