Google Cloud TTS 不同步运行

问题描述 投票:0回答:1

我正在 Android Studio 项目中运行 Google Cloud TTS。我的语音服务课程:

public class SpeechService {

    private static final String TAG = SpeechService.class.getSimpleName();
    private static final String ttsAPIUrl = "https://texttospeech.googleapis.com/v1/text:synthesize";

    private static final String APIKey = "APIKEY"; // Replace with your API key

    private boolean busy = false;
    private MediaPlayer mediaPlayer;
    private SpeechCallback speechCallback;

    private static SpeechService instance;

    public static SpeechService getInstance(Context context) {
        if (instance == null) {
            instance = new SpeechService(context);
        }
        return instance;
    }

    private Context context;

    // Update the constructor to accept a Context instance
    private SpeechService(Context context) {
        this.context = context;
    }

    public void speak(String text, SpeechCallback callback) {
        if (busy) {
            Log.d(TAG, "Speech Service busy!");
            return;
        }

        busy = true;
        speechCallback = callback;

        new TextToSpeechTask().execute(text);
    }

    private class TextToSpeechTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            String text = params[0];

            try {
                JSONObject postData = buildPostData(text);
                String response = makePOSTRequest(ttsAPIUrl, postData.toString());

                JSONObject jsonResponse = new JSONObject(response);

                if (jsonResponse.has("audioContent")) {
                    String audioContent = jsonResponse.getString("audioContent");
                    byte[] audioData = Base64.decode(audioContent, Base64.DEFAULT);

                    playAudio(audioData);
                } else {
                    Log.e(TAG, "Invalid response: " + jsonResponse.toString());
                }

            } catch (IOException | JSONException e) {
                Log.e(TAG, "Error: " + e.getMessage());
            }

            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            busy = false;

            if (speechCallback != null) {
                speechCallback.onSpeechComplete();
            }
        }
    }

    private JSONObject buildPostData(String text) throws JSONException {
        JSONObject voiceParams = new JSONObject();
        voiceParams.put("languageCode", "en-IN");
        voiceParams.put("name", "en-IN-Neural2-D");

        JSONObject params = new JSONObject();
        params.put("input", new JSONObject().put("text", text));
        params.put("voice", voiceParams);
        params.put("audioConfig", new JSONObject().put("audioEncoding", "LINEAR16"));

        return params;
    }

    private void playAudio(byte[] audioData) {
        try {
            releaseMediaPlayer();

            // Save audio data to a temporary file
            File tempFile = File.createTempFile("tempAudio", ".pcm", context.getCacheDir());
            FileOutputStream fos = new FileOutputStream(tempFile);
            fos.write(audioData);
            fos.close();

            mediaPlayer = new MediaPlayer();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                        .build());
            } else {
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            }

            // Set data source using the temporary file path
            mediaPlayer.setDataSource(tempFile.getAbsolutePath());
            mediaPlayer.prepare();
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    releaseMediaPlayer();
                    // Optionally, delete the temporary file after playback
                    tempFile.delete();
                }
            });

            mediaPlayer.start();

        } catch (IOException e) {
            Log.e(TAG, "Error playing audio: " + e.getMessage());
        }
    }


    private void releaseMediaPlayer() {
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    private String makePOSTRequest(String urlString, String postData) throws IOException {
        URL url = new URL(urlString);
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        try {
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Content-Type", "application/json");
            urlConnection.setRequestProperty("X-Goog-Api-Key", APIKey);

            urlConnection.setDoOutput(true);
            DataOutputStream outputStream = new DataOutputStream(urlConnection.getOutputStream());
            outputStream.write(postData.getBytes());
            outputStream.flush();
            outputStream.close();

            BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;

            while ((line = in.readLine()) != null) {
                response.append(line);
            }

            return response.toString();

        } finally {
            urlConnection.disconnect();
        }
    }

    public interface SpeechCallback {
        void onSpeechComplete();
    }
}

当我在 MainActivity 中使用此类时:

   String textToSpeak = "Hello," + username + ", How are you? Are you ready to play with me?";
        speechService.speak(textToSpeak, new SpeechService.SpeechCallback() {
            @Override
            public void onSpeechComplete() {
                // The first speech is complete, start the second one here
                Log.w("SOUND", "Done with TTS");
            }
        });

甚至在演讲结束之前,它就会打印“Done with TTS”。我该如何解决这个问题?我希望能够根据用户活动嵌套多个文本转语音语句,但如果它们全部同时运行,这是不可能的,这就是现在正在发生的情况。

java android text-to-speech google-text-to-speech
1个回答
0
投票

你应该做 busy = false;在音乐播放器的 onCompletion 中而不是在 onPostExecute

    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
           @Override
           public void onCompletion(MediaPlayer mp) {
           busy = false
           releaseMediaPlayer();
           // Optionally, delete the temporary file after playback
           tempFile.delete();
   } });
© www.soinside.com 2019 - 2024. All rights reserved.