Skip to content

Commit 274c009

Browse files
committed
sabr: add more protos; revert virus total fix when no apk found
1 parent 3c855de commit 274c009

File tree

9 files changed

+368
-161
lines changed

9 files changed

+368
-161
lines changed

.github/workflows/virustotal_scan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3939
run: |
4040
mkdir -p release_assets
41-
gh release download $TAG_NAME --dir release_assets --pattern "*.apk" || echo "No APKs found"
41+
gh release download $TAG_NAME --dir release_assets --pattern "*.apk"
4242
ls -l release_assets
4343
4444
- name: Install VirusTotal CLI

exoplayer-amzn-2.10.6/library/sabr/src/main/java/com/google/android/exoplayer2/source/sabr/manifest/SabrManifest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.google.android.exoplayer2.C;
44
import com.google.android.exoplayer2.offline.FilterableManifest;
55
import com.google.android.exoplayer2.offline.StreamKey;
6-
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.ClientInfo;
6+
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.StreamerContext.ClientInfo;
77

88
import java.util.List;
99

exoplayer-amzn-2.10.6/library/sabr/src/main/java/com/google/android/exoplayer2/source/sabr/manifest/SabrManifestParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import com.google.android.exoplayer2.source.sabr.manifest.SegmentBase.SegmentTemplate;
1414
import com.google.android.exoplayer2.source.sabr.manifest.SegmentBase.SegmentTimelineElement;
1515
import com.google.android.exoplayer2.source.sabr.manifest.SegmentBase.SingleSegmentBase;
16-
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.ClientInfo;
17-
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.ClientName;
16+
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.StreamerContext.ClientInfo;
17+
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.StreamerContext.ClientName;
1818
import com.google.android.exoplayer2.util.MimeTypes;
1919
import com.liskovsoft.mediaserviceinterfaces.data.MediaFormat;
2020
import com.liskovsoft.mediaserviceinterfaces.data.MediaItemFormatInfo;

exoplayer-amzn-2.10.6/library/sabr/src/main/java/com/google/android/exoplayer2/source/sabr/parser/SabrStream.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import com.google.android.exoplayer2.source.sabr.parser.ump.UMPPart;
2727
import com.google.android.exoplayer2.source.sabr.parser.ump.UMPPartId;
2828
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.ClientAbrState;
29-
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.ClientInfo;
29+
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.StreamerContext.ClientInfo;
3030
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.FormatInitializationMetadata;
3131
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.LiveMetadata;
3232
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.NextRequestPolicy;

exoplayer-amzn-2.10.6/library/sabr/src/main/java/com/google/android/exoplayer2/source/sabr/parser/processor/SabrProcessor.java

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
import com.google.android.exoplayer2.source.sabr.parser.parts.PoTokenStatusSabrPart.PoTokenStatus;
2424
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.BufferedRange;
2525
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.ClientAbrState;
26-
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.ClientInfo;
26+
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.StreamerContext.ClientInfo;
2727
import com.google.android.exoplayer2.source.sabr.protos.misc.FormatId;
2828
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.FormatInitializationMetadata;
2929
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.LiveMetadata;
3030
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.MediaHeader;
3131
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.NextRequestPolicy;
32-
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.SabrContext;
32+
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.StreamerContext.ClientName;
33+
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.StreamerContext.SabrContext;
3334
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.SabrContextSendingPolicy;
3435
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.SabrContextUpdate;
3536
import com.google.android.exoplayer2.source.sabr.protos.videostreaming.SabrSeek;
@@ -685,20 +686,100 @@ public int getLiveSegmentTargetDurationSec() {
685686
return liveSegmentTargetDurationSec;
686687
}
687688

