La reconnaissance vocale Google sous Windows avec Python est apparue comme une nécessité à mes yeux quand j’ai testé Cortana: ce truc, c’est vraiment tout pourri… En effet, d’abord, on est redirigé sur le navigateur Microsoft (ça, déjà, ça le fait moyen) et en plus, sous Bing (donc les résultats sont pas terribles).
J’ai donc souhaité écrire un programme Python me permettant d’effectuer des recherches par reconnaissance vocale en utilisant le moteur de recherche Google.
Reconnaissance vocale Google sous Windows en Python: prémices
Avant tout projet, aussi petit soit-il, il est important de fixer les idées sur ce que l’on veut: c’est le cahier des charges.
Ce que j’aimerais, c’est:
- un objet (on va donc se diriger vers la POO);
- une simple fenêtre contenant une image de micro;
- quand on clique sur le micro, la reconnaissance vocale est déclenchée;
- une fois la phrase terminée, la page de recherche Google s’affiche dans mon navigateur préféré;
- accessoirement, j’aimerais régler la langue.
Reconnaissance vocale Google sous Windows en Python: l’objet
L’objet va être défini par une classe, que je vais appeler VocalSearch.
Le constructeur
Le constructeur doit définir avant tout la fenêtre. Je vais utiliser tkinter pour ce qui est de la solution graphique. De toutes façons, je ne maîtrise rien d’autre donc je n’ai pas le choix !
Ma classe débute donc par:
class VocalSearch: def __init__(self, window): self.window = window self.window.geometry('145x135') self.window.iconbitmap("micro.ico") self.window.resizable(0,0) with open('lang.txt') as f: for line in f: self.lang= line self.main() root = Tk() app = VocalSearch(root) root.mainloop()
Bien entendu, cela nécessite d’avoir défini un icône.
J’ai ici choisi de ne pas rendre redimensionnable la fenêtre.
J’anticipe et charge la langue par défaut: elle est enregistrée dans le fichier lang.txt comme étant “fr-FR”. Ainsi, à ce stade, la variable self.lang vaut “fr-FR”.
Ensuite, j’appelle la méthode main().
La méthode main()
Le contenu de cette méthode pourrait très bien être dans le constructeur, mais j’ai une idée en tête… J’aimerais que l’image de fond change quand on clique dessus le micro. Et j’aimerais aussi qu’elle redevienne un micro quand la reconnaissance vocale s’arrête. Par conséquent, j’ai décidé de mettre les commandes d’affichage des images dans une méthode à part du constructeur.
def main(self): self.back = PhotoImage(file = 'micro.png') self.background = self.back.subsample(1, '1') self.info = ttk.Button(self.window, image=self.background , compound = LEFT, width=1 , command=self.search) self.info.image = self.background self.info.place(x=0,y=0) infoBulle(parent = self.info , texte="Click here & speak") # self.backParam = PhotoImage(file = 'param.png') self.backgroundParam = self.backParam.subsample(1, '1') self.infoParam = ttk.Button(self.window, image=self.backgroundParam , compound = LEFT, width=1 , command=self.parametres) self.infoParam.image = self.backgroundParam self.infoParam.place(x=0,y=0) infoBulle(parent = self.infoParam , texte="Paramètres")
L’image que j’affiche en fond est nommée “micro.png”. C’est un carré de côté 128px.
J’ai aussi décidé d’afficher une info-bulle, qui est un objet à part, et donc définie par une autre classe. Ça, c’est pour le fun…
J’affiche aussi une petite icône en haut à gauche pour les paramètres (si on souhaite les changer). Lors du clic sur cette icône, une autre méthode est appelée (nommée parametres) qui ouvrira une autre fenêtre.
Donc là, rien de grandiose….
La méthode search()
C’est ma méthode la plus importante bien sûr.
def search(self): self.back = PhotoImage(file = 'speak.png') self.background = self.back.subsample(1, '1') self.info = ttk.Button(self.window, image=self.background , compound = LEFT, width=1) self.info.image = self.background self.info.place(x=0,y=0) infoBulle(parent = self.info , texte="wait 1 second and speak") self.recognizer = Recognizer() with Microphone() as source: self.audio = self.recognizer.listen(source) try: self.text = self.recognizer.recognize_google(self.audio , language = self.lang) self.link = "https://www.google.com/search?q="+self.text.replace(' ','+') open_new(self.link) self.main() except Exception as ex: self.not_recognize()
Ici, je change l’image de fond (pour une image nommée speak.png).
Beaucoup de lignes pour pas grand chose car au final, j’utilise le module speech_recognition (voir cet article pour plus de détails) avec Recognizer() et Microphone().
Ensuite, je convertis en texte les mots prononcés et j’appelle la page de recherche Google avec la requête ainsi formée, tout ça dans mon navigateur préféré grâce au module webbrowser et sa fonction open_new.
Tout de suite après, j’appelle la méthode main() pour afficher le micro en fond et revenir donc au point de départ.
Notez ici le cas de l’exception : quand ce qui est dit n’est pas compréhensible, j’appelle la méthode not_recognize().
La méthode not_recognize()
def not_recognize(self): self.back = PhotoImage(file = 'interrogation.png') self.background = self.back.subsample(1, '1') self.info = ttk.Button(self.window, image=self.background , compound = LEFT, width=1 , command=self.search) self.info.image = self.background self.info.place(x=0,y=0) infoBulle(parent = self.info , texte="I don't understand...") self.window.after(2000,self.search)
Cette méthode affiche juste un point d’interrogation (au format image) pendant 2 secondes pour signifier que la reconnaissance vocale Google a échoué. Ensuite, la méthode search() est appelée.
La méthode parametres()
def parametres(self): appParam = Parametres()
Ici, j’ai décidé que la fenêtre qui allait s’ouvrir pour modifier les paramètres de langue était un autre objet. J’ai donc défini cet objet dans une autre classe nommée Parametres.