【问题标题】:Google's Text-To-Speech API from Android app来自 Android 应用的 Google 文本转语音 API
【发布时间】:2015-10-04 17:09:15
【问题描述】:

我想在 Android 应用程序中使用 Google 的 Text-To-Speech API,但我只能通过网络 (Chrome) 找到方法。这是我第一次尝试从应用程序播放“Hello world”。

playTTS 是onClick,它被执行了,但是没有声音。我需要导入任何 JS/Java 库吗?是否可以从中生成音频文件?

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    myBrowser = new WebView(this);
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }
}

public void playTTS(View view) {
    myBrowser.loadUrl("javascript:speechSynthesis.speak(
         SpeechSynthesisUtterance('Hello World'))");
}

【问题讨论】:

    标签: javascript android text-to-speech speech-synthesis


    【解决方案1】:

    在 Android java 代码中,您的 Activity/其他类应该实现 TextToSpeech.OnInitListener。您将通过调用TextToSpeech(context, this) 获得TextToSpeech 实例。 (其中context 指的是您的应用程序的上下文——可以是活动中的this。)然后您将收到带有statusonInit() 回调,它告诉您TTS 引擎是否可用。

    您可以拨打tts.speak(textToBeSpoken, TextToSpeech.QUEUE_FLUSH, null)tts.speak(textToBeSpoken, TextToSpeech.QUEUE_ADD, null) 交谈。第一个将打断仍在说的任何“话语”,后一个将把新的“话语”添加到队列中。最后一个参数不是强制性的。如果您想通过设置UtteranceProgressListener 来监控 TTS 状态,它可能是您定义的“话语 ID”。 (没必要)

    在 Java 代码中,一个简单的“TTS talker”类可能类似于:

    public class MyTtsTalker implements TextToSpeech.OnInitListener {
    
      private TextToSpeech tts;
      private boolean ttsOk;
    
      // The constructor will create a TextToSpeech instance.
      MyTtsTalker(Context context) {
        tts = new TextToSpeech(context, this);
      }
    
      @Override
      // OnInitListener method to receive the TTS engine status
      public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
          ttsOk = true;
        }
        else {
          ttsOk = false;
        }
      }
    
      // A method to speak something
      @SuppressWarnings("deprecation") // Support older API levels too.
      public void speak(String text, Boolean override) {
        if (ttsOk) {
          if (override) {
            tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);    
          }    
          else {
            tts.speak(text, TextToSpeech.QUEUE_ADD, null);    
          }
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      TTS 代码:


      import android.annotation.TargetApi;
      import android.content.Context;
      import android.os.Build;
      import android.speech.tts.TextToSpeech;
      import android.speech.tts.UtteranceProgressListener;
      import android.util.Log;
      import android.webkit.JavascriptInterface;
      import android.webkit.WebView;
      import android.widget.Toast;
      
      import java.util.HashMap;
      import java.util.Locale;
      
      public class KiwixTextToSpeech {
      
          public static final String TAG_ASKQ = "askq;
      
          private Context context;
      
          private OnSpeakingListener onSpeakingListener;
      
          private WebView webView;
      
          private TextToSpeech tts;
      
          private boolean initialized = false;
      
          /**
           * Constructor.
           *
           * @param context               the context to create TextToSpeech with
           * @param webView               {@link android.webkit.WebView} to take contents from
           * @param onInitSucceedListener listener that receives event when initialization of TTS is done
           *                              (and does not receive if it failed)
           * @param onSpeakingListener    listener that receives an event when speaking just started or
           *                              ended
           */
          public KiwixTextToSpeech(Context context, WebView webView,
                  final OnInitSucceedListener onInitSucceedListener,
                  final OnSpeakingListener onSpeakingListener) {
              Log.d(TAG_ASKQ, "Initializing TextToSpeech");
      
              this.context = context;
              this.onSpeakingListener = onSpeakingListener;
              this.webView = webView;
              this.webView.addJavascriptInterface(new TTSJavaScriptInterface(), "tts");
      
              initTTS(onInitSucceedListener);
          }
      
          @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
          private void initTTS(final OnInitSucceedListener onInitSucceedListener) {
              tts = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
                  @Override
                  public void onInit(int status) {
                      if (status == TextToSpeech.SUCCESS) {
                          Log.d(TAG_ASKQ, "TextToSpeech was initialized successfully.");
                          initialized = true;
                          onInitSucceedListener.onInitSucceed();
                      } else {
                          Log.e(TAG_ASKQ, "Initilization of TextToSpeech Failed!");
                      }
                  }
              });
      
              tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                  @Override
                  public void onStart(String utteranceId) {
                  }
      
                  @Override
                  public void onDone(String utteranceId) {
                      Log.e(TAG_ASKQ, "TextToSpeech: " + utteranceId);
                      onSpeakingListener.onSpeakingEnded();
                  }
      
                  @Override
                  public void onError(String utteranceId) {
                      Log.e(TAG_ASKQ, "TextToSpeech: " + utteranceId);
                      onSpeakingListener.onSpeakingEnded();
                  }
              });
          }
      
          /**
           * Reads the currently selected text in the WebView.
           */
          public void readSelection() {
            webView.loadUrl("javascript:tts.speakAloud(window.getSelection().toString());", null);
          }
      
          /**
           * Starts speaking the WebView content aloud (or stops it if TTS is speaking now).
           */
          public void readAloud() {
              if (tts.isSpeaking()) {
                  if (tts.stop() == TextToSpeech.SUCCESS) {
                      onSpeakingListener.onSpeakingEnded();
                  }
              } else {
                  Locale locale = LanguageUtils.ISO3ToLocale(ZimContentProvider.getLanguage());
                  int result;
                  if (locale == null
                          || (result = tts.isLanguageAvailable(locale)) == TextToSpeech.LANG_MISSING_DATA
                          || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                      Log.d(TAG_ASKQ, "TextToSpeech: language not supported: " +
                              ZimContentProvider.getLanguage() + " (" + locale.getLanguage() + ")");
                      Toast.makeText(context,
                              context.getResources().getString(R.string.tts_lang_not_supported),
                              Toast.LENGTH_LONG).show();
                  } else {
                      tts.setLanguage(locale);
      
                      // We use JavaScript to get the content of the page conveniently, earlier making some
                      // changes in the page
                      webView.loadUrl("javascript:" +
                              "body = document.getElementsByTagName('body')[0].cloneNode(true);" +
                              // Remove some elements that are shouldn't be read (table of contents,
                              // references numbers, thumbnail captions, duplicated title, etc.)
                              "toRemove = body.querySelectorAll('sup.reference, #toc, .thumbcaption, " +
                              "    title, .navbox');" +
                              "Array.prototype.forEach.call(toRemove, function(elem) {" +
                              "    elem.parentElement.removeChild(elem);" +
                              "});" +
                              "tts.speakAloud(body.innerText);");
                  }
              }
          }
      
          /**
           * Returns whether the TTS is initialized.
           *
           * @return <code>true</code> if TTS is initialized; <code>false</code> otherwise
           */
          public boolean isInitialized() {
              return initialized;
          }
      
          /**
           * Releases the resources used by the engine.
           *
           * @see android.speech.tts.TextToSpeech#shutdown()
           */
          public void shutdown() {
              tts.shutdown();
          }
      
          /**
           * The listener which is notified when initialization of the TextToSpeech engine is successfully
           * done.
           */
          public interface OnInitSucceedListener {
      
              public void onInitSucceed();
          }
      
          /**
           * The listener that is notified when speaking starts or stops (regardless of whether it was a
           * result of error, user, or because whole text was read).
           *
           * Note that the methods of this interface may not be called from the UI thread.
           */
          public interface OnSpeakingListener {
      
              public void onSpeakingStarted();
      
              public void onSpeakingEnded();
          }
      
          private class TTSJavaScriptInterface {
      
              @JavascriptInterface
              @SuppressWarnings("unused")
              public void speakAloud(String content) {
                  String[] lines = content.split("\n");
                  for (int i = 0; i < lines.length - 1; i++) {
                      String line = lines[i];
                      tts.speak(line, TextToSpeech.QUEUE_ADD, null);
                  }
      
                  HashMap<String, String> params = new HashMap<>();
                  // The utterance ID isn't actually used anywhere, the param is passed only to force
                  // the utterance listener to be notified
                  params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "kiwixLastMessage");
                  tts.speak(lines[lines.length - 1], TextToSpeech.QUEUE_ADD, params);
      
                  if (lines.length > 0) {
                      onSpeakingListener.onSpeakingStarted();
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-29
        • 2018-03-29
        • 2021-07-01
        相关资源
        最近更新 更多