689+
//public VideoPlaybackAbrRequest buildVideoPlaybackAbrRequest() {
690+
// return VideoPlaybackAbrRequest.newBuilder()
691+
// .setClientAbrState(getClientAbrState())
692+
// .addAllPreferredVideoFormatIds(selectedVideoFormatIds)
693+
// .addAllPreferredAudioFormatIds(selectedAudioFormatIds)
694+
// .addAllPreferredSubtitleFormatIds(selectedCaptionFormatIds)
695+
// .addAllSelectedFormatIds(getSelectedFormatIds())
696+
// .setVideoPlaybackUstreamerConfig(
697+
// ByteString.copyFrom(
698+
// Base64.decode(videoPlaybackUstreamerConfig, Base64.URL_SAFE)
699+
// )
700+
// )
701+
// .setStreamerContext(createStreamerContext())
702+
// .addAllBufferedRanges(createBufferedRanges())
703+
// .build();
704+
//}
705+
688706
public VideoPlaybackAbrRequest buildVideoPlaybackAbrRequest() {
707+
ClientAbrState clientAbrStateTest = ClientAbrState.newBuilder()
708+
.setLastManualSelectedResolution(1080)
709+
.setStickyResolution(1080)
710+
.setBandwidthEstimate(1350000)
711+
.setEnabledTrackTypesBitfield(2)
712+
.setDrcEnabled(false)
713+
.setSabrForceMaxNetworkInterruptionDurationMs(0)
714+
.build();
715+
716+
FormatId selectedVideo = FormatId.newBuilder()
717+
.setItag(399)
718+
.setLastModified(1759475866788004L)
719+
.build();
720+
FormatId selectedAudio = FormatId.newBuilder()
721+
.setItag(140)
722+
.setLastModified(1759475037898391L)
723+
.build();
724+
List<FormatId> selectedFormats = new ArrayList<>();
725+
selectedFormats.add(selectedAudio);
726+
727+
List<FormatId> preferredVideoFormats = new ArrayList<>();
728+
preferredVideoFormats.add(selectedVideo);
729+
730+
List<FormatId> preferredAudioFormats = new ArrayList<>();
731+
preferredAudioFormats.add(selectedAudio);
732+
733+
TimeRange timeRange = TimeRange.newBuilder()
734+
.setStartTicks(0)
735+
.setDurationTicks(2147483647)
736+
.setTimescale(1000)
737+
.build();
738+
BufferedRange bufferedRange = BufferedRange.newBuilder()
739+
.setFormatId(selectedAudio)
740+
.setStartTimeMs(0)
741+
.setDurationMs(2147483647)
742+
.setStartSegmentIndex(2147483647)
743+
.setEndSegmentIndex(2147483647)
744+
.setTimeRange(timeRange)
745+
.build();
746+
List<BufferedRange> bufferedRanges = new ArrayList<>();
747+
bufferedRanges.add(bufferedRange);
748+
749+
ClientInfo clientInfoTest = ClientInfo.newBuilder()
750+
.setClientName(ClientName.WEB)
751+
.setClientVersion("2.20250222.10.00")
752+
.setOsName("Macintosh")
753+
.setOsVersion("10_15_7")
754+
.build();
755+
756+
StreamerContext streamerContext = StreamerContext.newBuilder()
757+
.setPoToken(
758+
ByteString.copyFrom(
759+
Base64.decode(poToken, Base64.URL_SAFE)
760+
)
761+
)
762+
.setPlaybackCookie(
763+
nextRequestPolicy != null ? nextRequestPolicy.getPlaybackCookie() : ByteString.EMPTY
764+
)
765+
.setClientInfo(clientInfoTest)
766+
.addAllSabrContexts(createSabrContexts())
767+
.addAllUnsentSabrContexts(createUnsentSabrContexts())
768+
.build();
769+
689770
return VideoPlaybackAbrRequest.newBuilder()
690-
.setClientAbrState(getClientAbrState())
691-
.addAllPreferredVideoFormatIds(selectedVideoFormatIds)
692-
.addAllPreferredAudioFormatIds(selectedAudioFormatIds)
771+
.setClientAbrState(clientAbrStateTest)
772+
.addAllPreferredVideoFormatIds(preferredVideoFormats)
773+
.addAllPreferredAudioFormatIds(preferredAudioFormats)
693774
.addAllPreferredSubtitleFormatIds(selectedCaptionFormatIds)
694-
.addAllSelectedFormatIds(getSelectedFormatIds())
775+
.addAllSelectedFormatIds(selectedFormats)
776+
.addAllBufferedRanges(bufferedRanges)
695777
.setVideoPlaybackUstreamerConfig(
696778
ByteString.copyFrom(
697779
Base64.decode(videoPlaybackUstreamerConfig, Base64.URL_SAFE)
698780
)
699781
)
700-
.setStreamerContext(createStreamerContext())
701-
.addAllBufferedRanges(createBufferedRanges())
782+
.setStreamerContext(streamerContext)
702783
.build();
703784
}
704785

