nativescript-community / texttospeech

Text to Speech NativeScript plugin for Android & iOS :loudspeaker:
http://nativescript-community.github.io/texttospeech/
MIT License
50 stars 24 forks source link

First sound playing is long to start #7

Closed GrEg00z closed 7 years ago

GrEg00z commented 7 years ago

After every startup of my app, I have to wait maybe 10 secondes before the first sound start to play, when using :

this.TTS.speak(speakOptions);

After the first sound finished, all others calls to this.TTS.speak are directly played.

I've tried to re-install the app but nothing changes

bradmartin commented 7 years ago

Initializing the synthesizer takes some time and varies on device capabilities. Are you playing the sound at app start? Or during some user interaction? If with some user interaction you should create an instance of the synthesizer before calling speak(). One solution might be to initialize it in a page navigation event and then just reuse that instance when needed. You could also try initializing on app start and attaching your instance to global and reuse it across your app. Let me know if that makes any sense or not. :)

On Tue, Apr 11, 2017, 8:33 AM GrEg00z notifications@github.com wrote:

After every startup of my app, I have to wait maybe 10 secondes before the first sound start to play, when using :

this.TTS.speak(speakOptions);

After the first sound finished, all others calls to this.TTS.speak are directly played.

I've tried to re-install the app but nothing changes

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bradmartin/nativescript-texttospeech/issues/7, or mute the thread https://github.com/notifications/unsubscribe-auth/AFulhCUb2HPDZfJUKGOf0ax4kVNnY0VKks5ru4ELgaJpZM4M6Gjp .

GrEg00z commented 7 years ago

Yes it makes sense :)

I'm playing the sound after user interaction, on a tap event action.

I'm using nativescript with angular, and I created an 'angular' service in my app that instanciate TNSTextToSpeech , which is initialized after app start (declared as provider in my app.module file).

So I use only one instance of TNSTextToSpeech in my app, which is instanciate long time before I call this.TTS.speak (method play() in my service). Systematically, the time to wait is about 10-12 seconds

Here the service I created :

import { Injectable }             from '@angular/core';
import { TNSTextToSpeech, SpeakOptions } from 'nativescript-texttospeech';

@Injectable()
export class SpeakerService {

  TTS : TNSTextToSpeech;
  constructor() {
      this.TTS = new TNSTextToSpeech();
  }

  play(text : string) {
    let speakOptions: SpeakOptions = {
        text: text, /// *** required ***
        speakRate: 1.0, // optional - default is 1.0
        pitch: 1.0, // optional - default is 1.0
        volume: 1.0, // optional - default is 1.0
        language: "fr-FR",  // optional - default is system language,
        finishedCallback: () => {
          console.log("We have finish to read text");
        } // optional
    }
    this.TTS.speak(speakOptions);
  }
}
bradmartin commented 7 years ago

Can you confirm, maybe with some console.logs() in the constructor the timing before/after the this.TTS = new... and see how long it's taking and when it's being initialized? I'd also try logging out this.TTS inside the play method and see if it's the same instance the constructor creates. They should log the same value if so.

GrEg00z commented 7 years ago

Yes it's well instanciate during app start, it takes no time. Also there is no callback or others ways (like observale or promise) to detect that the synthesizer is ready to be used, asynchronously.

I've just added this to detect that TNSTextToSpeech is ready :

constructor() {
      console.log("init SpeakerService")
      this.TTS = new TNSTextToSpeech();
      console.log("end init SpeakerService", JSON.stringify(this.TTS))
  }

I've checked this.TTS inside play method, it also have the same instance as constructor

I can also confirm that when I add this inside finishedCallback function (in play method) :

this.TTS.destroy();
this.TTS = new TNSTextToSpeech();

Then every next call to play method take also 10-12s to play.

Information : I use android 7.1.1 with Nexus 5X

bradmartin commented 7 years ago

Don't destroy unless you want to init a new instance. Is that what you want? Destroy will destroy the instance and free up memory on device. So only use it when you will no longer use the module. As for my test app I did for egghead last month on my Droid turbo 2 it takes about 2seconds to init the synthesizer and then speak method is near instant when using that instance at any time later.

On Tue, Apr 11, 2017, 11:13 AM GrEg00z notifications@github.com wrote:

Yes it's well instanciate during app start, it takes no time. Also there is no callback or others ways (like observale or promise) to detect that the synthesizer is ready to be used, asynchronously.

I've just added this to detect that TNSTextToSpeech is ready :

constructor() { console.log("init SpeakerService") this.TTS = new TNSTextToSpeech(); console.log("end init SpeakerService", JSON.stringify(this.TTS)) }

I've checked this.TTS inside play method, it also have the same instance as constructor

I can also confirm that when I add this inside finishedCallback function (in play method) :

this.TTS.destroy(); this.TTS = new TNSTextToSpeech();

Then every next call to play method take also 10-12s to play

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/bradmartin/nativescript-texttospeech/issues/7#issuecomment-293314476, or mute the thread https://github.com/notifications/unsubscribe-auth/AFulhLlkLT8wUaC2exAVXNtWghsHsbjjks5ru6aZgaJpZM4M6Gjp .

GrEg00z commented 7 years ago

Yeah it's not also what I want destroy the instance It was just for yours informations and help for debug.

But anyway it's still a problem to be used in my app. I will try to give you more informations about this

rkhayyat commented 7 years ago

I confirm the long delay of instanciation as it happened with GrEg00z ( arround 10-12 sec), and by the way, only when I use the english language en-USA, it is much faster in instanciation

GrEg00z commented 7 years ago

Yes the same for me, with english language it's very fast on first playing

bradmartin commented 7 years ago

On android it's a second or two to init for the device I have. I don't have any iOS devices to test the result there. Sorry. I don't have time to dig in and see what can be done to improve this. If someone wants to help I can answer any questions they might have. I would first start with viewing official documentation on the native speech synthesizers, finding an example from apple and google on using it and then lets make sure we implement it the same way. Then we can look at adding a NS background thread (worker) to the init and see if that's something we can implement with this plugin and run the speech synth on a worker thread 👍

bradmartin commented 7 years ago

https://github.com/bradmartin/nativescript-texttospeech#tip - this should help reduce initial time on the first speak call.