Added option to report player errors
* Added a new setting so that player errors are reported (under Video and Audio > Player) * Moved the player error logic to separate class specially created for this purpose
This commit is contained in:
parent
6cd25d7e55
commit
e632fab4d0
5 changed files with 116 additions and 43 deletions
|
@ -97,7 +97,6 @@ import android.widget.ProgressBar;
|
|||
import android.widget.RelativeLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -166,6 +165,7 @@ import org.schabi.newpipe.player.playback.MediaSourceManager;
|
|||
import org.schabi.newpipe.player.playback.PlaybackListener;
|
||||
import org.schabi.newpipe.player.playback.PlayerMediaSession;
|
||||
import org.schabi.newpipe.player.playback.SurfaceHolderCallback;
|
||||
import org.schabi.newpipe.player.playererror.PlayerErrorHandler;
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueueAdapter;
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
||||
|
@ -268,7 +268,7 @@ public final class Player implements
|
|||
@Nullable private MediaSourceTag currentMetadata;
|
||||
@Nullable private Bitmap currentThumbnail;
|
||||
|
||||
@Nullable private Toast errorToast;
|
||||
@NonNull private PlayerErrorHandler playerErrorHandler;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Player
|
||||
|
@ -413,6 +413,8 @@ public final class Player implements
|
|||
videoResolver = new VideoPlaybackResolver(context, dataSource, getQualityResolver());
|
||||
audioResolver = new AudioPlaybackResolver(context, dataSource);
|
||||
|
||||
playerErrorHandler = new PlayerErrorHandler(context);
|
||||
|
||||
windowManager = ContextCompat.getSystemService(context, WindowManager.class);
|
||||
}
|
||||
|
||||
|
@ -2512,30 +2514,33 @@ public final class Player implements
|
|||
*/
|
||||
@Override
|
||||
public void onPlayerError(@NonNull final ExoPlaybackException error) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "ExoPlayer - onPlayerError() called with: " + "error = [" + error + "]");
|
||||
}
|
||||
if (errorToast != null) {
|
||||
errorToast.cancel();
|
||||
errorToast = null;
|
||||
}
|
||||
Log.e(TAG, "ExoPlayer - onPlayerError() called with:", error);
|
||||
|
||||
saveStreamProgressState();
|
||||
|
||||
switch (error.type) {
|
||||
case ExoPlaybackException.TYPE_SOURCE:
|
||||
processSourceError(error.getSourceException());
|
||||
showStreamError(error);
|
||||
playerErrorHandler.showPlayerError(
|
||||
error,
|
||||
currentMetadata.getMetadata(),
|
||||
R.string.player_stream_failure);
|
||||
break;
|
||||
case ExoPlaybackException.TYPE_UNEXPECTED:
|
||||
showRecoverableError(error);
|
||||
playerErrorHandler.showPlayerError(
|
||||
error,
|
||||
currentMetadata.getMetadata(),
|
||||
R.string.player_recoverable_failure);
|
||||
setRecovery();
|
||||
reloadPlayQueueManager();
|
||||
break;
|
||||
case ExoPlaybackException.TYPE_REMOTE:
|
||||
case ExoPlaybackException.TYPE_RENDERER:
|
||||
default:
|
||||
showUnrecoverableError(error);
|
||||
playerErrorHandler.showPlayerError(
|
||||
error,
|
||||
currentMetadata.getMetadata(),
|
||||
R.string.player_unrecoverable_failure);
|
||||
onPlaybackShutdown();
|
||||
break;
|
||||
}
|
||||
|
@ -2557,37 +2562,6 @@ public final class Player implements
|
|||
playQueue.error();
|
||||
}
|
||||
}
|
||||
|
||||
private void showStreamError(final Exception exception) {
|
||||
exception.printStackTrace();
|
||||
|
||||
if (errorToast == null) {
|
||||
errorToast = Toast
|
||||
.makeText(context, R.string.player_stream_failure, Toast.LENGTH_SHORT);
|
||||
errorToast.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void showRecoverableError(final Exception exception) {
|
||||
exception.printStackTrace();
|
||||
|
||||
if (errorToast == null) {
|
||||
errorToast = Toast
|
||||
.makeText(context, R.string.player_recoverable_failure, Toast.LENGTH_SHORT);
|
||||
errorToast.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void showUnrecoverableError(final Exception exception) {
|
||||
exception.printStackTrace();
|
||||
|
||||
if (errorToast != null) {
|
||||
errorToast.cancel();
|
||||
}
|
||||
errorToast = Toast
|
||||
.makeText(context, R.string.player_unrecoverable_failure, Toast.LENGTH_SHORT);
|
||||
errorToast.show();
|
||||
}
|
||||
//endregion
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package org.schabi.newpipe.player.playererror;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.error.ErrorActivity;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.extractor.Info;
|
||||
|
||||
/**
|
||||
* Handles (exoplayer)errors that occur in the player.
|
||||
*/
|
||||
public class PlayerErrorHandler {
|
||||
// This has to be <= 23 chars on devices running Android 7 or lower (API <= 25)
|
||||
// or it fails with an IllegalArgumentException
|
||||
// https://stackoverflow.com/a/54744028
|
||||
private static final String TAG = "PlayerErrorHandler";
|
||||
|
||||
@Nullable
|
||||
private Toast errorToast;
|
||||
|
||||
@NonNull
|
||||
private final Context context;
|
||||
|
||||
public PlayerErrorHandler(@NonNull final Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void showPlayerError(
|
||||
@NonNull final ExoPlaybackException exception,
|
||||
@NonNull final Info info,
|
||||
@StringRes final int textResId) {
|
||||
// Hide existing toast message
|
||||
if (errorToast != null) {
|
||||
Log.d(TAG, "Trying to cancel previous player error error toast");
|
||||
errorToast.cancel();
|
||||
errorToast = null;
|
||||
}
|
||||
|
||||
if (shouldReportError()) {
|
||||
try {
|
||||
reportError(exception, info);
|
||||
// When a report pops up we need no toast
|
||||
return;
|
||||
} catch (final Exception ex) {
|
||||
Log.w(TAG, "Unable to report error:", ex);
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(TAG, "Showing player error toast");
|
||||
errorToast = Toast.makeText(context, textResId, Toast.LENGTH_SHORT);
|
||||
errorToast.show();
|
||||
}
|
||||
|
||||
private void reportError(@NonNull final ExoPlaybackException exception,
|
||||
@NonNull final Info info) {
|
||||
ErrorActivity.reportError(
|
||||
context,
|
||||
new ErrorInfo(
|
||||
exception,
|
||||
UserAction.PLAY_STREAM,
|
||||
"Player error[type=" + exception.type + "] occurred while playing: "
|
||||
+ info.getUrl(),
|
||||
info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private boolean shouldReportError() {
|
||||
return PreferenceManager
|
||||
.getDefaultSharedPreferences(context)
|
||||
.getBoolean(
|
||||
context.getString(R.string.report_player_errors_key),
|
||||
false);
|
||||
}
|
||||
}
|
|
@ -89,6 +89,8 @@
|
|||
<item>@string/never</item>
|
||||
</string-array>
|
||||
|
||||
<string name="report_player_errors_key" translatable="false">report_player_errors_key</string>
|
||||
|
||||
<string name="seekbar_preview_thumbnail_key" translatable="false">seekbar_preview_thumbnail_key</string>
|
||||
<string name="seekbar_preview_thumbnail_high_quality" translatable="false">seekbar_preview_thumbnail_high_quality</string>
|
||||
<string name="seekbar_preview_thumbnail_low_quality" translatable="false">seekbar_preview_thumbnail_low_quality</string>
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
<string name="kore_package" translatable="false">org.xbmc.kore</string>
|
||||
<string name="show_play_with_kodi_title">Show \"Play with Kodi\" option</string>
|
||||
<string name="show_play_with_kodi_summary">Display an option to play a video via Kodi media center</string>
|
||||
<string name="report_player_errors_title">Report player errors</string>
|
||||
<string name="report_player_errors_summary">Reports player errors in full detail instead of showing a short-lived toast message (useful for diagnosing problems)</string>
|
||||
<string name="notification_scale_to_square_image_title">Scale thumbnail to 1:1 aspect ratio</string>
|
||||
<string name="notification_scale_to_square_image_summary">Scale the video thumbnail shown in the notification from 16:9 to 1:1 aspect ratio (may introduce distortions)</string>
|
||||
<string name="notification_action_0_title">First action button</string>
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
android:title="@string/show_play_with_kodi_title"
|
||||
app:singleLineTitle="false"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<ListPreference
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -101,6 +102,14 @@
|
|||
app:singleLineTitle="false"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="@string/report_player_errors_key"
|
||||
android:summary="@string/report_player_errors_summary"
|
||||
android:title="@string/report_player_errors_title"
|
||||
app:singleLineTitle="false"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
|
Loading…
Reference in a new issue