Skip to content

Commit e632fab

Browse files
committed
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
1 parent 6cd25d7 commit e632fab

5 files changed

Lines changed: 116 additions & 43 deletions

File tree

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
import android.widget.RelativeLayout;
9898
import android.widget.SeekBar;
9999
import android.widget.TextView;
100-
import android.widget.Toast;
101100

102101
import androidx.annotation.NonNull;
103102
import androidx.annotation.Nullable;
@@ -166,6 +165,7 @@
166165
import org.schabi.newpipe.player.playback.PlaybackListener;
167166
import org.schabi.newpipe.player.playback.PlayerMediaSession;
168167
import org.schabi.newpipe.player.playback.SurfaceHolderCallback;
168+
import org.schabi.newpipe.player.playererror.PlayerErrorHandler;
169169
import org.schabi.newpipe.player.playqueue.PlayQueue;
170170
import org.schabi.newpipe.player.playqueue.PlayQueueAdapter;
171171
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
@@ -268,7 +268,7 @@ public final class Player implements
268268
@Nullable private MediaSourceTag currentMetadata;
269269
@Nullable private Bitmap currentThumbnail;
270270

271-
@Nullable private Toast errorToast;
271+
@NonNull private PlayerErrorHandler playerErrorHandler;
272272

273273
/*//////////////////////////////////////////////////////////////////////////
274274
// Player
@@ -413,6 +413,8 @@ public Player(@NonNull final MainPlayer service) {
413413
videoResolver = new VideoPlaybackResolver(context, dataSource, getQualityResolver());
414414
audioResolver = new AudioPlaybackResolver(context, dataSource);
415415

416+
playerErrorHandler = new PlayerErrorHandler(context);
417+
416418
windowManager = ContextCompat.getSystemService(context, WindowManager.class);
417419
}
418420

@@ -2512,30 +2514,33 @@ public void onCues(final List<Cue> cues) {
25122514
*/
25132515
@Override
25142516
public void onPlayerError(@NonNull final ExoPlaybackException error) {
2515-
if (DEBUG) {
2516-
Log.d(TAG, "ExoPlayer - onPlayerError() called with: " + "error = [" + error + "]");
2517-
}
2518-
if (errorToast != null) {
2519-
errorToast.cancel();
2520-
errorToast = null;
2521-
}
2517+
Log.e(TAG, "ExoPlayer - onPlayerError() called with:", error);
25222518

25232519
saveStreamProgressState();
25242520

25252521
switch (error.type) {
25262522
case ExoPlaybackException.TYPE_SOURCE:
25272523
processSourceError(error.getSourceException());
2528-
showStreamError(error);
2524+
playerErrorHandler.showPlayerError(
2525+
error,
2526+
currentMetadata.getMetadata(),
2527+
R.string.player_stream_failure);
25292528
break;
25302529
case ExoPlaybackException.TYPE_UNEXPECTED:
2531-
showRecoverableError(error);
2530+
playerErrorHandler.showPlayerError(
2531+
error,
2532+
currentMetadata.getMetadata(),
2533+
R.string.player_recoverable_failure);
25322534
setRecovery();
25332535
reloadPlayQueueManager();
25342536
break;
25352537
case ExoPlaybackException.TYPE_REMOTE:
25362538
case ExoPlaybackException.TYPE_RENDERER:
25372539
default:
2538-
showUnrecoverableError(error);
2540+
playerErrorHandler.showPlayerError(
2541+
error,
2542+
currentMetadata.getMetadata(),
2543+
R.string.player_unrecoverable_failure);
25392544
onPlaybackShutdown();
25402545
break;
25412546
}
@@ -2557,37 +2562,6 @@ private void processSourceError(final IOException error) {
25572562
playQueue.error();
25582563
}
25592564
}
2560-
2561-
private void showStreamError(final Exception exception) {
2562-
exception.printStackTrace();
2563-
2564-
if (errorToast == null) {
2565-
errorToast = Toast
2566-
.makeText(context, R.string.player_stream_failure, Toast.LENGTH_SHORT);
2567-
errorToast.show();
2568-
}
2569-
}
2570-
2571-
private void showRecoverableError(final Exception exception) {
2572-
exception.printStackTrace();
2573-
2574-
if (errorToast == null) {
2575-
errorToast = Toast
2576-
.makeText(context, R.string.player_recoverable_failure, Toast.LENGTH_SHORT);
2577-
errorToast.show();
2578-
}
2579-
}
2580-
2581-
private void showUnrecoverableError(final Exception exception) {
2582-
exception.printStackTrace();
2583-
2584-
if (errorToast != null) {
2585-
errorToast.cancel();
2586-
}
2587-
errorToast = Toast
2588-
.makeText(context, R.string.player_unrecoverable_failure, Toast.LENGTH_SHORT);
2589-
errorToast.show();
2590-
}
25912565
//endregion
25922566

