Skip to content

Commit bfdcd5e

Browse files
committed
Fix bug in media quality and improve code
Signed-off-by: Dev4Mod <[email protected]>
1 parent e23ed89 commit bfdcd5e

File tree

3 files changed

+101
-143
lines changed

3 files changed

+101
-143
lines changed

app/src/main/java/com/wmods/wppenhacer/xposed/core/devkit/Unobfuscator.java

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -452,28 +452,6 @@ private static Class<?> loadMediaQualityClass(ClassLoader classLoader) throws Ex
452452
});
453453
}
454454

455-
public synchronized static Method loadMediaQualityResolutionMethod(ClassLoader classLoader) throws Exception {
456-
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> {
457-
var clazz = loadMediaQualityClass(classLoader);
458-
return Arrays.stream(clazz.getDeclaredMethods()).filter(
459-
m -> m.getParameterTypes().length == 3 &&
460-
m.getParameterTypes()[0].equals(int.class) &&
461-
m.getParameterTypes()[1].equals(int.class) &&
462-
m.getParameterTypes()[2].equals(int.class)
463-
).findFirst().orElse(null);
464-
});
465-
}
466-
467-
public synchronized static Method loadMediaQualityBitrateMethod(ClassLoader classLoader) throws Exception {
468-
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> {
469-
var clazz = loadMediaQualityClass(classLoader);
470-
return Arrays.stream(clazz.getDeclaredMethods()).filter(
471-
m -> m.getParameterTypes().length == 1 &&
472-
m.getParameterTypes()[0].equals(int.class) &&
473-
m.getReturnType().equals(int.class)
474-
).findFirst().orElse(null);
475-
});
476-
}
477455

478456
public synchronized static Method loadMediaQualityVideoMethod2(ClassLoader classLoader) throws Exception {
479457
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> {
@@ -513,14 +491,6 @@ public synchronized static HashMap<String, Field> loadMediaQualityOriginalVideoF
513491
return result;
514492
}
515493

516-
public synchronized static Class loadMediaQualityVideoLimitClass(ClassLoader classLoader) throws Exception {
517-
return UnobfuscatorCache.getInstance().getClass(classLoader, () -> {
518-
var clazz = findFirstClassUsingStrings(classLoader, StringMatchType.Contains, "videoLimitMb=");
519-
if (clazz == null) throw new Exception("MediaQualityVideoLimit method not found");
520-
return clazz;
521-
});
522-
}
523-
524494
// TODO: Classes and methods to ShareLimit
525495

526496

@@ -1369,13 +1339,6 @@ public synchronized static Class loadImageVewContainerClass(ClassLoader loader)
13691339
});
13701340
}
13711341

1372-
public synchronized static Class loadMediaQualityProcessor(ClassLoader loader) throws Exception {
1373-
return UnobfuscatorCache.getInstance().getClass(loader, () -> {
1374-
var clazz = findFirstClassUsingStrings(loader, StringMatchType.Contains, "{maxKb=");
1375-
if (clazz == null) throw new RuntimeException("MediaQualityProcessor class not found");
1376-
return clazz;
1377-
});
1378-
}
13791342

