use of com.ichi2.anki.cardviewer.TTS in project AnkiChinaAndroid by ankichinateam.
the class ReadText method selectTtsForVip.
public static void selectTtsForVip(String text, long cid, long did, int ord, Sound.SoundSide qa, boolean vipSpeak) {
Timber.w("selectTts:%s", vipSpeak);
// TODO: Consolidate with ReadText.readCardSide
mTextToSpeak = text;
mQuestionAnswer = qa;
mDid = did;
mOrd = ord;
Resources res = mReviewer.get().getResources();
final MaterialDialog.Builder builder = new MaterialDialog.Builder(mReviewer.get());
// Build the language list if it's empty
if (availableTtsLocales.isEmpty()) {
buildAvailableLanguages(TextToSpeech.LANG_AVAILABLE);
}
if (availableTtsLocales.size() == 0) {
Timber.w("ReadText.textToSpeech() no TTS languages available");
builder.content(res.getString(R.string.no_tts_available_message)).iconAttr(R.attr.dialogErrorIcon).positiveText(res.getString(R.string.dialog_ok));
} else {
if (vipSpeak) {
for (int i = 0; i < availableTtsLocales.size(); i++) {
// vip里的设置,默认选择中文
String name = availableTtsLocales.get(i).getDisplayName();
if (name.contains("chinese") || name.contains("Chinese") || name.contains("中文") || name.contains("中国")) {
// 默认选择中文
String locale = availableTtsLocales.get(i).getISO3Language();
// if (!locale.equals(NO_TTS)) {
// speak(mTextToSpeak, locale, TextToSpeech.QUEUE_FLUSH);
// }
MetaDB.storeLanguage(mReviewer.get(), mDid, mOrd, mQuestionAnswer, locale);
return;
}
}
CustomStyleDialog d = new CustomStyleDialog.Builder(mReviewer.get()).setCustomLayout(R.layout.dialog_common_custom_next).setTitle("首次朗读,请设置语言").centerTitle().setMessage("设置语言后,朗读效果更优,还可以选择是否自动朗读。").setPositiveButton("前往设置", (dialog, which) -> {
dialog.dismiss();
SpeakSettingActivity.OpenSpeakSetting(cid, did, mReviewer.get());
}).create();
d.show();
}
}
}
use of com.ichi2.anki.cardviewer.TTS in project AnkiChinaAndroid by ankichinateam.
the class ReadText method initializeTts.
public static String initializeTts(Context context, boolean vipSpeak, boolean showToast, ReadTextListener listener) {
// Store weak reference to Activity to prevent memory leak
mReviewer = new WeakReference<>(context);
// Create new TTS object and setup its onInit Listener
mTts = new TextToSpeech(context, status -> {
if (status == TextToSpeech.SUCCESS) {
// build list of available languages
buildAvailableLanguages(TextToSpeech.LANG_AVAILABLE);
if (availableTtsLocales.size() > 0) {
// notify the reviewer that TTS has been initialized
Timber.d("TTS initialized and available languages found");
if (listener != null) {
listener.ttsInitialized();
}
// ((AbstractFlashcardViewer) mReviewer.get()).ttsInitialized();
} else {
if (showToast) {
Toast.makeText(mReviewer.get(), mReviewer.get().getString(R.string.no_tts_available_message), Toast.LENGTH_LONG).show();
}
Timber.w("TTS initialized but no available languages found");
}
mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onDone(String arg0) {
if (ReadText.sTextQueue.size() > 0) {
String[] text = ReadText.sTextQueue.remove(0);
ReadText.speak(text[0], text[1], TextToSpeech.QUEUE_FLUSH);
}
if (listener != null) {
listener.onDone();
}
}
@Override
@Deprecated
public void onError(String utteranceId) {
Timber.v("Andoid TTS failed. Check logcat for error. Indicates a problem with Android TTS engine.");
final Uri helpUrl = Uri.parse(mReviewer.get().getString(R.string.link_faq_tts));
final AnkiActivity ankiActivity = (AnkiActivity) mReviewer.get();
ankiActivity.mayOpenUrl(helpUrl);
if (showToast) {
UIUtils.showSnackbar(ankiActivity, R.string.no_tts_available_message, false, R.string.help, v -> openTtsHelpUrl(helpUrl), ankiActivity.findViewById(R.id.root_layout), new Snackbar.Callback());
}
}
@Override
public void onStart(String arg0) {
// no nothing
}
});
} else {
if (showToast) {
Toast.makeText(mReviewer.get(), mReviewer.get().getString(R.string.no_tts_available_message), Toast.LENGTH_LONG).show();
}
Timber.w("TTS not successfully initialized");
}
});
// Show toast that it's getting initialized, as it can take a while before the sound plays the first time
if (showToast) {
Toast.makeText(context, context.getString(R.string.initializing_tts), Toast.LENGTH_LONG).show();
}
return mTts.getDefaultEngine();
}
use of com.ichi2.anki.cardviewer.TTS in project AnkiChinaAndroid by ankichinateam.
the class Sound method playSoundInternal.
/**
* Plays a sound without ensuring that the playAllListener will release the audio
*/
// audio API deprecation tracked on github as #5022
@SuppressWarnings({ "PMD.EmptyIfStmt", "PMD.CollapsibleIfStatements", "deprecation" })
private void playSoundInternal(String soundPath, OnCompletionListener playAllListener, VideoView videoView) {
Timber.d("Playing %s has listener? %b", soundPath, playAllListener != null);
Uri soundUri = Uri.parse(soundPath);
if ("tts".equals(soundPath.substring(0, 3))) {
// TODO: give information about did
// ReadText.textToSpeech(soundPath.substring(4, soundPath.length()),
// Integer.parseInt(soundPath.substring(3, 4)));
} else {
// Check if the file extension is that of a known video format
final String extension = soundPath.substring(soundPath.lastIndexOf(".") + 1).toLowerCase();
boolean isVideo = Arrays.asList(VIDEO_WHITELIST).contains(extension);
if (!isVideo) {
final String guessedType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
isVideo = (guessedType != null) && guessedType.startsWith("video/");
}
// Also check that there is a video thumbnail, as some formats like mp4 can be audio only
isVideo = isVideo && ThumbnailUtils.createVideoThumbnail(soundUri.getPath(), MediaStore.Images.Thumbnails.MINI_KIND) != null;
// holder
if (isVideo && videoView == null && mCallingActivity != null && mCallingActivity.get() != null) {
Timber.d("Requesting AbstractFlashcardViewer play video - no SurfaceHolder");
mPlayAllListener = playAllListener;
((AbstractFlashcardViewer) mCallingActivity.get()).playVideo(soundPath);
return;
}
// Play media
try {
// Create media player
if (mMediaPlayer == null) {
Timber.d("Creating media player for playback");
mMediaPlayer = new MediaPlayer();
} else {
Timber.d("Resetting media for playback");
mMediaPlayer.reset();
}
if (mAudioManager == null) {
mAudioManager = (AudioManager) AnkiDroidApp.getInstance().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
}
// Provide a VideoView to the MediaPlayer if valid video file
if (isVideo && videoView != null) {
mMediaPlayer.setDisplay(videoView.getHolder());
mMediaPlayer.setOnVideoSizeChangedListener((mp, width, height) -> configureVideo(videoView, width, height));
}
mMediaPlayer.setOnErrorListener((mp, what, extra) -> {
Timber.w("Media Error: (%d, %d). Calling OnCompletionListener", what, extra);
return false;
});
// Setup the MediaPlayer
mMediaPlayer.setDataSource(AnkiDroidApp.getInstance().getApplicationContext(), soundUri);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnPreparedListener(mp -> {
Timber.d("Starting media player");
mMediaPlayer.start();
});
if (playAllListener != null) {
mMediaPlayer.setOnCompletionListener(playAllListener);
}
mMediaPlayer.prepareAsync();
Timber.d("Requesting audio focus");
mAudioManager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
} catch (Exception e) {
Timber.e(e, "playSounds - Error reproducing sound %s", soundPath);
releaseSound();
}
}
}
use of com.ichi2.anki.cardviewer.TTS in project Anki-Android by ankidroid.
the class AbstractFlashcardViewer method displayCardAnswer.
protected void displayCardAnswer() {
// #7294 Required in case the animation end action does not fire:
actualHideEaseButtons();
Timber.d("displayCardAnswer()");
mMissingImageHandler.onCardSideChange();
mBackButtonPressedToReturn = false;
// prevent answering (by e.g. gestures) before card is loaded
if (mCurrentCard == null) {
return;
}
// TODO needs testing: changing a card's model without flipping it back to the front
// (such as editing a card, then editing the card template)
mTypeAnswer.updateInfo(mCurrentCard, getResources());
// but sometimes failed to do so (e.g. if an OnKeyListener is attached).
if (mTypeAnswer.validForEditText()) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(mAnswerField.getWindowToken(), 0);
}
sDisplayAnswer = true;
mSoundPlayer.stopSounds();
mAnswerField.setVisibility(View.GONE);
// Clean up the user answer and the correct answer
if (!mTypeAnswer.useInputTag()) {
mTypeAnswer.setInput(mAnswerField.getText().toString());
}
mIsSelecting = false;
CardHtml answerContent = mHtmlGenerator.generateHtml(mCurrentCard, false, Side.BACK);
updateCard(answerContent);
displayAnswerBottomBar();
mAutomaticAnswer.onDisplayAnswer();
// If Card-based TTS is enabled, we "automatic display" after the TTS has finished as we don't know the duration
if (!mTTS.isEnabled()) {
mAutomaticAnswer.scheduleAutomaticDisplayQuestion(mUseTimerDynamicMS);
}
}
Aggregations