25932567

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package org.schabi.newpipe.player.playererror;
2+
3+
import android.content.Context;
4+
import android.util.Log;
5+
import android.widget.Toast;
6+
7+
import androidx.annotation.NonNull;
8+
import androidx.annotation.Nullable;
9+
import androidx.annotation.StringRes;
10+
import androidx.preference.PreferenceManager;
11+
12+
import com.google.android.exoplayer2.ExoPlaybackException;
13+
14+
import org.schabi.newpipe.R;
15+
import org.schabi.newpipe.error.ErrorActivity;
16+
import org.schabi.newpipe.error.ErrorInfo;
17+
import org.schabi.newpipe.error.UserAction;
18+
import org.schabi.newpipe.extractor.Info;
19+
20+
/**
21+
* Handles (exoplayer)errors that occur in the player.
22+
*/
23+
public class PlayerErrorHandler {
24+
// This has to be <= 23 chars on devices running Android 7 or lower (API <= 25)
25+
// or it fails with an IllegalArgumentException
26+
// https://stackoverflow.com/a/54744028
27+
private static final String TAG = "PlayerErrorHandler";
28+
29+
@Nullable
30+
private Toast errorToast;
31+
32+
@NonNull
33+
private final Context context;
34+
35+
public PlayerErrorHandler(@NonNull final Context context) {
36+
this.context = context;
37+
}
38+
39+
public void showPlayerError(
40+
@NonNull final ExoPlaybackException exception,
41+
@NonNull final Info info,
42+
@StringRes final int textResId) {
43+
// Hide existing toast message
44+
if (errorToast != null) {
45+
Log.d(TAG, "Trying to cancel previous player error error toast");
46+
errorToast.cancel();
47+
errorToast = null;
48+
}
49+
50+
if (shouldReportError()) {
51+
try {
52+
reportError(exception, info);
53+
// When a report pops up we need no toast
54+
return;
55+
} catch (final Exception ex) {
56+
Log.w(TAG, "Unable to report error:", ex);
57+
}
58+
}
59+
60+
Log.d(TAG, "Showing player error toast");
61+
errorToast = Toast.makeText(context, textResId, Toast.LENGTH_SHORT);
62+
errorToast.show();
63+
}
64+
65+
private void reportError(@NonNull final ExoPlaybackException exception,
66+
@NonNull final Info info) {
67+
ErrorActivity.reportError(
68+
context,
69+
new ErrorInfo(
70+
exception,
71+
UserAction.PLAY_STREAM,
72+
"Player error[type=" + exception.type + "] occurred while playing: "
73+
+ info.getUrl(),
74+
info
75+
)
76+
);
77+
}
78+
79+
private boolean shouldReportError() {
80+
return PreferenceManager
81+
.getDefaultSharedPreferences(context)
82+
.getBoolean(
83+
context.getString(R.string.report_player_errors_key),
84+
false);
85+
}
86+
}

app/src/main/res/values/settings_keys.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989
<item>@string/never</item>
9090
</string-array>
9191

92+
<string name="report_player_errors_key" translatable="false">report_player_errors_key</string>
93+
9294
<string name="seekbar_preview_thumbnail_key" translatable="false">seekbar_preview_thumbnail_key</string>
9395
<string name="seekbar_preview_thumbnail_high_quality" translatable="false">seekbar_preview_thumbnail_high_quality</string>
9496
<string name="seekbar_preview_thumbnail_low_quality" translatable="false">seekbar_preview_thumbnail_low_quality</string>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
<string name="kore_package" translatable="false">org.xbmc.kore</string>
5353
<string name="show_play_with_kodi_title">Show \"Play with Kodi\" option</string>
5454
<string name="show_play_with_kodi_summary">Display an option to play a video via Kodi media center</string>
55+
<string name="report_player_errors_title">Report player errors</string>
56+
<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>
5557
<string name="notification_scale_to_square_image_title">Scale thumbnail to 1:1 aspect ratio</string>
5658
<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>
5759
<string name="notification_action_0_title">First action button</string>

app/src/main/res/xml/video_audio_settings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
android:title="@string/show_play_with_kodi_title"
9090
app:singleLineTitle="false"
9191
app:iconSpaceReserved="false" />
92+
9293
<ListPreference
9394
android:layout_width="wrap_content"
9495
android:layout_height="wrap_content"
@@ -101,6 +102,14 @@
101102
app:singleLineTitle="false"
102103
app:iconSpaceReserved="false" />
103104

105+
<SwitchPreferenceCompat
106+
android:defaultValue="false"
107+
android:key="@string/report_player_errors_key"
108+
android:summary="@string/report_player_errors_summary"
109+
android:title="@string/report_player_errors_title"
110+
app:singleLineTitle="false"
111+
app:iconSpaceReserved="false" />
112+
104113
</PreferenceCategory>
105114

106115
<PreferenceCategory

0 commit comments

Comments
 (0)