X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff..269195b3729c1bdc22e9053ee4ebca667ea8549d:/Android/folioreader/src/main/java/com/folioreader/ui/folio/mediaoverlay/MediaController.java diff --git a/Android/folioreader/src/main/java/com/folioreader/ui/folio/mediaoverlay/MediaController.java b/Android/folioreader/src/main/java/com/folioreader/ui/folio/mediaoverlay/MediaController.java new file mode 100755 index 0000000..f197530 --- /dev/null +++ b/Android/folioreader/src/main/java/com/folioreader/ui/folio/mediaoverlay/MediaController.java @@ -0,0 +1,243 @@ +package com.folioreader.ui.folio.mediaoverlay; + +import android.annotation.TargetApi; +import android.content.Context; +import android.media.MediaPlayer; +import android.os.Build; +import android.os.Handler; +import android.speech.tts.TextToSpeech; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + +import com.folioreader.Constants; +import com.folioreader.model.event.MediaOverlayPlayPauseEvent; +import com.folioreader.model.event.MediaOverlaySpeedEvent; +import com.folioreader.model.media_overlay.OverlayItems; +import com.folioreader.util.UiUtil; + +import org.readium.r2_streamer.model.publication.SMIL.Clip; +import org.readium.r2_streamer.model.publication.SMIL.MediaOverlays; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; + +/** + * @author gautam chibde on 21/6/17. + */ + +public class MediaController { + + private static final String TAG = MediaController.class.getSimpleName(); + + public enum MediaType { + TTS, SMIL, + } + + private MediaType mediaType; + private MediaControllerCallbacks callbacks; + private Context context; + + //**********************************// + // MEDIA OVERLAY // + //**********************************// + private MediaOverlays mediaOverlays; + private List mediaItems = new ArrayList<>(); + private int mediaItemPosition = 0; + private MediaPlayer mediaPlayer; + + private Clip currentClip; + + private boolean isMediaPlayerReady; + private Handler mediaHandler; + + //*********************************// + // TTS // + //*********************************// + private TextToSpeech mTextToSpeech; + private boolean mIsSpeaking = false; + + public MediaController(Context context, MediaType mediaType, MediaControllerCallbacks callbacks) { + this.mediaType = mediaType; + this.callbacks = callbacks; + this.context = context; + } + + private Runnable mHighlightTask = new Runnable() { + @Override + public void run() { + int currentPosition = mediaPlayer.getCurrentPosition(); + if (mediaPlayer.getDuration() != currentPosition) { + if (mediaItemPosition < mediaItems.size()) { + int end = (int) currentClip.end * 1000; + if (currentPosition > end) { + mediaItemPosition++; + currentClip = mediaOverlays.clip(mediaItems.get(mediaItemPosition).getId()); + if (currentClip != null) { + callbacks.highLightText(mediaItems.get(mediaItemPosition).getId()); + } else { + mediaItemPosition++; + } + } + mediaHandler.postDelayed(mHighlightTask, 10); + } else { + mediaHandler.removeCallbacks(mHighlightTask); + } + } + } + }; + + public void resetMediaPosition() { + mediaItemPosition = 0; + } + + public void setSMILItems(List overlayItems) { + this.mediaItems = overlayItems; + } + + public void next() { + mediaItemPosition++; + } + + public void setTextToSpeech(final Context context) { + mTextToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() { + @Override + public void onInit(int status) { + if (status != TextToSpeech.ERROR) { + mTextToSpeech.setLanguage(Locale.getDefault()); + mTextToSpeech.setSpeechRate(0.70f); + } + + mTextToSpeech.setOnUtteranceCompletedListener( + new TextToSpeech.OnUtteranceCompletedListener() { + @Override + public void onUtteranceCompleted(String utteranceId) { + ((AppCompatActivity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + if (mIsSpeaking) { + callbacks.highLightTTS(); + } + } + }); + } + }); + } + }); + } + + public void setUpMediaPlayer(MediaOverlays mediaOverlays, String path, String mBookTitle) { + this.mediaOverlays = mediaOverlays; + mediaHandler = new Handler(); + try { + mediaItemPosition = 0; + String uri = Constants.LOCALHOST + mBookTitle + "/" + path; + mediaPlayer = new MediaPlayer(); + mediaPlayer.setDataSource(uri); + mediaPlayer.prepare(); + isMediaPlayerReady = true; + } catch (IOException e) { + Log.d(TAG, e.getMessage()); + } + } + + public void setSpeed(MediaOverlaySpeedEvent.Speed speed) { + switch (speed) { + case HALF: + setPlaybackSpeed(0.5f); + break; + case ONE: + setPlaybackSpeed(1.0f); + break; + case ONE_HALF: + setPlaybackSpeed(1.5f); + break; + case TWO: + setPlaybackSpeed(2.0f); + break; + } + } + + @TargetApi(Build.VERSION_CODES.M) + private void setPlaybackSpeed(float speed) { + if (mediaType == MediaType.SMIL) { + if (mediaPlayer != null && mediaPlayer.isPlaying()) { + mediaPlayer.setPlaybackParams(mediaPlayer.getPlaybackParams().setSpeed(speed)); + } + } else { + mTextToSpeech.setSpeechRate(speed); + } + } + + public void stateChanged(MediaOverlayPlayPauseEvent event) { + if (event.isStateChanged()) { + if (mediaPlayer != null) { + mediaPlayer.pause(); + } + if (mTextToSpeech != null && mTextToSpeech.isSpeaking()) { + mTextToSpeech.stop(); + } + } else { + if (event.isPlay()) { + UiUtil.keepScreenAwake(true, context); + } else { + UiUtil.keepScreenAwake(false, context); + } + if (mediaType == MediaType.SMIL) { + playSMIL(); + } else { + if (mTextToSpeech.isSpeaking()) { + mTextToSpeech.stop(); + mIsSpeaking = false; + callbacks.resetCurrentIndex(); + } else { + mIsSpeaking = true; + callbacks.highLightTTS(); + } + } + } + } + + private void playSMIL() { + if (mediaPlayer != null && isMediaPlayerReady) { + if (mediaPlayer.isPlaying()) { + mediaPlayer.pause(); + } else { + currentClip = mediaOverlays.clip(mediaItems.get(mediaItemPosition).getId()); + if (currentClip != null) { + mediaPlayer.start(); + mediaHandler.post(mHighlightTask); + } else { + mediaItemPosition++; + mediaPlayer.start(); + mediaHandler.post(mHighlightTask); + } + } + } + } + + public void speakAudio(String sentence) { + if (mediaType == MediaType.TTS) { + HashMap params = new HashMap<>(); + params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "stringId"); + mTextToSpeech.speak(sentence, TextToSpeech.QUEUE_FLUSH, params); + } + } + + public void stop() { + if (mTextToSpeech != null) { + if (mTextToSpeech.isSpeaking()) { + mTextToSpeech.stop(); + } + mTextToSpeech.shutdown(); + } + if (mediaPlayer != null && mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + mediaPlayer.release(); + mediaPlayer = null; + mediaHandler.removeCallbacks(mHighlightTask); + } + } +}