diff options
author | James Falcon <therealfalcon@gmail.com> | 2013-05-01 22:42:17 -0500 |
---|---|---|
committer | James Falcon <therealfalcon@gmail.com> | 2013-05-01 22:42:17 -0500 |
commit | 332ed1b883aa6a1b76beeca857551e9fc5b01202 (patch) | |
tree | a6dbccb5dc64e80f17a46e6f5cef63f906daca80 /src | |
parent | 6bbde80dd0c21649b9b1b649b16ff61351d3eb9c (diff) | |
parent | b2d8423543165bf086ad7da49d4196d8ff550cee (diff) | |
download | AntennaPod-332ed1b883aa6a1b76beeca857551e9fc5b01202.zip |
Merge branch 'speed' into develop
Diffstat (limited to 'src')
-rw-r--r-- | src/de/danoeh/antennapod/service/PlaybackService.java | 294 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/util/DuckType.java | 115 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/util/playback/AudioPlayer.java | 30 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/util/playback/IPlayer.java | 64 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/util/playback/VideoPlayer.java | 62 |
5 files changed, 478 insertions, 87 deletions
diff --git a/src/de/danoeh/antennapod/service/PlaybackService.java b/src/de/danoeh/antennapod/service/PlaybackService.java index 409ac6b48..56bdce375 100644 --- a/src/de/danoeh/antennapod/service/PlaybackService.java +++ b/src/de/danoeh/antennapod/service/PlaybackService.java @@ -51,9 +51,13 @@ import de.danoeh.antennapod.preferences.UserPreferences; import de.danoeh.antennapod.receiver.MediaButtonReceiver; import de.danoeh.antennapod.receiver.PlayerWidget; import de.danoeh.antennapod.util.BitmapDecoder; +import de.danoeh.antennapod.util.DuckType; import de.danoeh.antennapod.util.flattr.FlattrUtils; +import de.danoeh.antennapod.util.playback.AudioPlayer; +import de.danoeh.antennapod.util.playback.IPlayer; import de.danoeh.antennapod.util.playback.Playable; import de.danoeh.antennapod.util.playback.Playable.PlayableException; +import de.danoeh.antennapod.util.playback.VideoPlayer; /** Controls the MediaPlayer that plays a FeedMedia-file */ public class PlaybackService extends Service { @@ -120,7 +124,7 @@ public class PlaybackService extends Service { private AudioManager audioManager; private ComponentName mediaButtonReceiver; - private MediaPlayer player; + private IPlayer player; private RemoteControlClient remoteControlClient; private Playable media; @@ -232,7 +236,6 @@ public class PlaybackService extends Service { Log.w(TAG, "SchedEx rejected submission of new task"); } }); - player = createMediaPlayer(); mediaButtonReceiver = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName()); @@ -252,18 +255,39 @@ public class PlaybackService extends Service { } - private MediaPlayer createMediaPlayer() { - return createMediaPlayer(new MediaPlayer()); + private IPlayer createMediaPlayer() { + IPlayer player; + if (media == null || media.getMediaType() == MediaType.VIDEO) { + player = new VideoPlayer(); + } else { + player = new AudioPlayer(this); + } + return createMediaPlayer(player); } - private MediaPlayer createMediaPlayer(MediaPlayer mp) { - if (mp != null) { - mp.setOnPreparedListener(preparedListener); - mp.setOnCompletionListener(completionListener); - mp.setOnSeekCompleteListener(onSeekCompleteListener); - mp.setOnErrorListener(onErrorListener); - mp.setOnBufferingUpdateListener(onBufferingUpdateListener); - mp.setOnInfoListener(onInfoListener); + private IPlayer createMediaPlayer(IPlayer mp) { + if (mp != null && media != null) { + if (media.getMediaType() == MediaType.AUDIO) { + ((AudioPlayer) mp).setOnPreparedListener(audioPreparedListener); + ((AudioPlayer) mp) + .setOnCompletionListener(audioCompletionListener); + ((AudioPlayer) mp) + .setOnSeekCompleteListener(audioSeekCompleteListener); + ((AudioPlayer) mp).setOnErrorListener(audioErrorListener); + ((AudioPlayer) mp) + .setOnBufferingUpdateListener(audioBufferingUpdateListener); + ((AudioPlayer) mp).setOnInfoListener(audioInfoListener); + } else { + ((VideoPlayer) mp).setOnPreparedListener(videoPreparedListener); + ((VideoPlayer) mp) + .setOnCompletionListener(videoCompletionListener); + ((VideoPlayer) mp) + .setOnSeekCompleteListener(videoSeekCompleteListener); + ((VideoPlayer) mp).setOnErrorListener(videoErrorListener); + ((VideoPlayer) mp) + .setOnBufferingUpdateListener(videoBufferingUpdateListener); + ((VideoPlayer) mp).setOnInfoListener(videoInfoListener); + } } return mp; } @@ -367,7 +391,6 @@ public class PlaybackService extends Service { || !playable.getIdentifier().equals(media.getIdentifier()) || playbackType != shouldStream) { pause(true, false); - player.reset(); sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0); if (media == null || !playable.getIdentifier().equals( @@ -502,7 +525,6 @@ public class PlaybackService extends Service { player.setDisplay(null); player.reset(); player.release(); - player = createMediaPlayer(); status = PlayerStatus.STOPPED; if (media != null) { initMediaplayer(); @@ -518,6 +540,10 @@ public class PlaybackService extends Service { if (AppConfig.DEBUG) Log.d(TAG, "Setting up media player"); try { + if (player != null) { + player.release(); + } + player = createMediaPlayer(); MediaType mediaType = media.getMediaType(); if (mediaType == MediaType.AUDIO) { if (AppConfig.DEBUG) @@ -613,106 +639,169 @@ public class PlaybackService extends Service { } } - private MediaPlayer.OnPreparedListener preparedListener = new MediaPlayer.OnPreparedListener() { + private final com.aocate.media.MediaPlayer.OnPreparedListener audioPreparedListener = new com.aocate.media.MediaPlayer.OnPreparedListener() { @Override - public void onPrepared(MediaPlayer mp) { + public void onPrepared(com.aocate.media.MediaPlayer mp) { + genericOnPrepared(mp); + } + }; + + private final android.media.MediaPlayer.OnPreparedListener videoPreparedListener = new android.media.MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(android.media.MediaPlayer mp) { + genericOnPrepared(mp); + } + }; + + private final void genericOnPrepared(Object inObj) { + IPlayer mp = DuckType.coerce(inObj).to(IPlayer.class); + if (AppConfig.DEBUG) + Log.d(TAG, "Resource prepared"); + mp.seekTo(media.getPosition()); + if (media.getDuration() == 0) { if (AppConfig.DEBUG) - Log.d(TAG, "Resource prepared"); - mp.seekTo(media.getPosition()); - if (media.getDuration() == 0) { + Log.d(TAG, "Setting duration of media"); + media.setDuration(mp.getDuration()); + } + setStatus(PlayerStatus.PREPARED); + if (chapterLoader != null) { + chapterLoader.interrupt(); + } + chapterLoader = new Thread() { + @Override + public void run() { if (AppConfig.DEBUG) - Log.d(TAG, "Setting duration of media"); - media.setDuration(mp.getDuration()); - } - setStatus(PlayerStatus.PREPARED); - if (chapterLoader != null) { - chapterLoader.interrupt(); - } - chapterLoader = new Thread() { - @Override - public void run() { - if (AppConfig.DEBUG) - Log.d(TAG, "Chapter loader started"); - if (media != null && media.getChapters() == null) { - media.loadChapterMarks(); - if (!isInterrupted() && media.getChapters() != null) { - sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, - 0); - } + Log.d(TAG, "Chapter loader started"); + if (media != null && media.getChapters() == null) { + media.loadChapterMarks(); + if (!isInterrupted() && media.getChapters() != null) { + sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0); } - if (AppConfig.DEBUG) - Log.d(TAG, "Chapter loader stopped"); } - }; - chapterLoader.start(); - - if (startWhenPrepared) { - play(); + if (AppConfig.DEBUG) + Log.d(TAG, "Chapter loader stopped"); } + }; + chapterLoader.start(); + + if (startWhenPrepared) { + play(); + } + } + + private final com.aocate.media.MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener = new com.aocate.media.MediaPlayer.OnSeekCompleteListener() { + @Override + public void onSeekComplete(com.aocate.media.MediaPlayer mp) { + genericSeekCompleteListener(); + } + }; + + private final android.media.MediaPlayer.OnSeekCompleteListener videoSeekCompleteListener = new android.media.MediaPlayer.OnSeekCompleteListener() { + @Override + public void onSeekComplete(android.media.MediaPlayer mp) { + genericSeekCompleteListener(); } }; - private MediaPlayer.OnSeekCompleteListener onSeekCompleteListener = new MediaPlayer.OnSeekCompleteListener() { + private final void genericSeekCompleteListener() { + if (status == PlayerStatus.SEEKING) { + setStatus(statusBeforeSeek); + } + } + private final com.aocate.media.MediaPlayer.OnInfoListener audioInfoListener = new com.aocate.media.MediaPlayer.OnInfoListener() { @Override - public void onSeekComplete(MediaPlayer mp) { - if (status == PlayerStatus.SEEKING) { - setStatus(statusBeforeSeek); - } + public boolean onInfo(com.aocate.media.MediaPlayer mp, int what, + int extra) { + return genericInfoListener(what); + } + }; + private final android.media.MediaPlayer.OnInfoListener videoInfoListener = new android.media.MediaPlayer.OnInfoListener() { + @Override + public boolean onInfo(android.media.MediaPlayer mp, int what, int extra) { + return genericInfoListener(what); } }; - private MediaPlayer.OnInfoListener onInfoListener = new MediaPlayer.OnInfoListener() { + private boolean genericInfoListener(int what) { + switch (what) { + case MediaPlayer.MEDIA_INFO_BUFFERING_START: + sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_START, 0); + return true; + case MediaPlayer.MEDIA_INFO_BUFFERING_END: + sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_END, 0); + return true; + default: + return false; + } + } + private final com.aocate.media.MediaPlayer.OnErrorListener audioErrorListener = new com.aocate.media.MediaPlayer.OnErrorListener() { @Override - public boolean onInfo(MediaPlayer mp, int what, int extra) { - switch (what) { - case MediaPlayer.MEDIA_INFO_BUFFERING_START: - sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_START, 0); - return true; - case MediaPlayer.MEDIA_INFO_BUFFERING_END: - sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_END, 0); - return true; - default: - return false; - } + public boolean onError(com.aocate.media.MediaPlayer mp, int what, + int extra) { + return genericOnError(mp, what, extra); } }; - private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() { - private static final String TAG = "PlaybackService.onErrorListener"; - + private final android.media.MediaPlayer.OnErrorListener videoErrorListener = new android.media.MediaPlayer.OnErrorListener() { @Override - public boolean onError(MediaPlayer mp, int what, int extra) { - Log.w(TAG, "An error has occured: " + what); - if (mp.isPlaying()) { - pause(true, true); - } - sendNotificationBroadcast(NOTIFICATION_TYPE_ERROR, what); - setCurrentlyPlayingMedia(PlaybackPreferences.NO_MEDIA_PLAYING); - stopSelf(); - return true; + public boolean onError(android.media.MediaPlayer mp, int what, int extra) { + return genericOnError(mp, what, extra); } }; - private MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() { + private boolean genericOnError(Object inObj, int what, int extra) { + final String TAG = "PlaybackService.onErrorListener"; + Log.w(TAG, "An error has occured: " + what + " " + extra); + IPlayer mp = DuckType.coerce(inObj).to(IPlayer.class); + if (mp.isPlaying()) { + pause(true, true); + } + sendNotificationBroadcast(NOTIFICATION_TYPE_ERROR, what); + setCurrentlyPlayingMedia(PlaybackPreferences.NO_MEDIA_PLAYING); + stopSelf(); + return true; + } + private final com.aocate.media.MediaPlayer.OnCompletionListener audioCompletionListener = new com.aocate.media.MediaPlayer.OnCompletionListener() { @Override - public void onCompletion(MediaPlayer mp) { - endPlayback(true); + public void onCompletion(com.aocate.media.MediaPlayer mp) { + genericOnCompletion(); } }; - private MediaPlayer.OnBufferingUpdateListener onBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() { + private final android.media.MediaPlayer.OnCompletionListener videoCompletionListener = new android.media.MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(android.media.MediaPlayer mp) { + genericOnCompletion(); + } + }; + private void genericOnCompletion() { + endPlayback(true); + } + + private final com.aocate.media.MediaPlayer.OnBufferingUpdateListener audioBufferingUpdateListener = new com.aocate.media.MediaPlayer.OnBufferingUpdateListener() { @Override - public void onBufferingUpdate(MediaPlayer mp, int percent) { - sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_UPDATE, percent); + public void onBufferingUpdate(com.aocate.media.MediaPlayer mp, + int percent) { + genericOnBufferingUpdate(percent); + } + }; + private final android.media.MediaPlayer.OnBufferingUpdateListener videoBufferingUpdateListener = new android.media.MediaPlayer.OnBufferingUpdateListener() { + @Override + public void onBufferingUpdate(android.media.MediaPlayer mp, int percent) { + genericOnBufferingUpdate(percent); } }; + private void genericOnBufferingUpdate(int percent) { + sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_UPDATE, percent); + } + private void endPlayback(boolean playNextEpisode) { if (AppConfig.DEBUG) Log.d(TAG, "Playback ended"); @@ -821,7 +910,7 @@ public class PlaybackService extends Service { * file is being streamed */ public void pause(boolean abandonFocus, boolean reinit) { - if (player.isPlaying()) { + if (player != null && player.isPlaying()) { if (AppConfig.DEBUG) Log.d(TAG, "Pausing playback."); player.pause(); @@ -870,7 +959,6 @@ public class PlaybackService extends Service { /** Resets the media player and moves into INITIALIZED state. */ public void reinit() { player.reset(); - player = createMediaPlayer(player); prepareImmediately = false; initMediaplayer(); } @@ -892,7 +980,7 @@ public class PlaybackService extends Service { player.start(); if (status != PlayerStatus.PAUSED) { - player.seekTo((int) media.getPosition()); + player.seekTo(media.getPosition()); } setStatus(PlayerStatus.PLAYING); setupPositionSaver(); @@ -1249,7 +1337,7 @@ public class PlaybackService extends Service { * Pauses playback when the headset is disconnected and the preference is * set */ - private BroadcastReceiver headsetDisconnected = new BroadcastReceiver() { + private final BroadcastReceiver headsetDisconnected = new BroadcastReceiver() { private static final String TAG = "headsetDisconnected"; private static final int UNPLUGGED = 0; @@ -1272,7 +1360,7 @@ public class PlaybackService extends Service { } }; - private BroadcastReceiver audioBecomingNoisy = new BroadcastReceiver() { + private final BroadcastReceiver audioBecomingNoisy = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -1292,7 +1380,7 @@ public class PlaybackService extends Service { } } - private BroadcastReceiver shutdownReceiver = new BroadcastReceiver() { + private final BroadcastReceiver shutdownReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -1305,7 +1393,7 @@ public class PlaybackService extends Service { }; - private BroadcastReceiver skipCurrentEpisodeReceiver = new BroadcastReceiver() { + private final BroadcastReceiver skipCurrentEpisodeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(ACTION_SKIP_CURRENT_EPISODE)) { @@ -1421,7 +1509,7 @@ public class PlaybackService extends Service { return media; } - public MediaPlayer getPlayer() { + public IPlayer getPlayer() { return player; } @@ -1434,6 +1522,38 @@ public class PlaybackService extends Service { postStatusUpdateIntent(); } + public boolean canSetSpeed() { + if (media.getMediaType() == MediaType.AUDIO) { + return ((AudioPlayer) player).canSetSpeed(); + } + return false; + } + + public boolean canSetPitch() { + if (media.getMediaType() == MediaType.AUDIO) { + return ((AudioPlayer) player).canSetPitch(); + } + return false; + } + + public void setSpeed(double speed) { + if (media.getMediaType() == MediaType.AUDIO) { + AudioPlayer audioPlayer = (AudioPlayer) player; + if (audioPlayer.canSetSpeed()) { + audioPlayer.setPlaybackSpeed((float) speed); + } + } + } + + public void setPitch(double pitch) { + if (media.getMediaType() == MediaType.AUDIO) { + AudioPlayer audioPlayer = (AudioPlayer) player; + if (audioPlayer.canSetPitch()) { + audioPlayer.setPlaybackPitch((float) pitch); + } + } + } + /** * call getDuration() on mediaplayer or return INVALID_TIME if player is in * an invalid state. This method should be used instead of calling diff --git a/src/de/danoeh/antennapod/util/DuckType.java b/src/de/danoeh/antennapod/util/DuckType.java new file mode 100644 index 000000000..0dfc01508 --- /dev/null +++ b/src/de/danoeh/antennapod/util/DuckType.java @@ -0,0 +1,115 @@ +/* Adapted from: http://thinking-in-code.blogspot.com/2008/11/duck-typing-in-java-using-dynamic.html */ + +package de.danoeh.antennapod.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * Allows "duck typing" or dynamic invocation based on method signature rather + * than type hierarchy. In other words, rather than checking whether something + * IS-a duck, check whether it WALKS-like-a duck or QUACKS-like a duck. + * + * To use first use the coerce static method to indicate the object you want to + * do Duck Typing for, then specify an interface to the to method which you want + * to coerce the type to, e.g: + * + * public interface Foo { void aMethod(); } class Bar { ... public void + * aMethod() { ... } ... } Bar bar = ...; Foo foo = + * DuckType.coerce(bar).to(Foo.class); foo.aMethod(); + * + * + */ +public class DuckType { + + private final Object objectToCoerce; + + private DuckType(Object objectToCoerce) { + this.objectToCoerce = objectToCoerce; + } + + private class CoercedProxy implements InvocationHandler { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Method delegateMethod = findMethodBySignature(method); + assert delegateMethod != null; + return delegateMethod.invoke(DuckType.this.objectToCoerce, args); + } + } + + /** + * Specify the duck typed object to coerce. + * + * @param object + * the object to coerce + * @return + */ + public static DuckType coerce(Object object) { + return new DuckType(object); + } + + /** + * Coerce the Duck Typed object to the given interface providing it + * implements all the necessary methods. + * + * @param + * @param iface + * @return an instance of the given interface that wraps the duck typed + * class + * @throws ClassCastException + * if the object being coerced does not implement all the + * methods in the given interface. + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public <T> T to(Class iface) { + assert iface.isInterface() : "cannot coerce object to a class, must be an interface"; + if (isA(iface)) { + return (T) iface.cast(objectToCoerce); + } + if (quacksLikeA(iface)) { + return generateProxy(iface); + } + throw new ClassCastException("Could not coerce object of type " + objectToCoerce.getClass() + " to " + iface); + } + + @SuppressWarnings("rawtypes") + private boolean isA(Class iface) { + return objectToCoerce.getClass().isInstance(iface); + } + + /** + * Determine whether the duck typed object can be used with the given + * interface. + * + * @param Type + * of the interface to check. + * @param iface + * Interface class to check + * @return true if the object will support all the methods in the interface, + * false otherwise. + */ + @SuppressWarnings("rawtypes") + public boolean quacksLikeA(Class iface) { + for (Method method : iface.getMethods()) { + if (findMethodBySignature(method) == null) { + return false; + } + } + return true; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private <T> T generateProxy(Class iface) { + return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, new CoercedProxy()); + } + + private Method findMethodBySignature(Method method) { + try { + return objectToCoerce.getClass().getMethod(method.getName(), method.getParameterTypes()); + } catch (NoSuchMethodException e) { + return null; + } + } + +}
\ No newline at end of file diff --git a/src/de/danoeh/antennapod/util/playback/AudioPlayer.java b/src/de/danoeh/antennapod/util/playback/AudioPlayer.java new file mode 100644 index 000000000..68d31324d --- /dev/null +++ b/src/de/danoeh/antennapod/util/playback/AudioPlayer.java @@ -0,0 +1,30 @@ +package de.danoeh.antennapod.util.playback; + +import android.content.Context; +import android.util.Log; +import android.view.SurfaceHolder; + +import com.aocate.media.MediaPlayer; + +public class AudioPlayer extends MediaPlayer implements IPlayer { + private static final String TAG = "AudioPlayer"; + + public AudioPlayer(Context context) { + super(context); + } + + @Override + public void setScreenOnWhilePlaying(boolean screenOn) { + Log.e(TAG, "Setting screen on while playing not supported in Audio Player"); + throw new UnsupportedOperationException("Setting screen on while playing not supported in Audio Player"); + + } + + @Override + public void setDisplay(SurfaceHolder sh) { + if (sh != null) { + Log.e(TAG, "Setting display not supported in Audio Player"); + throw new UnsupportedOperationException("Setting display not supported in Audio Player"); + } + } +} diff --git a/src/de/danoeh/antennapod/util/playback/IPlayer.java b/src/de/danoeh/antennapod/util/playback/IPlayer.java new file mode 100644 index 000000000..ca9b36358 --- /dev/null +++ b/src/de/danoeh/antennapod/util/playback/IPlayer.java @@ -0,0 +1,64 @@ +package de.danoeh.antennapod.util.playback; + +import java.io.IOException; + +import android.view.SurfaceHolder; + +public interface IPlayer { + boolean canSetPitch(); + + boolean canSetSpeed(); + + float getCurrentPitchStepsAdjustment(); + + int getCurrentPosition(); + + float getCurrentSpeedMultiplier(); + + int getDuration(); + + float getMaxSpeedMultiplier(); + + float getMinSpeedMultiplier(); + + boolean isLooping(); + + boolean isPlaying(); + + void pause(); + + void prepare() throws IllegalStateException, IOException; + + void prepareAsync(); + + void release(); + + void reset(); + + void seekTo(int msec); + + void setAudioStreamType(int streamtype); + + void setScreenOnWhilePlaying(boolean screenOn); + + void setDataSource(String path) throws IllegalStateException, IOException, + IllegalArgumentException, SecurityException; + + void setDisplay(SurfaceHolder sh); + + void setEnableSpeedAdjustment(boolean enableSpeedAdjustment); + + void setLooping(boolean looping); + + void setPitchStepsAdjustment(float pitchSteps); + + void setPlaybackPitch(float f); + + void setPlaybackSpeed(float f); + + void setVolume(float left, float right); + + void start(); + + void stop(); +} diff --git a/src/de/danoeh/antennapod/util/playback/VideoPlayer.java b/src/de/danoeh/antennapod/util/playback/VideoPlayer.java new file mode 100644 index 000000000..f0a50542c --- /dev/null +++ b/src/de/danoeh/antennapod/util/playback/VideoPlayer.java @@ -0,0 +1,62 @@ +package de.danoeh.antennapod.util.playback; + +import android.media.MediaPlayer; +import android.util.Log; + +public class VideoPlayer extends MediaPlayer implements IPlayer { + private static final String TAG = "VideoPlayer"; + + @Override + public boolean canSetPitch() { + return false; + } + + @Override + public boolean canSetSpeed() { + return false; + } + + @Override + public float getCurrentPitchStepsAdjustment() { + return 1; + } + + @Override + public float getCurrentSpeedMultiplier() { + return 1; + } + + @Override + public float getMaxSpeedMultiplier() { + return 1; + } + + @Override + public float getMinSpeedMultiplier() { + return 1; + } + + @Override + public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) throws UnsupportedOperationException { + Log.e(TAG, "Setting enable speed adjustment unsupported in video player"); + throw new UnsupportedOperationException("Setting enable speed adjustment unsupported in video player"); + } + + @Override + public void setPitchStepsAdjustment(float pitchSteps) { + Log.e(TAG, "Setting pitch steps adjustment unsupported in video player"); + throw new UnsupportedOperationException("Setting pitch steps adjustment unsupported in video player"); + } + + @Override + public void setPlaybackPitch(float f) { + Log.e(TAG, "Setting playback pitch unsupported in video player"); + throw new UnsupportedOperationException("Setting playback pitch unsupported in video player"); + } + + @Override + public void setPlaybackSpeed(float f) { + Log.e(TAG, "Setting playback speed unsupported in video player"); + throw new UnsupportedOperationException("Setting playback speed unsupported in video player"); + } +} |