13801343
public synchronized static Method getFilterInitMethod(ClassLoader loader) throws Exception {
13811344
return UnobfuscatorCache.getInstance().getMethod(loader, () -> {

app/src/main/java/com/wmods/wppenhacer/xposed/features/media/MediaQuality.java

Lines changed: 88 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@
33
import android.graphics.Bitmap;
44
import android.graphics.RecordingCanvas;
55
import android.os.Build;
6-
import android.util.Pair;
76

87
import androidx.annotation.NonNull;
98

109
import com.wmods.wppenhacer.xposed.core.Feature;
1110
import com.wmods.wppenhacer.xposed.core.devkit.Unobfuscator;
1211
import com.wmods.wppenhacer.xposed.features.general.Others;
1312
import com.wmods.wppenhacer.xposed.utils.ReflectionUtils;
13+
import com.wmods.wppenhacer.xposed.utils.Utils;
1414

1515
import org.json.JSONObject;
1616

17+
import java.util.concurrent.atomic.AtomicReference;
18+
1719
import de.robv.android.xposed.XC_MethodHook;
1820
import de.robv.android.xposed.XC_MethodReplacement;
1921
import de.robv.android.xposed.XSharedPreferences;
@@ -30,136 +32,135 @@ public void doHook() throws Exception {
3032
var videoQuality = prefs.getBoolean("videoquality", false);
3133
var imageQuality = prefs.getBoolean("imagequality", false);
3234
var maxSize = (int) prefs.getFloat("video_limit_size", 60);
35+
var realResolution = prefs.getBoolean("video_real_resolution", false);
36+
37+
// Max video size
38+
Others.propsInteger.put(3185, maxSize);
39+
Others.propsInteger.put(3656, maxSize);
40+
Others.propsInteger.put(4155, maxSize);
41+
Others.propsInteger.put(3659, maxSize);
42+
Others.propsInteger.put(4685, maxSize);
43+
Others.propsInteger.put(596, maxSize);
3344

3445
Others.propsBoolean.put(7950, false); // Força o uso do MediaComposer para processar os videos
3546

3647
if (videoQuality) {
3748

38-
Others.propsBoolean.put(5549, true); // Remove o limite de qualidade do video
49+
Others.propsBoolean.put(5549, true); // Use bitrate from json to force video high quality
3950

4051
var jsonProperty = Unobfuscator.loadPropsJsonMethod(classLoader);
41-
XposedBridge.hookMethod(jsonProperty, new XC_MethodHook() {
52+
53+
AtomicReference<XC_MethodHook.Unhook> jsonPropertyHook = new AtomicReference<>();
54+
var unhooked = XposedBridge.hookMethod(jsonProperty, new XC_MethodHook() {
4255
@Override
4356
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
4457
var index = ReflectionUtils.findIndexOfType(param.args, Integer.class);
4558
if (index == -1) {
46-
logDebug("PropsJson: index int not found");
59+
Utils.showToast("PropsJson: index int not found", 0);
60+
jsonPropertyHook.get().unhook();
4761
return;
4862
}
49-
if ((int) param.args[index] == 5550) {
50-
var json = (JSONObject) param.getResult();
51-
for (int i = 0; i < json.length(); i++) {
52-
var key = (String) json.names().opt(i);
53-
var jSONObject = json.getJSONObject(key);
54-
jSONObject.put("max_bitrate", 96000);
55-
jSONObject.put("max_bandwidth", maxSize);
56-
}
63+
// Desativar os perfis de video (mobile network)
64+
if ((int) param.args[index] == 5550 || (int) param.args[index] == 9705) {
65+
param.setResult(new JSONObject());
5766
}
5867
}
5968
});
60-
61-
var resolutionMethod = Unobfuscator.loadMediaQualityResolutionMethod(classLoader);
62-
logDebug(Unobfuscator.getMethodDescriptor(resolutionMethod));
63-
64-
XposedBridge.hookMethod(resolutionMethod, new XC_MethodHook() {
65-
@Override
66-
protected void afterHookedMethod(MethodHookParam param) {
67-
var pair = new Pair<>(param.args[0], param.args[1]);
68-
param.setResult(pair);
69-
}
70-
});
71-
72-
var bitrateMethod = Unobfuscator.loadMediaQualityBitrateMethod(classLoader);
73-
logDebug(Unobfuscator.getMethodDescriptor(bitrateMethod));
74-
75-
XposedBridge.hookMethod(bitrateMethod, new XC_MethodHook() {
76-
@Override
77-
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
78-
param.setResult(96 * 1000 * 1000);
79-
}
80-
});
69+
jsonPropertyHook.set(unhooked);
8170

8271
var videoMethod = Unobfuscator.loadMediaQualityVideoMethod2(classLoader);
8372
logDebug(Unobfuscator.getMethodDescriptor(videoMethod));
8473

85-
// var mediaFields = Unobfuscator.loadMediaQualityOriginalVideoFields(classLoader);
74+
var mediaFields = Unobfuscator.loadMediaQualityOriginalVideoFields(classLoader);
8675
var mediaTranscodeParams = Unobfuscator.loadMediaQualityVideoFields(classLoader);
8776

8877
XposedBridge.hookMethod(videoMethod, new XC_MethodHook() {
8978

9079
@Override
9180
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
81+
var resizeVideo = param.getResult();
9282
if ((int) param.args[1] == 3) {
93-
var resizeVideo = param.getResult();
94-
// var width = mediaFields.get("widthPx").getInt(param.args[0]);
95-
// var height = mediaFields.get("heightPx").getInt(param.args[0]);
96-
//
97-
// var targetWidthField = mediaTranscodeParams.get("targetWidth");
98-
// var targetHeightField = mediaTranscodeParams.get("targetHeight");
99-
// var targetWidth = targetWidthField.getInt(resizeVideo);
100-
// var targetHeight = targetHeightField.getInt(resizeVideo);
101-
//
102-
// var inverted = targetWidth > targetHeight != width > height;
103-
//
104-
// targetHeightField.setInt(resizeVideo, inverted ? width : height);
105-
// targetWidthField.setInt(resizeVideo, inverted ? height : width);
106-
107-
if (prefs.getBoolean("video_maxfps", false)) {
108-
var frameRateField = mediaTranscodeParams.get("frameRate");
109-
frameRateField.setInt(resizeVideo, 60);
83+
84+
if (realResolution) {
85+
var width = mediaFields.get("widthPx").getInt(param.args[0]);
86+
var height = mediaFields.get("heightPx").getInt(param.args[0]);
87+
var rotationAngle = mediaFields.get("rotationAngle").getInt(param.args[0]);
88+
89+
var targetWidthField = mediaTranscodeParams.get("targetWidth");
90+
var targetHeightField = mediaTranscodeParams.get("targetHeight");
91+
92+
var inverted = rotationAngle == 90 || rotationAngle == 270;
93+
94+
targetHeightField.setInt(resizeVideo, inverted ? width : height);
95+
targetWidthField.setInt(resizeVideo, inverted ? height : width);
96+
11097
}
98+
99+
}
100+
if (prefs.getBoolean("video_maxfps", false)) {
101+
var frameRateField = mediaTranscodeParams.get("frameRate");
102+
frameRateField.setInt(resizeVideo, 60);
111103
}
112104
}
113105
});
114106

115-
var videoLimitClass = Unobfuscator.loadMediaQualityVideoLimitClass(classLoader);
116-
logDebug(videoLimitClass);
107+
// HD video must be sent in maximum resolution (up to 4K)
108+
if (realResolution) {
109+
Others.propsInteger.put(594, 8000); // chat
110+
Others.propsInteger.put(12852, 8000); // chat
111+
Others.propsInteger.put(3183, 8000); // Stories
112+
Others.propsInteger.put(4685, 8000); // Stories
113+
} else {
114+
Others.propsInteger.put(594, 1920); // chat
115+
Others.propsInteger.put(12852, 1920); // chat
116+
Others.propsInteger.put(3183, 1920); // Stories
117+
Others.propsInteger.put(4685, 1920); // Stories
118+
}
117119

118-
XposedHelpers.findAndHookConstructor(videoLimitClass, int.class, int.class, int.class, new XC_MethodHook() {
119-
@Override
120-
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
121-
super.beforeHookedMethod(param);
122-
param.args[0] = maxSize;
123-
param.args[1] = 8000; // 4K Resolution
124-
param.args[2] = 96 * 1000 * 1000; // 96 Mbps
125-
}
126-
});
120+
// Non-HD video must be sent in HD resolution
121+
Others.propsInteger.put(4686, 1280);
122+
Others.propsInteger.put(3654, 1280);
127123

128-
Others.propsInteger.put(8606, maxSize);
124+
// Max bitrate
125+
Others.propsInteger.put(3755, 96000);
126+
Others.propsInteger.put(3756, 96000);
127+
Others.propsInteger.put(3757, 96000);
128+
Others.propsInteger.put(3758, 96000);
129129

130130
}
131131

132132
if (imageQuality) {
133-
int[] props = {1573, 1575, 1578, 1574, 1576, 1577, 2654, 2656, 6030, 6032};
134-
int max = 10000;
135-
int min = 1000;
136-
for (int index = 0; index < props.length; index++) {
137-
if (index <= 2) {
138-
Others.propsInteger.put(props[index], min);
139-
} else {
140-
Others.propsInteger.put(props[index], max);
141-
}
142-
}
143-
Others.propsInteger.put(2655, 100); // Image quality compression
144-
Others.propsInteger.put(6029, 100); // Image quality compression
145-
Others.propsInteger.put(3657, 100); // Image quality compression
146133

147-
var mediaQualityProcessor = Unobfuscator.loadMediaQualityProcessor(classLoader);
148-
XposedBridge.hookAllConstructors(mediaQualityProcessor, new XC_MethodHook() {
149-
@Override
150-
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
151-
if (param.args.length < 4) return;
152-
param.args[0] = 10000; // maxKb
153-
param.args[1] = 100; // quality
154-
param.args[2] = 10000; // maxEdge
155-
param.args[3] = 10000; // nothing
156-
}
157-
});
134+
// Image Max Size
135+
int maxImageSize = 50 * 1024; // 50MB
136+
Others.propsInteger.put(1577, maxImageSize);
137+
Others.propsInteger.put(6030, maxImageSize);
138+
Others.propsInteger.put(2656, maxImageSize);
139+
140+
// Image Quality
141+
int imageMaxQuality = 100;
142+
Others.propsInteger.put(1581, imageMaxQuality);
143+
Others.propsInteger.put(1575, imageMaxQuality);
144+
Others.propsInteger.put(1578, imageMaxQuality);
145+
Others.propsInteger.put(6029, imageMaxQuality);
146+
Others.propsInteger.put(2655, imageMaxQuality);
147+
148+
// HD image must be sent in maximum 4K resolution
149+
Others.propsBoolean.put(6033, true);
150+
Others.propsInteger.put(2654, 6000); // Only HD images
151+
Others.propsInteger.put(6032, 6000); // Only HD images
152+
153+
// Non-HD image must be sent in HD resolution
154+
Others.propsInteger.put(1580, 4160);
155+
Others.propsInteger.put(1574, 4160);
156+
Others.propsInteger.put(1576, 4160);
157+
Others.propsInteger.put(12902, 4160);
158158

159159
// Prevent crashes in Media preview
160160
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
161161
XposedHelpers.findAndHookMethod(RecordingCanvas.class, "throwIfCannotDraw", Bitmap.class, XC_MethodReplacement.DO_NOTHING);
162162
}
163+
163164
}
164165
}
165166

app/src/main/res/xml/fragment_media.xml

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,24 @@
3939
app:iconSpaceReserved="false"
4040
app:title="@string/title_video">
4141

42-
<rikka.material.preference.MaterialSwitchPreference
43-
app:key="videoquality"
44-
app:summary="@string/videoquality_sum"
45-
app:title="@string/videoquality" />
46-
47-
<!-- <rikka.material.preference.MaterialSwitchPreference-->
48-
<!-- app:dependency="videoquality"-->
49-
<!-- app:key="video_size_limit"-->
50-
<!-- app:summary="@string/increase_video_size_limit_sum"-->
51-
<!-- app:title="@string/increase_video_size_limit" />-->
52-
5342
<com.wmods.wppenhacer.preference.FloatSeekBarPreference
5443
android:defaultValue="60"
5544
app:key="video_limit_size"
5645
app:maxValue="120"
5746
app:minValue="30"
58-
app:valueSpacing="10"
59-
app:title="@string/increase_video_size_limit" />
60-
61-
<!-- <rikka.material.preference.MaterialSwitchPreference-->
62-
<!-- app:dependency="videoquality"-->
63-
<!-- app:key="video_real_resolution"-->
64-
<!-- app:summary="@string/send_video_in_real_resolution_sum"-->
65-
<!-- app:title="@string/send_video_in_real_resolution" />-->
47+
app:title="@string/increase_video_size_limit"
48+
app:valueSpacing="10" />
49+
50+
<rikka.material.preference.MaterialSwitchPreference
51+
app:key="videoquality"
52+
app:summary="@string/videoquality_sum"
53+
app:title="@string/videoquality" />
54+
55+
<rikka.material.preference.MaterialSwitchPreference
56+
app:dependency="videoquality"
57+
app:key="video_real_resolution"
58+
app:summary="@string/send_video_in_real_resolution_sum"
59+
app:title="@string/send_video_in_real_resolution" />
6660

6761
<rikka.material.preference.MaterialSwitchPreference
6862
app:dependency="videoquality"

0 commit comments

Comments
 (0)