Frage: Raspberry übers Web & Python via Sprache steuern.

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Ich hab einen Pi im Netzwerk, auf dem läuft mit bottle ein WebServer.

    Nun suche ich eine Möglichkeit, den Pi über Netzwerk und dem Web-Interface via Sprache zu steuern - also Speech-To-Text. Für letzteres nutze ich speech_recognition, aber womit kann ich das Mic meines PC's quasi streamen? :s


    Also der Pi steht far far away, ein direktes Mikrofon am Pi selbst kommt nicht in Frage, auch kein Bluetooth oder so.

    Ich möchte eine Webseite öffnen, einen Button drücken, in mein Mikrofon sabbeln, der Pi empfängt und verarbeitet es ... usw


    Hintergrund ist mein RoPi Projekt, in dem ich meinem Gefährt Sprachbefehle geben können möchte, auch wenn dieser außer Sichtweite ist.

    Es muss auf jeden Fall mit Bottle umgesetzt werden, da darauf mein gesamtes Web-Interface basiert - möchte nur ungerne Mischmasch.
    Python3 ist ebenfalls Pflicht ;)

    Ich hab zwar angebliche HTML5 Lösungen gefunden, benötigen aber Google Chrome - nutze ich zwar, möchte es aber gerne auch für FireFox lauffähig haben (auch wenn ich persönlich SRWare Iron bevorzuge)


    Mein tts und stt Gedöns sieht derzeit so aus: => http://codepad.org/SllgOq0B

    Spoiler anzeigen


    [code=php]
    # -*- coding: utf-8 -*-
    #
    # Class: Audio
    # - Convert Text to Speech using espeak
    # - Convert Audio Input into Text using CMUSphinx and react on commands - offline
    #
    # ToDo:
    # https://wiki.python.org/moin/PythonForArtificialIntelligence
    # https://github.com/simpleai-team/simpleai
    #
    # Version: 0.1
    # Creator: meigrafd
    # Copyright (C) 2016 by meiraspi@gmail.com published under the MIT License
    #
    # Requires PyAudio.
    import os
    import speech_recognition
    from espeak import espeak
    from time import sleep, ctime


    class AudioSpeakClass(object):
    """
    Text to Speech
    """
    def __init__(self, lang='de', speed=150):
    self.lang = lang
    self.speed = speed

    def tts(self, text):
    espeak.speed = self.speed
    espeak.set_voice(self.lang)
    espeak.synth(text)


    class AudioCommandClass(object):
    """
    Speech to Text and execute Commands
    """
    def __init__(self, speak=None):
    self.speak = speak
    self.recognizer = speech_recognition.Recognizer()
    with speech_recognition.Microphone() as source:
    self.recognizer.adjust_for_ambient_noise(source)
    self.mic = source
    # start listening in the background (note that we don't have to do this inside a `with` statement)
    self.stop_listening = self.recognizer.listen_in_background(self.mic, self.callback)

    def stop(self):
    self.stop_listening()

    # this is called from the background thread
    def callback(self, recognizer, audio):
    # received audio data
    try:
    data = recognizer.recognize_sphinx(audio)
    print("You said: " + data)
    self.jarvis(data)
    except speech_recognition.UnknownValueError:
    print("Could not understand audio")
    except speech_recognition.RequestError as e:
    print("Recog Error; {0}".format(e))

    def jarvis(self, data):
    if "how are you" in data:
    self.speak.tts("I am fine")

    elif "what time is it" in data:
    self.speak.tts(ctime())


    def run():
    audio_command = AudioCommandClass(speak=AudioSpeakClass())
    try:
    while True:
    sleep(0.5)
    except (KeyboardInterrupt, SystemExit):
    pass

    # EOF
    [/php]


    :danke_ATDE:

  • Frage: Raspberry übers Web & Python via Sprache steuern.? Schau mal ob du hier fündig wirst!

  • Hallo,

    also meine spontane Idee wäre:

    - Client-seitig den Text aufnehmen, vermutlich unter Einsatz einer JS Lib
    - an den Server senden (POST-Request, Websocket, was-auch-immer)
    - Serverseitig verarbeiten

    Ob das so möglich ist - keine Ahnung. Aber danach würde ich im Web suchen, wenn ich das gleiche Problem hätte.

    Gruß, noisefloor

  • Ja, ich würde, wie noisefloor auch versuchen, den Sprachbefehl schon auf der Clientseite in Text umzuwandlen. Wenn die Erkennung unbedingt auf dem Pi funktionieren soll: Muss von jedem PC aus gesendet werden können, oder nur von einem? Wenn du eh nur einen PC zum Steuern benutzt, gäbe es vielleicht die Möglichkeit mit JACK Audio ein remote Microphone zu streamen (sowas in die Richtung: https://www.raspberrypi.org/forums/viewtopic.php?f=41&t=78185)

    Wenn es von einem beliebigen PC aus funktionieren soll, könntest du eventuell auch die aufgenommene WAV Datei an den HTTP POST anhängen. So macht man das ja auch bei der Google Voice API. Könnte mir nur vorstellen, dass das dann die Latenz erhöht und die soll schätzungsweise optimiert werden, dass der Roboter nicht schon an die Wand gefahren ist, bis der Befehl ausgewertet wurde :D

  • Ich hab gerade diese Seiten gefunden:
    https://dvcs.w3.org/hg/audio/raw-f…Processing.html
    https://de.wikipedia.org/wiki/WebRTC , https://lincolnloop.com/blog/what-webrtc/ , http://pyvideo.org/europython-201…-webrtc-an.html , https://github.com/webrtc/samples
    https://w3c.github.io/media-source/
    https://github.com/rahulsekar/brautopy

    Letzteres sieht interessant aus
    WebRTC sieht aber auch interessant aus

    ..Naja, sehr viel zum lesen.. *puh*

    //EDIT: Ich denke das wäre mit "BRowser webAUdio TO PYthon webserver" machbar, nach beenden der Aufnahme wird eine *.wav geschrieben die wiederum von speech_recognition.AudioFile eingelesen wird ... Vorteil: Dank Opus Codec sind die übertragenen Daten kleiner da encoded/komprimiert, es muss also insg. weniger übertragen werden.
    mal zurecht basteln ;)

  • Puh, komplizierter als gedacht... :@

    Mittlerweile muss man mit Google Chrome HTTPS verwenden um die Audio API verwenden zu können => https://sites.google.com/a/chromium.org…nsecure-origins

    Das wiederum kloppt sich dann aber mit WebSocket. Da https verwendet wird weigert sich der Browser eine normale ws:// Verbindung herzustellen - also muss man auch hier nachrüsten und wss:// (secure websocket) verwenden, nur hier beginnen dann die Probleme...

    Ich würde gerne ws4py nutzen da ich das bereits für den Stream der RaspiCam nutze. ws4py scheint das aber nur als Client zu unterstützen nicht als Server :-/
    Google selbst entwickelt pywebsocket mit dem das möglich wäre, ist aber unstable
    Da ich bereits bottle verwende, will ich nicht tornado zur Lösung dieses Problems nutzen - damit ginge das auch.
    websockify würde das angeblich am besten unterstützen.

    :denker: sollte ich jetzt ws4py einstampfen und alles umprogrammieren? :s

    Evtl. kann man auch Pythons ssl Module verwenden (ssl.wrap_socket()), sieht mir aber grad zu komplex aus :blush:

    Aber HTTPS ist nicht gleich HTTPS. HTTPS kann über SSL und TLS in unterschiedlichen Versionen mit unterschiedlichen Verschlüsselungsalgorithmen laufen....


    PS: Und durch dieses Problem wiederum muss ich bottle bei bringen auch über https ansprechbar zu werden, ggf funktioniert eines von http://stackoverflow.com/a/21641086

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!