|
|
@@ -0,0 +1,141 @@ |
|
|
#!/usr/bin/env python3 |
|
|
# Copyright 2017 Google Inc. |
|
|
# |
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
# you may not use this file except in compliance with the License. |
|
|
# You may obtain a copy of the License at |
|
|
# |
|
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
|
# |
|
|
# Unless required by applicable law or agreed to in writing, software |
|
|
# distributed under the License is distributed on an "AS IS" BASIS, |
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
# See the License for the specific language governing permissions and |
|
|
# limitations under the License. |
|
|
|
|
|
"""Run a recognizer using the Google Assistant Library. |
|
|
|
|
|
The Google Assistant Library has direct access to the audio API, so this Python |
|
|
code doesn't need to record audio. Hot word detection "OK, Google" is supported. |
|
|
|
|
|
The Google Assistant Library can be installed with: |
|
|
env/bin/pip install google-assistant-library==0.0.2 |
|
|
|
|
|
It is available for Raspberry Pi 2/3 only; Pi Zero is not supported. |
|
|
""" |
|
|
|
|
|
import logging |
|
|
import re |
|
|
import subprocess |
|
|
import sys |
|
|
|
|
|
import aiy.assistant.auth_helpers |
|
|
import aiy.assistant.device_helpers |
|
|
import aiy.audio |
|
|
import aiy.voicehat |
|
|
from google.assistant.library import Assistant |
|
|
from google.assistant.library.event import EventType |
|
|
|
|
|
import vlc |
|
|
import youtube_dl |
|
|
|
|
|
logging.basicConfig( |
|
|
level=logging.INFO, |
|
|
format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s" |
|
|
) |
|
|
|
|
|
ydl_opts = { |
|
|
'default_search': 'ytsearch1:', |
|
|
'format': 'bestaudio/best', |
|
|
'noplaylist': True, |
|
|
'quiet': True |
|
|
} |
|
|
vlc_instance = vlc.get_default_instance() |
|
|
vlc_player = vlc_instance.media_player_new() |
|
|
|
|
|
|
|
|
def power_off_pi(): |
|
|
aiy.audio.say('Good bye!') |
|
|
subprocess.call('sudo shutdown now', shell=True) |
|
|
|
|
|
|
|
|
def reboot_pi(): |
|
|
aiy.audio.say('See you in a bit!') |
|
|
subprocess.call('sudo reboot', shell=True) |
|
|
|
|
|
|
|
|
def say_ip(): |
|
|
ip_address = subprocess.check_output("hostname -I | cut -d' ' -f1", shell=True) |
|
|
aiy.audio.say('My IP address is %s' % ip_address.decode('utf-8')) |
|
|
|
|
|
|
|
|
def play_music(name): |
|
|
try: |
|
|
with youtube_dl.YoutubeDL(ydl_opts) as ydl: |
|
|
meta = ydl.extract_info(name, download=False) |
|
|
except Exception: |
|
|
aiy.audio.say('Sorry, I can\'t find that song.') |
|
|
return |
|
|
|
|
|
if meta: |
|
|
info = meta['entries'][0] |
|
|
vlc_player.set_media(vlc_instance.media_new(info['url'])) |
|
|
aiy.audio.say('Now playing ' + re.sub(r'[^\s\w]', '', info['title'])) |
|
|
vlc_player.play() |
|
|
|
|
|
|
|
|
def process_event(assistant, event): |
|
|
status_ui = aiy.voicehat.get_status_ui() |
|
|
if event.type == EventType.ON_START_FINISHED: |
|
|
status_ui.status('ready') |
|
|
if sys.stdout.isatty(): |
|
|
print('Say "OK, Google" then speak, or press Ctrl+C to quit...') |
|
|
|
|
|
elif event.type == EventType.ON_CONVERSATION_TURN_STARTED: |
|
|
status_ui.status('listening') |
|
|
|
|
|
elif event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED and event.args: |
|
|
print('You said:', event.args['text']) |
|
|
text = event.args['text'].lower() |
|
|
if text == 'stop': |
|
|
if vlc_player.get_state() == vlc.State.Playing: |
|
|
vlc_player.stop() |
|
|
elif text == 'power off': |
|
|
assistant.stop_conversation() |
|
|
power_off_pi() |
|
|
elif text == 'reboot': |
|
|
assistant.stop_conversation() |
|
|
reboot_pi() |
|
|
elif text == 'ip address': |
|
|
assistant.stop_conversation() |
|
|
say_ip() |
|
|
elif text == 'pause': |
|
|
assistant.stop_conversation() |
|
|
vlc_player.set_pause(True) |
|
|
elif text == 'resume': |
|
|
assistant.stop_conversation() |
|
|
vlc_player.set_pause(False) |
|
|
elif text.startswith('play '): |
|
|
assistant.stop_conversation() |
|
|
play_music(text[6:]) |
|
|
|
|
|
elif event.type == EventType.ON_END_OF_UTTERANCE: |
|
|
status_ui.status('thinking') |
|
|
|
|
|
elif event.type == EventType.ON_CONVERSATION_TURN_FINISHED: |
|
|
status_ui.status('ready') |
|
|
|
|
|
elif event.type == EventType.ON_ASSISTANT_ERROR and event.args and event.args['is_fatal']: |
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
def main(): |
|
|
credentials = aiy.assistant.auth_helpers.get_assistant_credentials() |
|
|
device_id, model_id = aiy.assistant.device_helpers.get_ids(credentials) |
|
|
with Assistant(credentials, model_id) as assistant: |
|
|
for event in assistant.start(): |
|
|
process_event(assistant, event) |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
main() |