summaryrefslogtreecommitdiff
path: root/app/src/main/java/com/javispedro/wallmotion/Renderer.java
blob: efcd7c5d93f0a728cc58b5ac9d5a318c8ee860ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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 SharedPreferences.OnSharedPreferenceChangeListener prefsListener;
    private MediaPlayer player;

    private int savedPosition;

    public Renderer(Context context) {
        super(context);

        prefs = PreferenceManager.getDefaultSharedPreferences(context);
        prefsListener = new PrefsListener(); // must keep a reference according to SharedPreferences docs
        prefs.registerOnSharedPreferenceChangeListener(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(); // to ensure we reset the savedPosition
            }
        }
    }

    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);
    }
}