2
\$\begingroup\$

So, I am wanting to use Godot to get a (binary) file using HTTP and then either save it or, even better, turn it into a Resource in memory that I can use. It'll be WAV files that I'm getting in return (trying to implement MaryTTS, which is running as a server on localhost). I had a look at the docs for HTTPRequest, but can't seem to get a working solution.

I do $HTTPRequest.request("http://...") when a keypress is made, and I have the _on_HTTPRequest_request_completed() function, but this never seems to be called. I tried with the function in the same Node as the request (as per the docs' example), and I also tried putting it as part of a script for the HTTPRequest Node. If I hit the triggering key fast enough, it gives an error ("HTTPRequest is processing a request"), but if I do it slower, it doesn't give that error, so it appears it is finishing. It just doesn't do anything when it finishes. HTTPRequest gives a return value of 0, which I assume means no error? (Or should this give me HTTP status codes?)

Any idea what I'm doing wrong? Can HTTPRequest handle binary files? How do I get this working?

(Any suggestions on a better way to implement MaryTTS are also welcome).

\$\endgroup\$
1
\$\begingroup\$

Eventually managed to get this working, using HTTPClient instead of HTTPRequest.

I also implemented threading so it doesn't freeze the main thread.

Full code is here: https://pastebin.com/P1GYkvAX


Edit: As requested, some code samples. Basically it's a mix of the threading stuff here (https://docs.godotengine.org/en/3.1/tutorials/threads/using_multiple_threads.html) with HTTPClient from here (https://docs.godotengine.org/en/3.1/tutorials/networking/http_client_class.html)

func _ready():
    mutex = Mutex.new()
    semaphore = Semaphore.new()
    exit_thread = false

    thread = Thread.new()
    thread.start(self, "_thread_function", "")

func _thread_function(userdata):
    while true:
        semaphore.wait()

        mutex.lock()
        var should_exit = exit_thread
        mutex.unlock()

        if should_exit:
            break

        mutex.lock()
        _http_get_worker()
        mutex.unlock()

func http_get(url_passed = ""):
    url_path = url_passed
    semaphore.post()

func _exit_tree():
    mutex.lock()
    exit_thread = true
    mutex.unlock()

    semaphore.post()

    thread.wait_to_finish()

func _http_get_worker():

Followed by the HTTPClient code, followed by:

        var player = AudioStreamPlayer.new()
        self.add_child(player)
        var sound = AudioStreamSample.new()
        sound.data = rb # "rb" is the received HTTP data
        sound.format = AudioStreamSample.FORMAT_16_BITS
        sound.loop_mode = AudioStreamSample.LOOP_DISABLED
        sound.stereo = false
        sound.mix_rate = 16000
        player.stream = sound
        player.play()
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can you show a small sample of the relevant code here in the question, in case the pastebin link is ever unavailable? \$\endgroup\$
    – DMGregory
    Sep 28 '19 at 20:08
  • \$\begingroup\$ Added code samples as requested. :-) \$\endgroup\$ Oct 1 '19 at 4:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.