【问题标题】:Text to Speech Crashes文字转语音崩溃
【发布时间】:2014-10-20 08:57:24
【问题描述】:

我在使用 android TTS 时遇到了问题。

我制作了一款游戏,它会为每个游戏周期宣布一个数字。几个循环后游戏崩溃。查看 logcat,AudioPlayer 似乎空间不足“AudioFlinger?没有更多可用的轨道名称”。

所以经过一番搜索,我找到了这个问题。

AudioFlinger could not create track. status: -12

这有助于指出,Android 对每台设备的活动 AudioTrack 对象的硬性限制是 32 个。回到 logcat,我发现它已经宣布了 32 次。所以看来我的对象用完了。

所以我最初的想法是关闭 TTS 引擎并在 30 次公告后重新初始化它,游戏播放会有短暂的暂停,但还不错。不幸的是,这并没有奏效。似乎关闭 TTS 引擎不会重置 AudioTrack 对象。

我玩过这个游戏,发现你可以玩到崩溃之前,关闭程序,重新启动它并继续玩而不崩溃(直到它达到 32 连续播放。)所以有一种方法要释放 AudioTrack 对象,在 logcat 中它谈到“AwesomePlayer reset”在线搜索我不认为有一种方法可以控制 AwesomePlayer。

所以我的问题是,如何清除 AudioTrack 对象?有一个函数“release()”并且只有一组 AudioTracks,我只是不确定如何让它工作。

欢迎任何其他关于如何清除 AudoTrack 对象的想法。

感谢 TC

附:我很确定我已经正确实现了 TTS 这是我的代码

    private void playNumber() {
    if (inPlay) {

        numbersPlayed += 1;

        Log.d("TOM", "playNumber");

        Locale loc = new Locale("spa", "ESP");
        mTts.setLanguage(loc);

        String genNum = String.valueOf(generatedNumber);
        Log.d("TOM", "genNum to String");

        HashMap<String, String> map = new HashMap<String, String>();

        Log.d("TOM", "toHashMap");

        map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "TTS Stopped");

        Log.d("TOM", "mapPut");

        mTts.speak(genNum, TextToSpeech.QUEUE_FLUSH, map);

        Log.d("TOM", "TTSSpeak");

        mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() {

            @Override
            public void onStart(String utteranceId) {
                enterLock = true;

                Log.d("TOM", "uttStart");
            }

            @Override
            public void onDone(String utteranceId) {
                enterLock = false;
                timerCount.start();
                Log.d("TOM", "uttDone");
            }

            @Override
            public void onError(String utteranceId) {
                Log.d("TOM", "uttError");
            }
        });
    }
}

public void onInit(int i) {

    if (generatedNumber == -2) {
        enterLock = false;
        Toast.makeText(this, getString(R.string.ttsReady_toast), Toast.LENGTH_SHORT).show();
        Log.d("TOM", "onInit: " + Boolean.toString(inPlay));
    } else {
        playNumber();
        Log.d("TOM", "New Start Play");
    }
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_DATA_CHECK_CODE) {
        if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
            mTts = new TextToSpeech(this, this);
            Log.d("TOM", "ttsEngineOK");
        } else {
            Intent installIntent = new Intent();
            installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
            startActivity(installIntent);
            Log.d("TOM", "ttsEngineError");
        }
    }
}

【问题讨论】:

  • 抱歉 - 我想我的意思是说“指出 Android 对每个设备有 32 个活动 AudioTrack 对象的硬性限制。”
  • 不确定它是否真的能解决您的问题,但您不必在每次调用speak() 方法时都设置UtteranceProgressListener。例如,在mTts = new TextToSpeech(this, this); 调用之后设置一次就足够了。
  • 另外,您应该考虑为 TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID 使用唯一 ID,而不仅仅是硬编码的 "TTS Stopped" 字符串。
  • 好的,亚历克西斯,感谢您的建议。

标签: android text-to-speech


【解决方案1】:

我发现了我的问题。

我真的觉得有点傻,问题与 TTS 引擎无关。实际问题在于当播放器得到正确答案时我正在播放的媒体播放器剪辑。我设置它的方式,每次答案正确时都会创建一个新的媒体播放器对象,因此这达到了 32 AudioTrack 的限制,而不是 TTS。我刚刚把 mediaPlayer.create 函数放在了 onCreate 应该放在的地方,现在一切都很好!!!

这教会了我不要把所有代码都放在上面,我相信有更多经验的人会马上注意到这一点。

【讨论】:

    猜你喜欢
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多