From ac329e140435c3488ea5dfef89d237e2325da9e4 Mon Sep 17 00:00:00 2001 From: Javier Date: Wed, 12 Feb 2020 00:08:06 +0100 Subject: initial import --- .../java/com/javispedro/wallmotion/Renderer.java | 183 +++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 app/src/main/java/com/javispedro/wallmotion/Renderer.java (limited to 'app/src/main/java/com/javispedro/wallmotion/Renderer.java') diff --git a/app/src/main/java/com/javispedro/wallmotion/Renderer.java b/app/src/main/java/com/javispedro/wallmotion/Renderer.java new file mode 100644 index 0000000..6730afe --- /dev/null +++ b/app/src/main/java/com/javispedro/wallmotion/Renderer.java @@ -0,0 +1,183 @@ +package com.javispedro.wallmotion; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.SharedPreferences; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Build; +import android.text.TextUtils; +import android.util.Log; +import android.view.Surface; + +import androidx.preference.PreferenceManager; + +import java.io.IOException; + +public class Renderer extends ContextWrapper { + private static final String TAG = "Renderer"; + + private SharedPreferences prefs; + private MediaPlayer player; + + private int savedPosition; + + public Renderer(Context context) { + super(context); + + prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.registerOnSharedPreferenceChangeListener(new PrefsListener()); + } + + public boolean isActive() { + return player != null; + } + + public void start(Surface surface) { + preparePlayer(surface); + } + + public void stop() { + if (player != null && player.isPlaying() && shouldSaveRestorePosition()) { + savedPosition = player.getCurrentPosition(); + Log.d(TAG, "storing current position: " + savedPosition + " ms"); + } + releasePlayer(); + } + + public void reset() { + releasePlayer(); + savedPosition = 0; + } + + private class PrefsListener implements SharedPreferences.OnSharedPreferenceChangeListener { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(getString(R.string.settings_video_file_key))) { + Log.d(TAG, "video file key changed"); + reset(); + } else if (key.equals(getString(R.string.settings_display_restart_key))) { + savedPosition = 0; + } + } + } + + private class PlayerListener implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener { + @Override + public boolean onError(MediaPlayer mp, int what, int extra) { + Log.e(TAG, "MediaPlayer error: " + what + " extra:" + extra); + return false; + } + + @Override + public void onPrepared(MediaPlayer mp) { + Log.d(TAG, "onPrepared"); + if (player != null && !player.isPlaying()) { + Log.d(TAG, "start playing"); + if (savedPosition > 0 && shouldSaveRestorePosition()) { + restorePlayerPosition(); + } + player.start(); + } + } + + @Override + public void onSeekComplete(MediaPlayer mp) { + Log.d(TAG, "onSeekComplete: " + mp.getCurrentPosition() + " ms"); + } + } + + private void preparePlayer(Surface surface) { + releasePlayer(); + + int scaling = getVideoScaling(); + Log.d(TAG, "video scaling mode: " + scaling); + + Uri uri = getVideoFileUri(); + if (uri == null) { + Log.d(TAG, "no video URI: using missing video URI"); + uri = getResourceVideoFileUri(R.raw.video_file_missing); + scaling = MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT; + } + + try { + preparePlayer(surface, uri, scaling); + } catch (Exception ex) { + Log.e(TAG, "Could not open video URI: " + uri.toString() + " : " + ex.toString()); + ex.printStackTrace(); + releasePlayer(); + + uri = getResourceVideoFileUri(R.raw.video_file_error); + scaling = MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT; + + try { + preparePlayer(surface, uri, scaling); + } catch (Exception ex2) { + Log.e(TAG, "Could not open error video URI either: " + ex2.toString()); + ex2.printStackTrace(); + releasePlayer(); + } + } + } + + private void preparePlayer(Surface surface, Uri uri, int scaling) throws IOException { + Log.d(TAG, "creating player"); + player = new MediaPlayer(); + PlayerListener listener = new PlayerListener(); + player.setOnErrorListener(listener); + player.setOnPreparedListener(listener); + player.setOnSeekCompleteListener(listener); + player.setLooping(true); + player.setVolume(0, 0); + player.setSurface(surface); + Log.d(TAG, "setting data source to " + uri.toString()); + player.setDataSource(this, uri); + player.setVideoScalingMode(scaling); + player.prepareAsync(); + } + + private void releasePlayer() { + if (player != null) { + Log.d(TAG, "releasing player"); + player.release(); + player = null; + } + } + + private void restorePlayerPosition() { + Log.d(TAG, "seeking to " + savedPosition + " ms"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + player.seekTo(savedPosition, MediaPlayer.SEEK_CLOSEST); + } else { + player.seekTo(savedPosition); + } + } + + private Uri getVideoFileUri() { + String new_value = prefs.getString(getString(R.string.settings_video_file_key), null); + if (new_value != null) { + return Uri.parse(new_value); + } else { + return null; + } + } + + private Uri getResourceVideoFileUri(int resId) { + Uri.Builder builder = new Uri.Builder(); + builder.scheme("android.resource").authority(getPackageName()).appendPath(Integer.toString(resId)); + return builder.build(); + } + + private int getVideoScaling() { + String value = prefs.getString(getString(R.string.settings_display_scale_key), null); + if (TextUtils.equals(value, getString(R.string.settings_display_scale_to_fit_with_cropping_key))) { + return MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING; + } else { + return MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT; + } + } + + private boolean shouldSaveRestorePosition() { + return !prefs.getBoolean(getString(R.string.settings_display_restart_key), false); + } +} -- cgit v1.2.3