mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 05:07:41 +02:00
fix(YouTube - Spoof streaming data): Videos end 1 second early on iOS client
This commit is contained in:
@ -34,6 +34,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"$SPOOF_PATH/SpoofStreamingDataPatch;"
|
||||
|
||||
// In YouTube 17.34.36, this class is obfuscated.
|
||||
const val STREAMING_DATA_INTERFACE =
|
||||
"Lcom/google/protos/youtube/api/innertube/StreamingDataOuterClass${'$'}StreamingData;"
|
||||
|
||||
fun baseSpoofStreamingDataPatch(
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
executeBlock: BytecodePatchContext.() -> Unit = {},
|
||||
@ -130,7 +134,8 @@ fun baseSpoofStreamingDataPatch(
|
||||
if-eqz v2, :disabled
|
||||
|
||||
# Get streaming data.
|
||||
invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->getStreamingData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
|
||||
iget-object v6, p0, $setStreamingDataField
|
||||
invoke-static { v2, v6 }, $EXTENSION_CLASS_DESCRIPTOR->getStreamingData(Ljava/lang/String;$STREAMING_DATA_INTERFACE)Ljava/nio/ByteBuffer;
|
||||
move-result-object v3
|
||||
if-eqz v3, :disabled
|
||||
|
||||
@ -154,6 +159,39 @@ fun baseSpoofStreamingDataPatch(
|
||||
}
|
||||
}
|
||||
|
||||
videoStreamingDataConstructorFingerprint.methodOrThrow(videoStreamingDataToStringFingerprint).apply {
|
||||
val formatStreamModelInitIndex = indexOfFormatStreamModelInitInstruction(this)
|
||||
val getVideoIdIndex = indexOfFirstInstructionReversedOrThrow(formatStreamModelInitIndex) {
|
||||
val reference = getReference<FieldReference>()
|
||||
opcode == Opcode.IGET_OBJECT &&
|
||||
reference?.type == "Ljava/lang/String;" &&
|
||||
reference.definingClass == definingClass
|
||||
}
|
||||
val getVideoIdReference = getInstruction<ReferenceInstruction>(getVideoIdIndex).reference
|
||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(getVideoIdIndex) {
|
||||
opcode == Opcode.IGET_OBJECT &&
|
||||
getReference<FieldReference>()?.definingClass == STREAMING_DATA_INTERFACE
|
||||
}
|
||||
|
||||
val (freeRegister, streamingDataRegister) = with(getInstruction<TwoRegisterInstruction>(insertIndex)) {
|
||||
Pair(registerA, registerB)
|
||||
}
|
||||
val definingClassRegister = getInstruction<TwoRegisterInstruction>(getVideoIdIndex).registerB
|
||||
val insertReference = getInstruction<ReferenceInstruction>(insertIndex).reference
|
||||
|
||||
replaceInstruction(
|
||||
insertIndex,
|
||||
"iget-object v$freeRegister, v$freeRegister, $insertReference"
|
||||
)
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
iget-object v$freeRegister, v$definingClassRegister, $getVideoIdReference
|
||||
invoke-static { v$freeRegister, v$streamingDataRegister }, $EXTENSION_CLASS_DESCRIPTOR->getOriginalStreamingData(Ljava/lang/String;$STREAMING_DATA_INTERFACE)$STREAMING_DATA_INTERFACE
|
||||
move-result-object v$freeRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Remove /videoplayback request body to fix playback.
|
||||
|
@ -103,6 +103,34 @@ internal val protobufClassParseByteBufferFingerprint = legacyFingerprint(
|
||||
customFingerprint = { method, _ -> method.name == "parseFrom" },
|
||||
)
|
||||
|
||||
internal val videoStreamingDataConstructorFingerprint = legacyFingerprint(
|
||||
name = "videoStreamingDataConstructorFingerprint",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
returnType = "V",
|
||||
customFingerprint = { method, _ ->
|
||||
indexOfFormatStreamModelInitInstruction(method) >= 0
|
||||
},
|
||||
)
|
||||
|
||||
internal fun indexOfFormatStreamModelInitInstruction(method: Method) =
|
||||
method.indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
opcode == Opcode.INVOKE_DIRECT &&
|
||||
reference?.name == "<init>" &&
|
||||
reference.parameterTypes.size > 1
|
||||
}
|
||||
|
||||
internal val videoStreamingDataToStringFingerprint = legacyFingerprint(
|
||||
name = "videoStreamingDataToStringFingerprint",
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
strings = listOf("VideoStreamingData(itags="),
|
||||
customFingerprint = { method, _ ->
|
||||
method.name == "toString"
|
||||
},
|
||||
)
|
||||
|
||||
internal const val HLS_CURRENT_TIME_FEATURE_FLAG = 45355374L
|
||||
|
||||
internal val hlsCurrentTimeFingerprint = legacyFingerprint(
|
||||
|
Reference in New Issue
Block a user