def run(self): wait_for_user_trigger = False self._conversation_stream.start_recording() logging.info('Recording audio request.') i = -1 # This generator yields ConverseResponse proto messages # received from the gRPC Google Assistant API. for resp in self._assistant.Converse(self.iter_converse_requests(), grpc_deadline): assistant_helpers.log_converse_response_without_audio(resp) if resp.error.code != code_pb2.OK: logging.error('server error: %s', resp.error.message) break if resp.event_type == END_OF_UTTERANCE: logging.info('End of audio request detected') self._conversation_stream.stop_recording() if resp.result.spoken_request_text: i = 0 self._stop_playback = False logging.info('Transcript of user request: "%s".', resp.result.spoken_request_text) logging.info('Playing assistant response.') #Check if the voice spoken is part of a USER COMMAND, otherwise use Google Assistant SDK if self.search_command(resp.result.spoken_request_text): self._found_command = True else: i = -1 self._stop_playback = True if len(resp.audio_out.audio_data) > 0: self._conversation_stream.write(resp.audio_out.audio_data) if resp.result.spoken_response_text: logging.info( 'Transcript of TTS response ' '(only populated from IFTTT): "%s".', resp.result.spoken_response_text) if resp.result.conversation_state: conversation_state_bytes = resp.result.conversation_state if resp.result.volume_percentage != 0: volume_percentage = resp.result.volume_percentage logging.info('Volume should be set to %s%%', volume_percentage) if resp.result.microphone_mode == DIALOG_FOLLOW_ON: wait_for_user_trigger = False logging.info('Expecting follow-on query from user.') print "expetinggg" elif resp.result.microphone_mode == CLOSE_MICROPHONE: wait_for_user_trigger = True #Little hack to break the loop after 2 times, this has been found out that can block play back audio if the command is custom if i >= 0: i = i + 1 if i > 2: break logging.info('Finished playing assistant response.') self._conversation_stream.stop_playback() return wait_for_user_trigger
def converse(self): """Send a voice request to the Assistant and playback the response. Returns: True if conversation should continue. """ continue_conversation = False self.conversation_stream.start_recording() logging.info('Recording audio request.') def iter_converse_requests(): for c in self.gen_converse_requests(): assistant_helpers.log_converse_request_without_audio(c) yield c self.conversation_stream.start_playback() # This generator yields ConverseResponse proto messages # received from the gRPC Google Assistant API. for resp in self.assistant.Converse(iter_converse_requests(), self.deadline): assistant_helpers.log_converse_response_without_audio(resp) if resp.error.code != code_pb2.OK: logging.error('server error: %s', resp.error.message) break if resp.event_type == END_OF_UTTERANCE: logging.info('End of audio request detected') self.conversation_stream.stop_recording() if resp.result.spoken_request_text: logging.info('Transcript of user request: "%s".', resp.result.spoken_request_text) logging.info('Playing assistant response.') if len(resp.audio_out.audio_data) > 0: self.conversation_stream.write(resp.audio_out.audio_data) if resp.result.spoken_response_text: logging.info( 'Transcript of TTS response ' '(only populated from IFTTT): "%s".', resp.result.spoken_response_text) if resp.result.conversation_state: self.conversation_state = resp.result.conversation_state if resp.result.volume_percentage != 0: self.conversation_stream.volume_percentage = ( resp.result.volume_percentage ) if resp.result.microphone_mode == DIALOG_FOLLOW_ON: continue_conversation = True logging.info('Expecting follow-on query from user.') elif resp.result.microphone_mode == CLOSE_MICROPHONE: continue_conversation = False logging.info('Finished playing assistant response.') self.conversation_stream.stop_playback() return continue_conversation
def converse(self): """Send a voice request to the Assistant and playback the response. Returns: True if conversation should continue. """ continue_conversation = False self.conversation_stream.start_recording() logging.info('Recording audio request.') def iter_converse_requests(): for c in self.gen_converse_requests(): assistant_helpers.log_converse_request_without_audio(c) yield c self.conversation_stream.start_playback() # This generator yields ConverseResponse proto messages # received from the gRPC Google Assistant API. for resp in self.assistant.Converse(iter_converse_requests(), self.deadline): assistant_helpers.log_converse_response_without_audio(resp) if resp.error.code != code_pb2.OK: logging.error('server error: %s', resp.error.message) break if resp.event_type == END_OF_UTTERANCE: logging.info('End of audio request detected') self.conversation_stream.stop_recording() if resp.result.spoken_request_text: logging.info('Transcript of user request: "%s".', resp.result.spoken_request_text) logging.info('Playing assistant response.') if len(resp.audio_out.audio_data) > 0: self.conversation_stream.write(resp.audio_out.audio_data) if resp.result.spoken_response_text: logging.info( 'Transcript of TTS response ' '(only populated from IFTTT): "%s".', resp.result.spoken_response_text) if resp.result.conversation_state: self.conversation_state = resp.result.conversation_state if resp.result.volume_percentage != 0: self.conversation_stream.volume_percentage = ( resp.result.volume_percentage ) if resp.result.microphone_mode == DIALOG_FOLLOW_ON: continue_conversation = True logging.info('Expecting follow-on query from user.') elif resp.result.microphone_mode == CLOSE_MICROPHONE: continue_conversation = False logging.info('Finished playing assistant response.') self.conversation_stream.stop_playback() return continue_conversation
def main(api_endpoint, credentials, verbose, input_audio_file, output_audio_file, audio_sample_rate, audio_sample_width, audio_iter_size, audio_block_size, audio_flush_size, grpc_deadline, *args, **kwargs): """Samples for the Google Assistant API. Examples: Run the sample with microphone input and speaker output: $ python -m googlesamples.assistant Run the sample with file input and speaker output: $ python -m googlesamples.assistant -i <input file> Run the sample with file input and output: $ python -m googlesamples.assistant -i <input file> -o <output file> """ # Setup logging. logging.basicConfig(level=logging.DEBUG if verbose else logging.INFO) # Load credentials. try: creds = auth_helpers.load_credentials( credentials, scopes=[common_settings.ASSISTANT_OAUTH_SCOPE]) except Exception as e: logging.error('Error loading credentials: %s', e) logging.error('Run auth_helpers to initialize new OAuth2 credentials.') return # Create gRPC channel grpc_channel = auth_helpers.create_grpc_channel( api_endpoint, creds, ssl_credentials_file=kwargs.get('ssl_credentials_for_testing'), grpc_channel_options=kwargs.get('grpc_channel_option')) logging.info('Connecting to %s', api_endpoint) # Create Google Assistant API gRPC client. assistant = embedded_assistant_pb2.EmbeddedAssistantStub(grpc_channel) # Configure audio source and sink. audio_device = None if input_audio_file: audio_source = audio_helpers.WaveSource( open(input_audio_file, 'rb'), sample_rate=audio_sample_rate, sample_width=audio_sample_width) else: audio_source = audio_device = (audio_device or audio_helpers.SoundDeviceStream( sample_rate=audio_sample_rate, sample_width=audio_sample_width, block_size=audio_block_size, flush_size=audio_flush_size)) if output_audio_file: audio_sink = audio_helpers.WaveSink(open(output_audio_file, 'wb'), sample_rate=audio_sample_rate, sample_width=audio_sample_width) else: audio_sink = audio_device = (audio_device or audio_helpers.SoundDeviceStream( sample_rate=audio_sample_rate, sample_width=audio_sample_width, block_size=audio_block_size, flush_size=audio_flush_size)) # Create conversation stream with the given audio source and sink. conversation_stream = audio_helpers.ConversationStream( source=audio_source, sink=audio_sink, iter_size=audio_iter_size, ) # Interactive by default. wait_for_user_trigger = True # If file arguments are supplied, don't wait for user trigger. if input_audio_file or output_audio_file: wait_for_user_trigger = False # Stores an opaque blob provided in ConverseResponse that, # when provided in a follow-up ConverseRequest, # gives the Assistant a context marker within the current state # of the multi-Converse()-RPC "conversation". # This value, along with MicrophoneMode, supports a more natural # "conversation" with the Assistant. conversation_state_bytes = None # Stores the current volument percentage. # Note: No volume change is currently implemented in this sample volume_percentage = 50 while True: conversation_stream.start_recording() logging.info('Recording audio request.') # This generator yields ConverseRequest to send to the gRPC # Google Assistant API. def gen_converse_requests(): converse_state = None if conversation_state_bytes: logging.debug('Sending converse_state: %s', conversation_state_bytes) converse_state = embedded_assistant_pb2.ConverseState( conversation_state=conversation_state_bytes, ) config = embedded_assistant_pb2.ConverseConfig( audio_in_config=embedded_assistant_pb2.AudioInConfig( encoding='LINEAR16', sample_rate_hertz=int(audio_sample_rate), ), audio_out_config=embedded_assistant_pb2.AudioOutConfig( encoding='LINEAR16', sample_rate_hertz=int(audio_sample_rate), volume_percentage=volume_percentage, ), converse_state=converse_state) # The first ConverseRequest must contain the ConverseConfig # and no audio data. yield embedded_assistant_pb2.ConverseRequest(config=config) for data in conversation_stream: # Subsequent requests need audio data, but not config. yield embedded_assistant_pb2.ConverseRequest(audio_in=data) def iter_converse_requests(): for c in gen_converse_requests(): assistant_helpers.log_converse_request_without_audio(c) yield c conversation_stream.start_playback() # This generator yields ConverseResponse proto messages # received from the gRPC Google Assistant API. for resp in assistant.Converse(iter_converse_requests(), grpc_deadline): assistant_helpers.log_converse_response_without_audio(resp) if resp.error.code != code_pb2.OK: logging.error('server error: %s', resp.error.message) break if resp.event_type == END_OF_UTTERANCE: logging.info('End of audio request detected') conversation_stream.stop_recording() if resp.result.spoken_request_text: logging.info('Transcript of user request: "%s".', resp.result.spoken_request_text) logging.info('Playing assistant response.') if len(resp.audio_out.audio_data) > 0: conversation_stream.write(resp.audio_out.audio_data) if resp.result.spoken_response_text: logging.info( 'Transcript of TTS response ' '(only populated from IFTTT): "%s".', resp.result.spoken_response_text) if resp.result.conversation_state: conversation_state_bytes = resp.result.conversation_state if resp.result.volume_percentage != 0: volume_percentage = resp.result.volume_percentage logging.info('Volume should be set to %s%%', volume_percentage) if resp.result.microphone_mode == DIALOG_FOLLOW_ON: wait_for_user_trigger = False logging.info('Expecting follow-on query from user.') elif resp.result.microphone_mode == CLOSE_MICROPHONE: wait_for_user_trigger = True logging.info('Finished playing assistant response.') conversation_stream.stop_playback() # If file arguments are supplied, end the conversation. if input_audio_file or output_audio_file: break if wait_for_user_trigger: break conversation_stream.close()
def assist(self): # Configure audio source and sink. self.audio_device = None self.audio_source = self.audio_device = ( self.audio_device or audio_helpers.SoundDeviceStream( sample_rate=self.audio_sample_rate, sample_width=self.audio_sample_width, block_size=self.audio_block_size, flush_size=self.audio_flush_size)) self.audio_sink = self.audio_device = ( self.audio_device or audio_helpers.SoundDeviceStream( sample_rate=self.audio_sample_rate, sample_width=self.audio_sample_width, block_size=self.audio_block_size, flush_size=self.audio_flush_size)) # Create conversation stream with the given audio source and sink. self.conversation_stream = audio_helpers.ConversationStream( source=self.audio_source, sink=self.audio_sink, iter_size=self.audio_iter_size, sample_width=self.audio_sample_width) restart = False continue_dialog = True try: while continue_dialog: continue_dialog = False # snowboydecoder.play_audio_file(snowboydecoder.DETECT_DING) self.conversation_stream.start_recording() self.logger.info('Recording audio request.') # This generator yields ConverseResponse proto messages # received from the gRPC Google Assistant API. for resp in self.assistant.Converse( self._iter_converse_requests(), self.grpc_deadline): assistant_helpers.log_converse_response_without_audio(resp) if resp.error.code != code_pb2.OK: self.logger.error('server error: %s', resp.error.message) break if resp.event_type == Assistant.END_OF_UTTERANCE: self.logger.info('End of audio request detected') self.conversation_stream.stop_recording() if resp.result.spoken_request_text: self.logger.info('Transcript of user request: "%s".', resp.result.spoken_request_text) self.logger.info('Playing assistant response.') if len(resp.audio_out.audio_data) > 0: self.conversation_stream.write( resp.audio_out.audio_data) if resp.result.spoken_response_text: self.logger.info( 'Transcript of TTS response ' '(only populated from IFTTT): "%s".', resp.result.spoken_response_text) if resp.result.conversation_state: self.conversation_state_bytes = resp.result.conversation_state if resp.result.volume_percentage != 0: volume_percentage = resp.result.volume_percentage self.logger.info('Volume should be set to %s%%', volume_percentage) if resp.result.microphone_mode == self.DIALOG_FOLLOW_ON: continue_dialog = True self.logger.info( 'Expecting follow-on query from user.') self.logger.info('Finished playing assistant response.') self.conversation_stream.stop_playback() except Exception as e: self._create_assistant() self.logger.exception('Skipping because of connection reset') restart = True try: self.conversation_stream.close() if restart: self.assist() except Exception: self.logger.error('Failed to close conversation_stream.')