username_94
username_94

Reputation: 11

How to play gif while using pyttsx3

I have an appliaction which asks the user questions which they should answer. The application uses pyttsx3 (version 2.9) to generate speech and I would like that while it speaks and only then, a gif animation would play for as long as it speaks. How can this be accomplished? For example:

import pyttsx3
engine = pyttsx3.init()
engine.say("I will speak this text")
engine.runAndWait()

And i want the gif animation to start running while runAndWait runs and stop when it stops

Upvotes: 0

Views: 119

Answers (1)

Derek
Derek

Reputation: 2244

Ok I've found another program that works with the GIF images I have.

This program speaks for itself and displays a gif image.

I'm using tkinter Text object for output and a Label to hold the image.

It should allow GIF animes to run but it requires specific information about the GIF.

This runs on windows 10 and pyttsx3 - 2.5

"""
Program outputs text while voice is speaking.

This program works on Python 2.6.14 and Python 3.7.3

"""

import tkinter as tk
from tkinter import filedialog as fido
import random, pyttsx3

class chatter:

    terminate = False

    def showText( self, m ):
        """talk.showText( m )"""
        self.main.insert( "insert", m )
        self.master.update( )
        self.main.edit_separator( )

    def Start( self, name ) ->"":
        """talk.Start( name )"""
        self.sentence = name.split(  )

    def Use( self, name, location, length ) ->"":
        """talk.Use( name, location, length )"""
        name = self.sentence.pop( 0 )
        self.showText( f"{name} " )

    def End( self, name, completed ) ->"":
        """talk.End( name, completed )"""
        if len( self.sentence ) > 0:
            while len( self.sentence ) > 0:
                name = self.sentence.pop( 0 )
                self.showText( f"{name}\n" )
        else:
            self.showText( "\n" )

    def Error( self, name, exception ) ->"":
        """talk.Error( name, exception )"""
        self.terminate = True
        self.engine.stop( )
        self.showText( f"\n{name}\n{exception}\n" )

    def say( self, m ):
        """talk.say( m )"""
        self.engine.say( m, m )
        self.engine.runAndWait(  )

    def intro( self ):
        for m in [
            "This program works on Python 2.6 and Python 3",
            "I am PYTTSX version 2.5" ]:
            talk.say( m )
        self.master.after( 100, self.imageUpdate, 0 )

    def displayInCanvas( self ):
        """talk.displayInCanvas( )"""
        self.image = fido.askopenfilename( title = 'Pick Gif' )
        w, h = self.image.width() + 14, self.image.height() + 46
        self.item = self.canvas.create_image( 2,2, anchor = "nw" )
        self.canvas.itemconfig( self.item, image = self.image )
        self.master.geometry( f"{w}x{h}" )
        self.labelframe[ "text" ] = self.image

    def getImage( self ):
        """talk.getImage( )"""
        self.item = tk.Label( anchor = "nw" )
        self.item.grid( row=0, column=1, sticky="nsew" )
        self.image = fido.askopenfilename( title = 'Pick Gif' )
        # This requires specific knowledge about the GIF image
        # n = number of animation frames
        # self.frame = [ tk.PhotoImage( master = self.master, file=self.image, format = 'gif -index %i' %( i ) ) for i in range( n ) ]
        self.frame = [ tk.PhotoImage(
            master = self.master, file = self.image, format = "gif -index 0" ) ]
        self.item.configure( image = self.frame[ 0 ] )

    def imageUpdate( self, ind ):
        """imageUpdate( ind )"""
        frame = self.frame[ ind ]
        ind += 1
        print( ind )
        # Will play gif infinitely
        if ind > 0: 
            ind = 0
        self.item.configure( image = frame )
        self.master.after( 100, self.imageUpdate, ind )

    def closer( self, ev = None ):
        self.master.destroy( )

    def __init__( self ):
        """talk.init"""

        self.engine =  pyttsx3.init(  )

        self.startUtter = self.engine.connect(
            "started-utterance", self.Start )
        self.wordsUtter = self.engine.connect(
            "started-word", self.Use )
        self.endsUtter  = self.engine.connect(
            "finished-utterance", self.End )
        self.erraUtter  = self.engine.connect(
            "error", self.Error )

        self.persona = self.engine.getProperty( "voices" )[~0].id
        self.engine.setProperty( "voice", self.persona )

        for a,b in [ ("rate", 150 ), ( "volume", 0.25 ) ]:
            self.engine.setProperty( a,b )
        self.engine.runAndWait( )

        self.master = tk.Tk()
        self.main = tk.Text(
            self.master, undo =1, wrap = "word",
            block = 1, width = 80, height = 25 )
        self.main.grid( row = 0, column = 0, sticky = "nsew" )

        self.master.bind( "<Escape>", self.closer )
        self.showText( __doc__ + "\n" )
        self.main.update_idletasks( )
        self.getImage( ) # load and display gif
        self.main.focus_set()
        self.master.after( 100, self.intro )

if __name__ == "__main__":

    talk = chatter( )
    tk.mainloop()

Upvotes: 0

Related Questions