Skip to content

Commit 4c46cb2

Browse files
fix(YouTube - Spoof video streams): Fix error toast that is sometimes shown (ReVanced#4090)
1 parent be72064 commit 4c46cb2

File tree

4 files changed

+106
-12
lines changed

4 files changed

+106
-12
lines changed

extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import java.nio.ByteBuffer;
88
import java.util.Map;
9-
import java.util.Objects;
109

1110
import app.revanced.extension.shared.Logger;
1211
import app.revanced.extension.shared.Utils;
@@ -87,14 +86,22 @@ public static void fetchStreams(String url, Map<String, String> requestHeaders)
8786
try {
8887
Uri uri = Uri.parse(url);
8988
String path = uri.getPath();
89+
9090
// 'heartbeat' has no video id and appears to be only after playback has started.
91-
if (path != null && path.contains("player") && !path.contains("heartbeat")) {
92-
String videoId = Objects.requireNonNull(uri.getQueryParameter("id"));
93-
StreamingDataRequest.fetchRequest(videoId, requestHeaders);
91+
// 'refresh' has no video id and appears to happen when waiting for a livestream to start.
92+
if (path != null && path.contains("player") && !path.contains("heartbeat")
93+
&& !path.contains("refresh")) {
94+
String id = uri.getQueryParameter("id");
95+
if (id == null) {
96+
Logger.printException(() -> "Ignoring request that has no video id." +
97+
" Url: " + url + " headers: " + requestHeaders);
98+
return;
99+
}
100+
101+
StreamingDataRequest.fetchRequest(id, requestHeaders);
94102
}
95103
} catch (Exception ex) {
96-
Logger.printException(() -> "buildRequest failure. Url: " + url
97-
+ " headers: " + requestHeaders, ex);
104+
Logger.printException(() -> "buildRequest failure", ex);
98105
}
99106
}
100107
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package app.revanced.extension.youtube.settings.preference;
2+
3+
import static app.revanced.extension.shared.StringRef.str;
4+
5+
import android.content.Context;
6+
import android.content.SharedPreferences;
7+
import android.preference.Preference;
8+
import android.preference.PreferenceManager;
9+
import android.util.AttributeSet;
10+
11+
import androidx.annotation.Nullable;
12+
13+
import app.revanced.extension.shared.Logger;
14+
import app.revanced.extension.shared.Utils;
15+
import app.revanced.extension.shared.settings.BaseSettings;
16+
import app.revanced.extension.shared.settings.Setting;
17+
import app.revanced.extension.shared.spoof.ClientType;
18+
19+
@SuppressWarnings({"deprecation", "unused"})
20+
public class SpoofStreamingDataSideEffectsPreference extends Preference {
21+
22+
@Nullable
23+
private ClientType currentClientType;
24+
25+
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
26+
// Because this listener may run before the ReVanced settings fragment updates Settings,
27+
// this could show the prior config and not the current.
28+
//
29+
// Push this call to the end of the main run queue,
30+
// so all other listeners are done and Settings is up to date.
31+
Utils.runOnMainThread(this::updateUI);
32+
};
33+
34+
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
35+
super(context, attrs, defStyleAttr, defStyleRes);
36+
}
37+
38+
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
39+
super(context, attrs, defStyleAttr);
40+
}
41+
42+
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs) {
43+
super(context, attrs);
44+
}
45+
46+
public SpoofStreamingDataSideEffectsPreference(Context context) {
47+
super(context);
48+
}
49+
50+
private void addChangeListener() {
51+
Setting.preferences.preferences.registerOnSharedPreferenceChangeListener(listener);
52+
}
53+
54+
private void removeChangeListener() {
55+
Setting.preferences.preferences.unregisterOnSharedPreferenceChangeListener(listener);
56+
}
57+
58+
@Override
59+
protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
60+
super.onAttachedToHierarchy(preferenceManager);
61+
updateUI();
62+
addChangeListener();
63+
}
64+
65+
@Override
66+
protected void onPrepareForRemoval() {
67+
super.onPrepareForRemoval();
68+
removeChangeListener();
69+
}
70+
71+
private void updateUI() {
72+
ClientType clientType = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
73+
if (currentClientType == clientType) {
74+
return;
75+
}
76+
77+
Logger.printDebug(() -> "Updating spoof stream side effects preference");
78+
setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get());
79+
80+
String key = "revanced_spoof_video_streams_about_"
81+
+ clientType.name().toLowerCase();
82+
setTitle(str(key + "_title"));
83+
setSummary(str(key + "_summary"));
84+
}
85+
}

patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
4545
summaryKey = null
4646
),
4747
SwitchPreference("revanced_spoof_video_streams_ios_force_avc"),
48-
NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
49-
NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
48+
// Preference requires a title but the actual text is chosen at runtime.
49+
NonInteractivePreference(
50+
key = "revanced_spoof_video_streams_about_android_vr",
51+
tag = "app.revanced.extension.youtube.settings.preference.SpoofStreamingDataSideEffectsPreference"
52+
),
5053
),
5154
),
5255
)

patches/src/main/resources/addresources/values/strings.xml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,11 +1229,10 @@ This is because Crowdin requires temporarily flattening this file and removing t
12291229
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video codec is determined automatically</string>
12301230
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Enabling this might improve battery life and fix playback stuttering.\n\nAVC has a maximum resolution of 1080p, Opus audio codec is not available, and video playback will use more internet data than VP9 or AV1.</string>
12311231
<string name="revanced_spoof_video_streams_about_ios_title">iOS spoofing side effects</string>
1232-
<string name="revanced_spoof_video_streams_about_ios_summary">• Private kids videos may not play\n• Livestreams start from the beginning\n• Videos may end 1 second early</string>
1232+
<string name="revanced_spoof_video_streams_about_ios_summary">• Private kids videos may not play\n• Age restricted videos may not play\n• Livestreams start from the beginning\n• Videos end 1 second early</string>
12331233
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing side effects</string>
1234-
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Kids videos may not play\n• Audio track menu is missing\n• Stable volume is not available</string>
1235-
<string name="revanced_spoof_video_streams_language_">Video streams are spoofed</string>
1236-
<string name="revanced_spoof_video_streams_language_title">Preferred audio stream language</string>
1234+
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Kids videos may not play\n• Age restricted videos may not play\n• Livestreams start from the beginning\n• Videos end 1 second early</string>
1235+
<string name="revanced_spoof_video_streams_language_title">Default audio stream language</string>
12371236
<string name="revanced_spoof_video_streams_language_DEFAULT">App language</string>
12381237
<string name="revanced_spoof_video_streams_language_AR">Arabic</string>
12391238
<string name="revanced_spoof_video_streams_language_AZ">Azerbaijani</string>

0 commit comments

Comments
 (0)