1 package com.folioreader.ui.folio.mediaoverlay;
3 import android.annotation.TargetApi;
4 import android.content.Context;
5 import android.media.MediaPlayer;
6 import android.os.Build;
7 import android.os.Handler;
8 import android.speech.tts.TextToSpeech;
9 import android.support.v7.app.AppCompatActivity;
10 import android.util.Log;
12 import com.folioreader.Constants;
13 import com.folioreader.model.event.MediaOverlayPlayPauseEvent;
14 import com.folioreader.model.event.MediaOverlaySpeedEvent;
15 import com.folioreader.model.media_overlay.OverlayItems;
16 import com.folioreader.util.UiUtil;
18 import org.readium.r2_streamer.model.publication.SMIL.Clip;
19 import org.readium.r2_streamer.model.publication.SMIL.MediaOverlays;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Locale;
28 * @author gautam chibde on 21/6/17.
31 public class MediaController {
33 private static final String TAG = MediaController.class.getSimpleName();
35 public enum MediaType {
39 private MediaType mediaType;
40 private MediaControllerCallbacks callbacks;
41 private Context context;
43 //**********************************//
45 //**********************************//
46 private MediaOverlays mediaOverlays;
47 private List<OverlayItems> mediaItems = new ArrayList<>();
48 private int mediaItemPosition = 0;
49 private MediaPlayer mediaPlayer;
51 private Clip currentClip;
53 private boolean isMediaPlayerReady;
54 private Handler mediaHandler;
56 //*********************************//
58 //*********************************//
59 private TextToSpeech mTextToSpeech;
60 private boolean mIsSpeaking = false;
62 public MediaController(Context context, MediaType mediaType, MediaControllerCallbacks callbacks) {
63 this.mediaType = mediaType;
64 this.callbacks = callbacks;
65 this.context = context;
68 private Runnable mHighlightTask = new Runnable() {
71 int currentPosition = mediaPlayer.getCurrentPosition();
72 if (mediaPlayer.getDuration() != currentPosition) {
73 if (mediaItemPosition < mediaItems.size()) {
74 int end = (int) currentClip.end * 1000;
75 if (currentPosition > end) {
77 currentClip = mediaOverlays.clip(mediaItems.get(mediaItemPosition).getId());
78 if (currentClip != null) {
79 callbacks.highLightText(mediaItems.get(mediaItemPosition).getId());
84 mediaHandler.postDelayed(mHighlightTask, 10);
86 mediaHandler.removeCallbacks(mHighlightTask);
92 public void resetMediaPosition() {
93 mediaItemPosition = 0;
96 public void setSMILItems(List<OverlayItems> overlayItems) {
97 this.mediaItems = overlayItems;
104 public void setTextToSpeech(final Context context) {
105 mTextToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
107 public void onInit(int status) {
108 if (status != TextToSpeech.ERROR) {
109 mTextToSpeech.setLanguage(Locale.getDefault());
110 mTextToSpeech.setSpeechRate(0.70f);
113 mTextToSpeech.setOnUtteranceCompletedListener(
114 new TextToSpeech.OnUtteranceCompletedListener() {
116 public void onUtteranceCompleted(String utteranceId) {
117 ((AppCompatActivity) context).runOnUiThread(new Runnable() {
121 callbacks.highLightTTS();
131 public void setUpMediaPlayer(MediaOverlays mediaOverlays, String path, String mBookTitle) {
132 this.mediaOverlays = mediaOverlays;
133 mediaHandler = new Handler();
135 mediaItemPosition = 0;
136 String uri = Constants.LOCALHOST + mBookTitle + "/" + path;
137 mediaPlayer = new MediaPlayer();
138 mediaPlayer.setDataSource(uri);
139 mediaPlayer.prepare();
140 isMediaPlayerReady = true;
141 } catch (IOException e) {
142 Log.d(TAG, e.getMessage());
146 public void setSpeed(MediaOverlaySpeedEvent.Speed speed) {
149 setPlaybackSpeed(0.5f);
152 setPlaybackSpeed(1.0f);
155 setPlaybackSpeed(1.5f);
158 setPlaybackSpeed(2.0f);
163 @TargetApi(Build.VERSION_CODES.M)
164 private void setPlaybackSpeed(float speed) {
165 if (mediaType == MediaType.SMIL) {
166 if (mediaPlayer != null && mediaPlayer.isPlaying()) {
167 mediaPlayer.setPlaybackParams(mediaPlayer.getPlaybackParams().setSpeed(speed));
170 mTextToSpeech.setSpeechRate(speed);
174 public void stateChanged(MediaOverlayPlayPauseEvent event) {
175 if (event.isStateChanged()) {
176 if (mediaPlayer != null) {
179 if (mTextToSpeech != null && mTextToSpeech.isSpeaking()) {
180 mTextToSpeech.stop();
183 if (event.isPlay()) {
184 UiUtil.keepScreenAwake(true, context);
186 UiUtil.keepScreenAwake(false, context);
188 if (mediaType == MediaType.SMIL) {
191 if (mTextToSpeech.isSpeaking()) {
192 mTextToSpeech.stop();
194 callbacks.resetCurrentIndex();
197 callbacks.highLightTTS();
203 private void playSMIL() {
204 if (mediaPlayer != null && isMediaPlayerReady) {
205 if (mediaPlayer.isPlaying()) {
208 currentClip = mediaOverlays.clip(mediaItems.get(mediaItemPosition).getId());
209 if (currentClip != null) {
211 mediaHandler.post(mHighlightTask);
215 mediaHandler.post(mHighlightTask);
221 public void speakAudio(String sentence) {
222 if (mediaType == MediaType.TTS) {
223 HashMap<String, String> params = new HashMap<>();
224 params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "stringId");
225 mTextToSpeech.speak(sentence, TextToSpeech.QUEUE_FLUSH, params);
230 if (mTextToSpeech != null) {
231 if (mTextToSpeech.isSpeaking()) {
232 mTextToSpeech.stop();
234 mTextToSpeech.shutdown();
236 if (mediaPlayer != null && mediaPlayer.isPlaying()) {
238 mediaPlayer.release();
240 mediaHandler.removeCallbacks(mHighlightTask);