Merge branch 'dev' into screenshot-order

This commit is contained in:
Christian Schabesberger 2018-11-13 16:58:18 +01:00 committed by GitHub
commit 1048caa496
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 112 additions and 72 deletions

View file

@ -98,35 +98,54 @@ public abstract class BasePlayer implements
Player.EventListener, PlaybackListener, ImageLoadingListener { Player.EventListener, PlaybackListener, ImageLoadingListener {
public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release"); public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
@NonNull public static final String TAG = "BasePlayer"; @NonNull
public static final String TAG = "BasePlayer";
@NonNull final protected Context context; @NonNull
final protected Context context;
@NonNull final protected BroadcastReceiver broadcastReceiver; @NonNull
@NonNull final protected IntentFilter intentFilter; final protected BroadcastReceiver broadcastReceiver;
@NonNull
final protected IntentFilter intentFilter;
@NonNull final protected HistoryRecordManager recordManager; @NonNull
final protected HistoryRecordManager recordManager;
@NonNull final protected CustomTrackSelector trackSelector; @NonNull
@NonNull final protected PlayerDataSource dataSource; final protected CustomTrackSelector trackSelector;
@NonNull
final protected PlayerDataSource dataSource;
@NonNull final private LoadControl loadControl; @NonNull
@NonNull final private RenderersFactory renderFactory; final private LoadControl loadControl;
@NonNull
final private RenderersFactory renderFactory;
@NonNull final private SerialDisposable progressUpdateReactor; @NonNull
@NonNull final private CompositeDisposable databaseUpdateReactor; final private SerialDisposable progressUpdateReactor;
@NonNull
final private CompositeDisposable databaseUpdateReactor;
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Intent // Intent
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@NonNull public static final String REPEAT_MODE = "repeat_mode"; @NonNull
@NonNull public static final String PLAYBACK_PITCH = "playback_pitch"; public static final String REPEAT_MODE = "repeat_mode";
@NonNull public static final String PLAYBACK_SPEED = "playback_speed"; @NonNull
@NonNull public static final String PLAYBACK_SKIP_SILENCE = "playback_skip_silence"; public static final String PLAYBACK_PITCH = "playback_pitch";
@NonNull public static final String PLAYBACK_QUALITY = "playback_quality"; @NonNull
@NonNull public static final String PLAY_QUEUE_KEY = "play_queue_key"; public static final String PLAYBACK_SPEED = "playback_speed";
@NonNull public static final String APPEND_ONLY = "append_only"; @NonNull
@NonNull public static final String SELECT_ON_APPEND = "select_on_append"; public static final String PLAYBACK_SKIP_SILENCE = "playback_skip_silence";
@NonNull
public static final String PLAYBACK_QUALITY = "playback_quality";
@NonNull
public static final String PLAY_QUEUE_KEY = "play_queue_key";
@NonNull
public static final String APPEND_ONLY = "append_only";
@NonNull
public static final String SELECT_ON_APPEND = "select_on_append";
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Playback // Playback
@ -137,13 +156,18 @@ public abstract class BasePlayer implements
protected PlayQueue playQueue; protected PlayQueue playQueue;
protected PlayQueueAdapter playQueueAdapter; protected PlayQueueAdapter playQueueAdapter;
@Nullable protected MediaSourceManager playbackManager; @Nullable
protected MediaSourceManager playbackManager;
@Nullable private PlayQueueItem currentItem; @Nullable
@Nullable private MediaSourceTag currentMetadata; private PlayQueueItem currentItem;
@Nullable private Bitmap currentThumbnail; @Nullable
private MediaSourceTag currentMetadata;
@Nullable
private Bitmap currentThumbnail;
@Nullable protected Toast errorToast; @Nullable
protected Toast errorToast;
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Player // Player
@ -213,7 +237,8 @@ public abstract class BasePlayer implements
registerBroadcastReceiver(); registerBroadcastReceiver();
} }
public void initListeners() {} public void initListeners() {
}
public void handleIntent(Intent intent) { public void handleIntent(Intent intent) {
if (DEBUG) Log.d(TAG, "handleIntent() called with: intent = [" + intent + "]"); if (DEBUG) Log.d(TAG, "handleIntent() called with: intent = [" + intent + "]");
@ -297,7 +322,6 @@ public abstract class BasePlayer implements
databaseUpdateReactor.clear(); databaseUpdateReactor.clear();
progressUpdateReactor.set(null); progressUpdateReactor.set(null);
simpleExoPlayer = null;
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -425,13 +449,15 @@ public abstract class BasePlayer implements
if (!isProgressLoopRunning()) startProgressLoop(); if (!isProgressLoopRunning()) startProgressLoop();
} }
public void onBuffering() {} public void onBuffering() {
}
public void onPaused() { public void onPaused() {
if (isProgressLoopRunning()) stopProgressLoop(); if (isProgressLoopRunning()) stopProgressLoop();
} }
public void onPausedSeek() {} public void onPausedSeek() {
}
public void onCompleted() { public void onCompleted() {
if (DEBUG) Log.d(TAG, "onCompleted() called"); if (DEBUG) Log.d(TAG, "onCompleted() called");
@ -602,19 +628,19 @@ public abstract class BasePlayer implements
/** /**
* Processes the exceptions produced by {@link com.google.android.exoplayer2.ExoPlayer ExoPlayer}. * Processes the exceptions produced by {@link com.google.android.exoplayer2.ExoPlayer ExoPlayer}.
* There are multiple types of errors: <br><br> * There are multiple types of errors: <br><br>
* * <p>
* {@link ExoPlaybackException#TYPE_SOURCE TYPE_SOURCE}: <br><br> * {@link ExoPlaybackException#TYPE_SOURCE TYPE_SOURCE}: <br><br>
* * <p>
* {@link ExoPlaybackException#TYPE_UNEXPECTED TYPE_UNEXPECTED}: <br><br> * {@link ExoPlaybackException#TYPE_UNEXPECTED TYPE_UNEXPECTED}: <br><br>
* If a runtime error occurred, then we can try to recover it by restarting the playback * If a runtime error occurred, then we can try to recover it by restarting the playback
* after setting the timestamp recovery. <br><br> * after setting the timestamp recovery. <br><br>
* * <p>
* {@link ExoPlaybackException#TYPE_RENDERER TYPE_RENDERER}: <br><br> * {@link ExoPlaybackException#TYPE_RENDERER TYPE_RENDERER}: <br><br>
* If the renderer failed, treat the error as unrecoverable. * If the renderer failed, treat the error as unrecoverable.
* *
* @see #processSourceError(IOException) * @see #processSourceError(IOException)
* @see Player.EventListener#onPlayerError(ExoPlaybackException) * @see Player.EventListener#onPlayerError(ExoPlaybackException)
* */ */
@Override @Override
public void onPlayerError(ExoPlaybackException error) { public void onPlayerError(ExoPlaybackException error) {
if (DEBUG) Log.d(TAG, "ExoPlayer - onPlayerError() called with: " + if (DEBUG) Log.d(TAG, "ExoPlayer - onPlayerError() called with: " +
@ -900,8 +926,8 @@ public abstract class BasePlayer implements
if (DEBUG) Log.d(TAG, "onPlayPrevious() called"); if (DEBUG) Log.d(TAG, "onPlayPrevious() called");
/* If current playback has run for PLAY_PREV_ACTIVATION_LIMIT_MILLIS milliseconds, /* If current playback has run for PLAY_PREV_ACTIVATION_LIMIT_MILLIS milliseconds,
* restart current track. Also restart the track if the current track * restart current track. Also restart the track if the current track
* is the first in a queue.*/ * is the first in a queue.*/
if (simpleExoPlayer.getCurrentPosition() > PLAY_PREV_ACTIVATION_LIMIT_MILLIS || if (simpleExoPlayer.getCurrentPosition() > PLAY_PREV_ACTIVATION_LIMIT_MILLIS ||
playQueue.getIndex() == 0) { playQueue.getIndex() == 0) {
seekToDefault(); seekToDefault();
@ -1010,8 +1036,8 @@ public abstract class BasePlayer implements
try { try {
metadata = (MediaSourceTag) simpleExoPlayer.getCurrentTag(); metadata = (MediaSourceTag) simpleExoPlayer.getCurrentTag();
} catch (IndexOutOfBoundsException | ClassCastException error) { } catch (IndexOutOfBoundsException | ClassCastException error) {
if(DEBUG) Log.d(TAG, "Could not update metadata: " + error.getMessage()); if (DEBUG) Log.d(TAG, "Could not update metadata: " + error.getMessage());
if(DEBUG) error.printStackTrace(); if (DEBUG) error.printStackTrace();
return; return;
} }
@ -1075,7 +1101,9 @@ public abstract class BasePlayer implements
currentThumbnail; currentThumbnail;
} }
/** Checks if the current playback is a livestream AND is playing at or beyond the live edge */ /**
* Checks if the current playback is a livestream AND is playing at or beyond the live edge
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted") @SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean isLiveEdge() { public boolean isLiveEdge() {
if (simpleExoPlayer == null || !isLive()) return false; if (simpleExoPlayer == null || !isLive()) return false;
@ -1099,8 +1127,8 @@ public abstract class BasePlayer implements
} catch (@NonNull IndexOutOfBoundsException ignored) { } catch (@NonNull IndexOutOfBoundsException ignored) {
// Why would this even happen =( // Why would this even happen =(
// But lets log it anyway. Save is save // But lets log it anyway. Save is save
if(DEBUG) Log.d(TAG, "Could not update metadata: " + ignored.getMessage()); if (DEBUG) Log.d(TAG, "Could not update metadata: " + ignored.getMessage());
if(DEBUG) ignored.printStackTrace(); if (DEBUG) ignored.printStackTrace();
return false; return false;
} }
} }

View file

@ -110,7 +110,8 @@ public final class ListHelper {
: context.getString(R.string.best_resolution_key); : context.getString(R.string.best_resolution_key);
String maxResolution = getResolutionLimit(context); String maxResolution = getResolutionLimit(context);
if (maxResolution != null && compareVideoStreamResolution(maxResolution, resolution) < 1){ if (maxResolution != null && (resolution.equals(context.getString(R.string.best_resolution_key))
|| compareVideoStreamResolution(maxResolution, resolution) < 1)) {
resolution = maxResolution; resolution = maxResolution;
} }
return resolution; return resolution;

View file

@ -96,12 +96,12 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
} }
}); });
/*h.itemView.setOnClickListener(new View.OnClickListener() { h.itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
showDetail(h); if(h.mission.finished) viewFile(h);
} }
});*/ });
return h; return h;
} }
@ -200,14 +200,12 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
Menu menu = popup.getMenu(); Menu menu = popup.getMenu();
MenuItem start = menu.findItem(R.id.start); MenuItem start = menu.findItem(R.id.start);
MenuItem pause = menu.findItem(R.id.pause); MenuItem pause = menu.findItem(R.id.pause);
MenuItem view = menu.findItem(R.id.view);
MenuItem delete = menu.findItem(R.id.delete); MenuItem delete = menu.findItem(R.id.delete);
MenuItem checksum = menu.findItem(R.id.checksum); MenuItem checksum = menu.findItem(R.id.checksum);
// Set to false first // Set to false first
start.setVisible(false); start.setVisible(false);
pause.setVisible(false); pause.setVisible(false);
view.setVisible(false);
delete.setVisible(false); delete.setVisible(false);
checksum.setVisible(false); checksum.setVisible(false);
@ -222,7 +220,6 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
pause.setVisible(true); pause.setVisible(true);
} }
} else { } else {
view.setVisible(true);
delete.setVisible(true); delete.setVisible(true);
checksum.setVisible(true); checksum.setVisible(true);
} }
@ -241,27 +238,6 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
mBinder.onMissionRemoved(mItemList.get(h.position)); mBinder.onMissionRemoved(mItemList.get(h.position));
h.lastTimeStamp = -1; h.lastTimeStamp = -1;
h.lastDone = -1; h.lastDone = -1;
return true;
case R.id.view:
File f = new File(h.mission.location, h.mission.name);
String ext = Utility.getFileExt(h.mission.name);
Log.d(TAG, "Viewing file: " + f.getAbsolutePath() + " ext: " + ext);
if (ext == null) {
Log.w(TAG, "Can't view file because it has no extension: " +
h.mission.name);
return false;
}
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.substring(1));
Log.v(TAG, "Mime: " + mime + " package: " + mContext.getApplicationContext().getPackageName() + ".provider");
if (f.exists()) {
viewFileWithFileProvider(f, mime);
} else {
Log.w(TAG, "File doesn't exist");
}
return true; return true;
case R.id.delete: case R.id.delete:
mDeleteDownloadManager.add(h.mission); mDeleteDownloadManager.add(h.mission);
@ -282,6 +258,28 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
popup.show(); popup.show();
} }
private boolean viewFile(ViewHolder h) {
File f = new File(h.mission.location, h.mission.name);
String ext = Utility.getFileExt(h.mission.name);
Log.d(TAG, "Viewing file: " + f.getAbsolutePath() + " ext: " + ext);
if (ext == null) {
Log.w(TAG, "Can't view file because it has no extension: " +
h.mission.name);
return true;
}
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.substring(1));
Log.v(TAG, "Mime: " + mime + " package: " + mContext.getApplicationContext().getPackageName() + ".provider");
if (f.exists()) {
viewFileWithFileProvider(f, mime);
} else {
Log.w(TAG, "File doesn't exist");
}
return false;
}
private void viewFileWithFileProvider(File file, String mimetype) { private void viewFileWithFileProvider(File file, String mimetype) {
String ourPackage = mContext.getApplicationContext().getPackageName(); String ourPackage = mContext.getApplicationContext().getPackageName();
Uri uri = FileProvider.getUriForFile(mContext, ourPackage + ".provider", file); Uri uri = FileProvider.getUriForFile(mContext, ourPackage + ".provider", file);

View file

@ -7,11 +7,7 @@
<item <item
android:id="@+id/pause" android:id="@+id/pause"
android:title="@string/pause"/> android:title="@string/pause"/>
<item
android:id="@+id/view"
android:title="@string/view"/>
<item <item
android:id="@+id/delete" android:id="@+id/delete"
android:title="@string/delete"/> android:title="@string/delete"/>

View file

@ -508,4 +508,21 @@
<string name="grid">Сетка</string> <string name="grid">Сетка</string>
<string name="auto">Автоматически</string> <string name="auto">Автоматически</string>
<string name="brightness_gesture_control_summary">Менять яркость плеера жестом</string>
<string name="brightness_gesture_control_title">Жест яркости</string>
<string name="download_to_sdcard_error_message">Загрузка на внешний накопитель невозможна. Сбросить расположение папки загрузки?</string>
<string name="download_to_sdcard_error_title">Внешний накопитель недоступен</string>
<string name="main_page_content_summary">Вкладки, видимые на главной странице</string>
<string name="restore_defaults">По умолчанию</string>
<string name="restore_defaults_confirmation">Хотите восстановить умолчания?</string>
<string name="saved_tabs_invalid_json">Ошибка чтения сохранённых вкладок. Используются вкладки по умолчанию</string>
<string name="selection">Выбор</string>
<string name="subscribers_count_not_available">Количество подписчиков недоступно</string>
<string name="switch_view">Переключить вид</string>
<string name="tab_choose">Выберите вкладку</string>
<string name="tab_new">Новая вкладка</string>
<string name="unsubscribe">Отписаться</string>
<string name="volume_gesture_control_summary">Менять громкость плеера жестом</string>
<string name="volume_gesture_control_title">Жест громкости</string>
</resources> </resources>