exoplayer-amzn-2.10.6/library/sabr/src/main/java/com/google/android/exoplayer2/source/sabr/parser/ump/UMPDecoder.java

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.liskovsoft.sharedutils.helpers.Helpers;
77

88
import java.io.ByteArrayInputStream;
9+
import java.io.EOFException;
910
import java.io.IOException;
1011

1112
public class UMPDecoder {
@@ -27,34 +28,65 @@ public UMPPart decode(@NonNull ExtractorInput extractorInput) {
2728
}
2829
}
2930

31+
//private long readVarInt(StreamWrapper input) throws IOException, InterruptedException {
32+
// // https://web.archive.org/web/20250430054327/https://github.com/gsuberland/UMP_Format/blob/main/UMP_Format.md
33+
// // https://web.archive.org/web/20250429151021/https://github.com/davidzeng0/innertube/blob/main/googlevideo/ump.md
34+
// byte[] buffer = new byte[1];
35+
// boolean success = input.readFully(buffer, 0, 1, true);
36+
// if (!success) {
37+
// // Expected EOF
38+
// return -1;
39+
// }
40+
//
41+
// long byteInt = buffer[0] & 0xFF; // convert to unsigned (0..255)
42+
// int size = varIntSize(byteInt);
43+
// long result = 0;
44+
// int shift = 0;
45+
//
46+
// if (size != 5) {
47+
// shift = 8 - size;
48+
// int mask = (1 << shift) - 1;
49+
// result |= byteInt & mask;
50+
// }
51+
//
52+
// for (int i : Helpers.range(1, size - 1, 1)) {
53+
// success = input.readFully(buffer, 0, 1, true);
54+
// if (!success) {
55+
// return -1;
56+
// }
57+
// byteInt = buffer[0] & 0xFF; // convert to unsigned (0..255)
58+
// result |= byteInt << shift;
59+
// shift += 8;
60+
// }
61+
//
62+
// return result;
63+
//}
64+
3065
private long readVarInt(StreamWrapper input) throws IOException, InterruptedException {
3166
// https://web.archive.org/web/20250430054327/https://github.com/gsuberland/UMP_Format/blob/main/UMP_Format.md
3267
// https://web.archive.org/web/20250429151021/https://github.com/davidzeng0/innertube/blob/main/googlevideo/ump.md
3368
byte[] buffer = new byte[1];
34-
boolean success = input.readFully(buffer, 0, 1, true);
35-
if (!success) {
36-
// Expected EOF
37-
return -1;
69+
if (!input.readFully(buffer, 0, 1, true)) {
70+
return -1; // clean EOF before reading anything
3871
}
3972

40-
long byteInt = buffer[0] & 0xFF; // convert to unsigned (0..255)
41-
int size = varIntSize(byteInt);
42-
long result = 0;
43-
int shift = 0;
73+
long first = buffer[0] & 0xFF;
74+
int size = varIntSize(first);
4475

45-
if (size != 5) {
46-
shift = 8 - size;
47-
int mask = (1 << shift) - 1;
48-
result |= byteInt & mask;
76+
if (size < 1 || size > 5) {
77+
throw new IOException("Invalid VarInt size: " + size);
4978
}
5079

51-
for (int i : Helpers.range(1, size - 1, 1)) {
52-
success = input.readFully(buffer, 0, 1, true);
53-
if (!success) {
54-
return -1;
80+
int payloadBits = 8 - (size + 1);
81+
long result = first & ((1L << payloadBits) - 1);
82+
int shift = payloadBits;
83+
84+
for (int i = 1; i < size; i++) {
85+
if (!input.readFully(buffer, 0, 1, true)) {
86+
throw new EOFException("Unexpected EOF in VarInt");
5587
}
56-
byteInt = buffer[0] & 0xFF; // convert to unsigned (0..255)
57-
result |= byteInt << shift;
88+
long b = buffer[0] & 0xFF;
89+
result |= b << shift;
5890
shift += 8;
5991
}
6092

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
syntax = "proto3";
2+
3+
package sabr.other;
4+
5+
option java_multiple_files = true;
6+
option java_package = "com.google.android.exoplayer2.source.sabr.protos.other";
7+
option optimize_for = LITE_RUNTIME;
8+
9+
enum UmpPartId {
10+
UNKNOWN = 0;
11+
ONESIE_HEADER = 10;
12+
ONESIE_DATA = 11;
13+
ONESIE_ENCRYPTED_MEDIA = 12;
14+
// Header for a media segment; includes sequence and timing information.
15+
MEDIA_HEADER = 20;
16+
// Chunk of media segment data.
17+
MEDIA = 21;
18+
// Indicates end of media segment; finalizes segment processing.
19+
MEDIA_END = 22;
20+
CONFIG = 30;
21+
LIVE_METADATA = 31;
22+
HOSTNAME_CHANGE_HINT_DEPRECATED = 32;
23+
LIVE_METADATA_PROMISE = 33;
24+
LIVE_METADATA_PROMISE_CANCELLATION = 34;
25+
// Server's policy for the next request; includes backoff time and playback cookie.
26+
NEXT_REQUEST_POLICY = 35;
27+
USTREAMER_VIDEO_AND_FORMAT_METADATA = 36;
28+
FORMAT_SELECTION_CONFIG = 37;
29+
USTREAMER_SELECTED_MEDIA_STREAM = 38;
30+
// Metadata for format initialization; contains total number of segments, duration, etc.
31+
FORMAT_INITIALIZATION_METADATA = 42;
32+
// Indicates a redirect to a different streaming URL.
33+
SABR_REDIRECT = 43;
34+
// Indicates a SABR error; happens when the payload is invalid or the server cannot process the request.
35+
SABR_ERROR = 44;
36+
SABR_SEEK = 45;
37+
// Directive to reload the player with new parameters.
38+
RELOAD_PLAYER_RESPONSE = 46;
39+
PLAYBACK_START_POLICY = 47;
40+
ALLOWED_CACHED_FORMATS = 48;
41+
START_BW_SAMPLING_HINT = 49;
42+
PAUSE_BW_SAMPLING_HINT = 50;
43+
SELECTABLE_FORMATS = 51;
44+
REQUEST_IDENTIFIER = 52;
45+
REQUEST_CANCELLATION_POLICY = 53;
46+
ONESIE_PREFETCH_REJECTION = 54;
47+
TIMELINE_CONTEXT = 55;
48+
REQUEST_PIPELINING = 56;
49+
// Updates SABR context data; usually used for ads.
50+
SABR_CONTEXT_UPDATE = 57;
51+
// Status of stream protection; indicates whether attestation is required.
52+
STREAM_PROTECTION_STATUS = 58;
53+
// Policy indicating which SABR contexts to send or discard in future requests.
54+
SABR_CONTEXT_SENDING_POLICY = 59;
55+
LAWNMOWER_POLICY = 60;
56+
SABR_ACK = 61;
57+
END_OF_TRACK = 62;
58+
CACHE_LOAD_POLICY = 63;
59+
LAWNMOWER_MESSAGING_POLICY = 64;
60+
PREWARM_CONNECTION = 65;
61+
PLAYBACK_DEBUG_INFO = 66;
62+
// Directive to show the user a notification message.
63+
SNACKBAR_MESSAGE = 67;
64+
}

0 commit comments

Comments
 (0)