|
|
|
|
|
from pytubefix.sabr.proto import BinaryWriter, BinaryReader |
|
|
|
|
|
class ClientAbrState: |
|
|
|
@staticmethod |
|
def create_base_client_abr_state(): |
|
return { |
|
"timeSinceLastManualFormatSelectionMs": 0, |
|
"lastManualDirection": 0, |
|
"lastManualSelectedResolution": 0, |
|
"detailedNetworkType": 0, |
|
"clientViewportWidth": 0, |
|
"clientViewportHeight": 0, |
|
"clientBitrateCapBytesPerSec": 0, |
|
"stickyResolution": 0, |
|
"clientViewportIsFlexible": False, |
|
"bandwidthEstimate": 0, |
|
"minAudioQuality": 0, |
|
"maxAudioQuality": 0, |
|
"videoQualitySetting": 0, |
|
"audioRoute": 0, |
|
"playerTimeMs": 0, |
|
"timeSinceLastSeek": 0, |
|
"dataSaverMode": False, |
|
"networkMeteredState": 0, |
|
"visibility": 0, |
|
"playbackRate": 0, |
|
"elapsedWallTimeMs": 0, |
|
"mediaCapabilities": bytearray(), |
|
"timeSinceLastActionMs": 0, |
|
"enabledTrackTypesBitfield": 0, |
|
"maxPacingRate": 0, |
|
"playerState": 0, |
|
"drcEnabled": False, |
|
"Jda": 0, |
|
"qw": 0, |
|
"Ky": 0, |
|
"sabrReportRequestCancellationInfo": 0, |
|
"l": False, |
|
"G7": 0, |
|
"preferVp9": False, |
|
"qj": 0, |
|
"Hx": 0, |
|
"isPrefetch": False, |
|
"sabrSupportQualityConstraints": 0, |
|
"sabrLicenseConstraint": bytearray(), |
|
"allowProximaLiveLatency": 0, |
|
"sabrForceProxima": 0, |
|
"Tqb": 0, |
|
"sabrForceMaxNetworkInterruptionDurationMs": 0, |
|
"audioTrackId": "" |
|
} |
|
|
|
@staticmethod |
|
def encode(message: dict, writer=None): |
|
if writer is None: |
|
writer = BinaryWriter() |
|
|
|
if message.get("timeSinceLastManualFormatSelectionMs", 0): |
|
writer.uint32(104).int64(message["timeSinceLastManualFormatSelectionMs"]) |
|
if message.get("lastManualDirection", 0): |
|
writer.uint32(112).sint32(message["lastManualDirection"]) |
|
if message.get("lastManualSelectedResolution", 0): |
|
writer.uint32(128).int32(message["lastManualSelectedResolution"]) |
|
if message.get("detailedNetworkType", 0): |
|
writer.uint32(136).int32(message["detailedNetworkType"]) |
|
if message.get("clientViewportWidth", 0): |
|
writer.uint32(144).int32(message["clientViewportWidth"]) |
|
if message.get("clientViewportHeight", 0): |
|
writer.uint32(152).int32(message["clientViewportHeight"]) |
|
if message.get("clientBitrateCapBytesPerSec", 0): |
|
writer.uint32(160).int64(message["clientBitrateCapBytesPerSec"]) |
|
if message.get("stickyResolution", 0): |
|
writer.uint32(168).int32(message["stickyResolution"]) |
|
if message.get("clientViewportIsFlexible", False): |
|
writer.uint32(176).bool(message["clientViewportIsFlexible"]) |
|
if message.get("bandwidthEstimate", 0): |
|
writer.uint32(184).int64(message["bandwidthEstimate"]) |
|
if message.get("minAudioQuality", 0): |
|
writer.uint32(192).int32(message["minAudioQuality"]) |
|
if message.get("maxAudioQuality", 0): |
|
writer.uint32(200).int32(message["maxAudioQuality"]) |
|
if message.get("videoQualitySetting", 0): |
|
writer.uint32(208).int32(message["videoQualitySetting"]) |
|
if message.get("audioRoute", 0): |
|
writer.uint32(216).int32(message["audioRoute"]) |
|
if message.get("playerTimeMs", 0): |
|
writer.uint32(224).int64(message["playerTimeMs"]) |
|
if message.get("timeSinceLastSeek", 0): |
|
writer.uint32(232).int64(message["timeSinceLastSeek"]) |
|
if message.get("dataSaverMode", False): |
|
writer.uint32(240).bool(message["dataSaverMode"]) |
|
if message.get("networkMeteredState", 0): |
|
writer.uint32(256).int32(message["networkMeteredState"]) |
|
if message.get("visibility", 0): |
|
writer.uint32(272).int32(message["visibility"]) |
|
if message.get("playbackRate", 0): |
|
writer.uint32(285).float(message["playbackRate"]) |
|
if message.get("elapsedWallTimeMs", 0): |
|
writer.uint32(288).int64(message["elapsedWallTimeMs"]) |
|
if message.get("mediaCapabilities", b''): |
|
writer.uint32(306).bytes(message["mediaCapabilities"]) |
|
if message.get("timeSinceLastActionMs", 0): |
|
writer.uint32(312).int64(message["timeSinceLastActionMs"]) |
|
if message.get("enabledTrackTypesBitfield", 0): |
|
writer.uint32(320).int32(message["enabledTrackTypesBitfield"]) |
|
if message.get("maxPacingRate", 0): |
|
writer.uint32(344).int32(message["maxPacingRate"]) |
|
if message.get("playerState", 0): |
|
writer.uint32(352).int64(message["playerState"]) |
|
if message.get("drcEnabled", False): |
|
writer.uint32(368).bool(message["drcEnabled"]) |
|
if message.get("Jda", 0): |
|
writer.uint32(384).int32(message["Jda"]) |
|
if message.get("qw", 0): |
|
writer.uint32(400).int32(message["qw"]) |
|
if message.get("Ky", 0): |
|
writer.uint32(408).int32(message["Ky"]) |
|
if message.get("sabrReportRequestCancellationInfo", 0): |
|
writer.uint32(432).int32(message["sabrReportRequestCancellationInfo"]) |
|
if message.get("l", False): |
|
writer.uint32(448).bool(message["l"]) |
|
if message.get("G7", 0): |
|
writer.uint32(456).int64(message["G7"]) |
|
if message.get("preferVp9", False): |
|
writer.uint32(464).bool(message["preferVp9"]) |
|
if message.get("qj", 0): |
|
writer.uint32(472).int32(message["qj"]) |
|
if message.get("Hx", 0): |
|
writer.uint32(480).int32(message["Hx"]) |
|
if message.get("isPrefetch", False): |
|
writer.uint32(488).bool(message["isPrefetch"]) |
|
if message.get("sabrSupportQualityConstraints", 0): |
|
writer.uint32(496).int32(message["sabrSupportQualityConstraints"]) |
|
if message.get("sabrLicenseConstraint", b''): |
|
writer.uint32(506).bytes(message["sabrLicenseConstraint"]) |
|
if message.get("allowProximaLiveLatency", 0): |
|
writer.uint32(512).int32(message["allowProximaLiveLatency"]) |
|
if message.get("sabrForceProxima", 0): |
|
writer.uint32(528).int32(message["sabrForceProxima"]) |
|
if message.get("Tqb", 0): |
|
writer.uint32(536).int32(message["Tqb"]) |
|
if message.get("sabrForceMaxNetworkInterruptionDurationMs", 0): |
|
writer.uint32(544).int64(message["sabrForceMaxNetworkInterruptionDurationMs"]) |
|
if message.get("audioTrackId", ""): |
|
writer.uint32(554).string(message["audioTrackId"]) |
|
|
|
return writer |
|
|
|
@staticmethod |
|
def decode(input_data, length=None): |
|
reader = input_data if isinstance(input_data, BinaryReader) else BinaryReader(input_data) |
|
end = reader.len if length is None else reader.pos + length |
|
message = ClientAbrState.create_base_client_abr_state() |
|
|
|
while reader.pos < end: |
|
tag = reader.uint32() |
|
field_number = tag >> 3 |
|
|
|
if field_number == 13 and tag == 104: |
|
message['timeSinceLastManualFormatSelectionMs'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 14 and tag == 112: |
|
message['lastManualDirection'] = reader.sint32() |
|
continue |
|
elif field_number == 16 and tag == 128: |
|
message['lastManualSelectedResolution'] = reader.int32() |
|
continue |
|
elif field_number == 17 and tag == 136: |
|
message['detailedNetworkType'] = reader.int32() |
|
continue |
|
elif field_number == 18 and tag == 144: |
|
message['clientViewportWidth'] = reader.int32() |
|
continue |
|
elif field_number == 19 and tag == 152: |
|
message['clientViewportHeight'] = reader.int32() |
|
continue |
|
elif field_number == 20 and tag == 160: |
|
message['clientBitrateCapBytesPerSec'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 21 and tag == 168: |
|
message['stickyResolution'] = reader.int32() |
|
continue |
|
elif field_number == 22 and tag == 176: |
|
message['clientViewportIsFlexible'] = reader.bool() |
|
continue |
|
elif field_number == 23 and tag == 184: |
|
message['bandwidthEstimate'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 24 and tag == 192: |
|
message['minAudioQuality'] = reader.int32() |
|
continue |
|
elif field_number == 25 and tag == 200: |
|
message['maxAudioQuality'] = reader.int32() |
|
continue |
|
elif field_number == 26 and tag == 208: |
|
message['videoQualitySetting'] = reader.int32() |
|
continue |
|
elif field_number == 27 and tag == 216: |
|
message['audioRoute'] = reader.int32() |
|
continue |
|
elif field_number == 28 and tag == 224: |
|
message['playerTimeMs'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 29 and tag == 232: |
|
message['timeSinceLastSeek'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 30 and tag == 240: |
|
message['dataSaverMode'] = reader.bool() |
|
continue |
|
elif field_number == 32 and tag == 256: |
|
message['networkMeteredState'] = reader.int32() |
|
continue |
|
elif field_number == 34 and tag == 272: |
|
message['visibility'] = reader.int32() |
|
continue |
|
elif field_number == 35 and tag == 285: |
|
message['playbackRate'] = reader.float() |
|
continue |
|
elif field_number == 36 and tag == 288: |
|
message['elapsedWallTimeMs'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 38 and tag == 306: |
|
message['mediaCapabilities'] = reader.bytes() |
|
continue |
|
elif field_number == 39 and tag == 312: |
|
message['timeSinceLastActionMs'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 40 and tag == 320: |
|
message['enabledTrackTypesBitfield'] = reader.int32() |
|
continue |
|
elif field_number == 43 and tag == 344: |
|
message['maxPacingRate'] = reader.int32() |
|
continue |
|
elif field_number == 44 and tag == 352: |
|
message['playerState'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 46 and tag == 368: |
|
message['drcEnabled'] = reader.bool() |
|
continue |
|
elif field_number == 48 and tag == 384: |
|
message['Jda'] = reader.int32() |
|
continue |
|
elif field_number == 50 and tag == 400: |
|
message['qw'] = reader.int32() |
|
continue |
|
elif field_number == 51 and tag == 408: |
|
message['Ky'] = reader.int32() |
|
continue |
|
elif field_number == 54 and tag == 432: |
|
message['sabrReportRequestCancellationInfo'] = reader.int32() |
|
continue |
|
elif field_number == 56 and tag == 448: |
|
message['l'] = reader.bool() |
|
continue |
|
elif field_number == 57 and tag == 456: |
|
message['G7'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 58 and tag == 464: |
|
message['preferVp9'] = reader.bool() |
|
continue |
|
elif field_number == 59 and tag == 472: |
|
message['qj'] = reader.int32() |
|
continue |
|
elif field_number == 60 and tag == 480: |
|
message['Hx'] = reader.int32() |
|
continue |
|
elif field_number == 61 and tag == 488: |
|
message['isPrefetch'] = reader.bool() |
|
continue |
|
elif field_number == 62 and tag == 496: |
|
message['sabrSupportQualityConstraints'] = reader.int32() |
|
continue |
|
elif field_number == 63 and tag == 506: |
|
message['sabrLicenseConstraint'] = reader.bytes() |
|
continue |
|
elif field_number == 64 and tag == 512: |
|
message['allowProximaLiveLatency'] = reader.int32() |
|
continue |
|
elif field_number == 66 and tag == 528: |
|
message['sabrForceProxima'] = reader.int32() |
|
continue |
|
elif field_number == 67 and tag == 536: |
|
message['Tqb'] = reader.int32() |
|
continue |
|
elif field_number == 68 and tag == 544: |
|
message['sabrForceMaxNetworkInterruptionDurationMs'] = long_to_number(reader.int64()) |
|
continue |
|
elif field_number == 69 and tag == 554: |
|
message['audioTrackId'] = reader.string() |
|
continue |
|
else: |
|
if (tag & 7) == 4 or tag == 0: |
|
break |
|
reader.skip(tag & 7) |
|
|
|
return message |
|
|
|
def long_to_number(int64_value): |
|
value = int(str(int64_value)) |
|
if value > (2 ** 53 - 1): |
|
raise OverflowError("Value is larger than 9007199254740991") |
|
if value < -(2 ** 53 - 1): |
|
raise OverflowError("Value is smaller than -9007199254740991") |
|
return value |