use of com.ichi2.libanki.Sound in project Anki-Android by ankidroid.
the class Sound method playSoundInternal.
/**
* Plays a sound without ensuring that the playAllListener will release the audio
*/
@SuppressWarnings({ "PMD.EmptyIfStmt", "PMD.CollapsibleIfStatements" })
private void playSoundInternal(String soundPath, @NonNull OnCompletionListener playAllListener, VideoView videoView, OnErrorListener errorListener) {
Timber.d("Playing %s has listener? %b", soundPath, playAllListener != null);
Uri soundUri = Uri.parse(soundPath);
mCurrentAudioUri = soundUri;
final OnErrorListener errorHandler = errorListener == null ? (mp, what, extra, path) -> {
Timber.w("Media Error: (%d, %d). Calling OnCompletionListener", what, extra);
return false;
} : errorListener;
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(Locale.getDefault());
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 && hasVideoThumbnail(soundUri);
// 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, which, extra) -> errorHandler.onError(mp, which, extra, soundPath));
// Setup the MediaPlayer
mMediaPlayer.setDataSource(AnkiDroidApp.getInstance().getApplicationContext(), soundUri);
mMediaPlayer.setAudioAttributes(new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build());
mMediaPlayer.setOnPreparedListener(mp -> {
Timber.d("Starting media player");
mMediaPlayer.start();
});
mMediaPlayer.setOnCompletionListener(playAllListener);
mMediaPlayer.prepareAsync();
Timber.d("Requesting audio focus");
// Set mAudioFocusRequest for API 26 and above.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAudioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK).setOnAudioFocusChangeListener(afChangeListener).build();
}
CompatHelper.getCompat().requestAudioFocus(mAudioManager, afChangeListener, mAudioFocusRequest);
} catch (Exception e) {
Timber.e(e, "playSounds - Error reproducing sound %s", soundPath);
if (!errorHandler.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNSUPPORTED, 0, soundPath)) {
Timber.d("Force playing next sound.");
playAllListener.onCompletion(mMediaPlayer);
}
}
}
}
use of com.ichi2.libanki.Sound in project Anki-Android by ankidroid.
the class CollectionTest method test_furigana.
@Test
@Ignore("Pending port of media search from Rust code")
public void test_furigana() {
Collection col = getCol();
ModelManager mm = col.getModels();
Model m = mm.current();
// filter should work
m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:Front}}");
mm.save(m);
Note n = col.newNote();
n.setItem("Front", "foo[abc]");
col.addNote(n);
Card c = n.cards().get(0);
assertTrue(c.q().endsWith("abc"));
// and should avoid sound
n.setItem("Front", "foo[sound:abc.mp3]");
n.flush();
String question = c.q(true);
assertThat("Question «" + question + "» does not contains «anki:play».", question, containsString("anki:play"));
// it shouldn't throw an error while people are editing
m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:}}");
mm.save(m);
c.q(true);
}
use of com.ichi2.libanki.Sound in project Anki-Android by Ramblurr.
the class NoteService method updateMultimediaNoteFromJsonNote.
public static void updateMultimediaNoteFromJsonNote(final Note editorNoteSrc, final IMultimediaEditableNote noteDst) {
if (noteDst instanceof MultimediaEditableNote) {
MultimediaEditableNote mmNote = (MultimediaEditableNote) noteDst;
String[] values = editorNoteSrc.getFields();
for (int i = 0; i < values.length; i++) {
String value = values[i];
IField field = null;
if (value.startsWith("<img")) {
field = new ImageField();
} else if (value.startsWith("[sound:")) {
field = new AudioField();
} else {
field = new TextField();
}
field.setFormattedString(value);
mmNote.setField(i, field);
}
mmNote.setModelId(editorNoteSrc.getMid());
// TODO: set current id of the note as well
}
}
use of com.ichi2.libanki.Sound 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.libanki.Sound 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();
}
}
}
Aggregations