Skip to content

Commit 4c893c9

Browse files
author
Aunali321
committed
feat(instagram): Add Max quality patch
1 parent 6286c0d commit 4c893c9

3 files changed

Lines changed: 125 additions & 0 deletions

File tree

patches/api/patches.api

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public final class li/auna/patches/instagram/misc/extension/ExtensionPatchKt {
3030
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
3131
}
3232

33+
public final class li/auna/patches/instagram/misc/quality/MaxMediaQualityPatchKt {
34+
public static final fun getMaxMediaQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
35+
}
36+
3337
public final class li/auna/patches/kustom/UnlockProPatchKt {
3438
public static final fun getHideSubtitleToastPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
3539
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package li.auna.patches.instagram.misc.quality
2+
3+
import app.revanced.patcher.fingerprint
4+
5+
internal val displayMetricsFingerprint = fingerprint {
6+
returns("Ljava/lang/String;")
7+
strings("%sdpi; %sx%s")
8+
}
9+
10+
internal val mediaSizeFingerprint = fingerprint {
11+
strings("_8.jpg", "_6.jpg")
12+
}
13+
14+
internal val storyMediaBitrateFingerprint = fingerprint {
15+
returns("Landroid/media/MediaFormat;")
16+
strings("color-format", "bitrate", "frame-rate", "i-frame-interval", "profile", "level")
17+
}
18+
19+
internal val videoEncoderConfigFingerprint = fingerprint {
20+
returns("Ljava/lang/String;")
21+
strings("VideoEncoderConfig{width=")
22+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package li.auna.patches.instagram.misc.quality
2+
3+
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
4+
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
5+
import app.revanced.patcher.extensions.InstructionExtensions.instructions
6+
import app.revanced.patcher.patch.bytecodePatch
7+
import com.android.tools.smali.dexlib2.Opcode
8+
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
9+
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
10+
11+
@Suppress("unused")
12+
val maxMediaQualityPatch = bytecodePatch(
13+
name = "Max Media Quality",
14+
description = "Enable max media quality.",
15+
) {
16+
compatibleWith(
17+
"com.instagram.android"
18+
)
19+
20+
execute {
21+
val maxPostSize = "2048" // Maximum post size.
22+
val maxBitRate = "10000000" // Maximum bit rate possible (found in code).
23+
24+
// Improve quality of images.
25+
// Instagram tend to reduce/compress the image resolution to user's device height and width.
26+
// This section of code removes that restriction and sets the resolution to 2048x2048 (max possible).
27+
displayMetricsFingerprint.let { it ->
28+
it.method.apply {
29+
val displayMetInstructions = instructions.filter { it.opcode == Opcode.IGET }
30+
31+
// There are 3 iget instances.
32+
// 1.dpi 2.width 3.height.
33+
// We don't need to change dpi, we just need to change height and width.
34+
displayMetInstructions.drop(1).forEach { instruction ->
35+
val index = instruction.location.index
36+
val register = getInstruction<TwoRegisterInstruction>(index).registerA
37+
38+
// Set height and width to 2048.
39+
addInstruction(index + 1, "const v$register, $maxPostSize")
40+
}
41+
}
42+
}
43+
44+
// Yet another method where the image resolution is compressed.
45+
mediaSizeFingerprint.let { it ->
46+
it.classDef.apply {
47+
val mediaSetMethod =
48+
methods.first { it.returnType == "Lcom/instagram/model/mediasize/ExtendedImageUrl;" }
49+
50+
val mediaSetInstructions =
51+
mediaSetMethod.instructions.filter { it.opcode == Opcode.INVOKE_VIRTUAL }
52+
53+
mediaSetInstructions.forEach { instruction ->
54+
val index = instruction.location.index + 1
55+
val register = mediaSetMethod.getInstruction<OneRegisterInstruction>(index).registerA
56+
57+
// Set height and width to 2048.
58+
mediaSetMethod.addInstruction(index + 1, "const v$register, $maxPostSize")
59+
}
60+
}
61+
}
62+
63+
// Improve quality of stories.
64+
// This section of code sets the bitrate of the stories to the maximum possible.
65+
storyMediaBitrateFingerprint.let { it ->
66+
it.method.apply {
67+
val ifLezIndex = instructions.first { it.opcode == Opcode.IF_LEZ }.location.index
68+
69+
val bitRateRegister = getInstruction<OneRegisterInstruction>(ifLezIndex).registerA
70+
71+
// Set the bitrate to maximum possible.
72+
addInstruction(ifLezIndex + 1, "const v$bitRateRegister, $maxBitRate")
73+
}
74+
}
75+
76+
// Improve quality of reels.
77+
// In general Instagram tend to set the minimum bitrate between maximum possible and compressed video's bitrate.
78+
// This section of code sets the bitrate of the reels to the maximum possible.
79+
videoEncoderConfigFingerprint.let { it ->
80+
it.classDef.apply {
81+
// Get the constructor.
82+
val videoEncoderConfigConstructor = methods.first()
83+
84+
val lastMoveResIndex = videoEncoderConfigConstructor.instructions
85+
.last { it.opcode == Opcode.MOVE_RESULT }.location.index
86+
87+
// Finding the register were the bitrate is stored.
88+
val bitRateRegister =
89+
videoEncoderConfigConstructor.getInstruction<OneRegisterInstruction>(lastMoveResIndex).registerA
90+
91+
// Set bitrate to maximum possible.
92+
videoEncoderConfigConstructor.addInstruction(
93+
lastMoveResIndex + 1,
94+
"const v$bitRateRegister, $maxBitRate",
95+
)
96+
}
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)