├── .release-please-manifest.json
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── question.yml
│ ├── feature.yml
│ └── issue.yml
└── workflows
│ ├── lint.yml
│ ├── test.yml
│ └── release-please.yml
├── .npmignore
├── src
├── exports
│ ├── utils.ts
│ ├── protos.ts
│ ├── sabr-stream.ts
│ ├── ump.ts
│ └── sabr-streaming-adapter.ts
├── utils
│ ├── index.ts
│ ├── RequestMetadataManager.ts
│ ├── EventEmitterLike.ts
│ └── Logger.ts
├── types
│ └── shared.ts
└── core
│ └── UmpWriter.ts
├── protos
├── video_streaming
│ ├── sabr_redirect.proto
│ ├── snackbar_message.proto
│ ├── request_identifier.proto
│ ├── sabr_error.proto
│ ├── stream_protection_status.proto
│ ├── time_range.proto
│ ├── format_selection_config.proto
│ ├── sabr_context_sending_policy.proto
│ ├── crypto_params.proto
│ ├── reload_player_response.proto
│ ├── sabr_seek.proto
│ ├── request_cancellation_policy.proto
│ ├── onesie_innertube_request.proto
│ ├── onesie_innertube_response.proto
│ ├── playback_start_policy.proto
│ ├── playback_cookie.proto
│ ├── onesie_header_type.proto
│ ├── onesie_proxy_status.proto
│ ├── format_initialization_metadata.proto
│ ├── next_request_policy.proto
│ ├── live_metadata.proto
│ ├── innertube_request.proto
│ ├── media_header.proto
│ ├── media_capabilities.proto
│ ├── onesie_header.proto
│ ├── onesie_request.proto
│ ├── buffered_range.proto
│ ├── sabr_context_update.proto
│ ├── video_playback_abr_request.proto
│ ├── streamer_context.proto
│ ├── ump_part_id.proto
│ └── client_abr_state.proto
└── generated
│ └── video_streaming
│ ├── onesie_header_type.ts
│ ├── onesie_proxy_status.ts
│ ├── sabr_redirect.ts
│ ├── snackbar_message.ts
│ ├── request_identifier.ts
│ ├── sabr_error.ts
│ ├── stream_protection_status.ts
│ ├── time_range.ts
│ ├── crypto_params.ts
│ ├── sabr_seek.ts
│ ├── ump_part_id.ts
│ ├── format_selection_config.ts
│ └── playback_cookie.ts
├── .vscode
└── settings.json
├── .editorconfig
├── docs
└── api
│ ├── exports
│ ├── ump
│ │ ├── README.md
│ │ └── classes
│ │ │ └── UmpWriter.md
│ ├── protos
│ │ ├── variables
│ │ │ ├── Range.md
│ │ │ ├── FormatId.md
│ │ │ ├── HttpHeader.md
│ │ │ ├── KeyValuePair.md
│ │ │ ├── SabrError.md
│ │ │ ├── IdentifierToken.md
│ │ │ ├── AuthorizedFormat.md
│ │ │ ├── MediaHeader.md
│ │ │ ├── ClientInfo.md
│ │ │ ├── CryptoParams.md
│ │ │ ├── LiveMetadata.md
│ │ │ ├── OnesieHeader.md
│ │ │ ├── SabrRedirect.md
│ │ │ ├── BufferedRange.md
│ │ │ ├── OnesieRequest.md
│ │ │ ├── PlaybackAuthorization.md
│ │ │ ├── PlaybackCookie.md
│ │ │ ├── ClientAbrState.md
│ │ │ ├── UstreamerFlags.md
│ │ │ ├── SnackbarMessage.md
│ │ │ ├── StreamerContext.md
│ │ │ ├── InnertubeRequest.md
│ │ │ ├── SabrContextValue.md
│ │ │ ├── MediaCapabilities.md
│ │ │ ├── NextRequestPolicy.md
│ │ │ ├── RequestIdentifier.md
│ │ │ ├── SabrContextUpdate.md
│ │ │ ├── PlaybackStartPolicy.md
│ │ │ ├── ReloadPlaybackParams.md
│ │ │ ├── ReloadPlaybackContext.md
│ │ │ ├── FormatSelectionConfig.md
│ │ │ ├── OnesieInnertubeRequest.md
│ │ │ ├── StreamProtectionStatus.md
│ │ │ ├── OnesieInnertubeResponse.md
│ │ │ ├── VideoPlaybackAbrRequest.md
│ │ │ ├── SabrContextSendingPolicy.md
│ │ │ ├── RequestCancellationPolicy.md
│ │ │ └── FormatInitializationMetadata.md
│ │ ├── interfaces
│ │ │ ├── SabrRedirect.md
│ │ │ ├── SnackbarMessage.md
│ │ │ ├── RequestIdentifier.md
│ │ │ ├── ReloadPlaybackParams.md
│ │ │ ├── UstreamerFlags.md
│ │ │ ├── ReloadPlaybackContext.md
│ │ │ ├── HttpHeader.md
│ │ │ ├── KeyValuePair.md
│ │ │ ├── AuthorizedFormat.md
│ │ │ ├── IdentifierToken.md
│ │ │ ├── SabrError.md
│ │ │ ├── PlaybackAuthorization.md
│ │ │ ├── StreamProtectionStatus.md
│ │ │ ├── FormatId.md
│ │ │ ├── PlaybackStartPolicy.md
│ │ │ ├── CryptoParams.md
│ │ │ ├── FormatSelectionConfig.md
│ │ │ ├── Range.md
│ │ │ ├── SabrContextValue.md
│ │ │ ├── RequestCancellationPolicy.md
│ │ │ ├── SabrContextSendingPolicy.md
│ │ │ ├── MediaCapabilities.md
│ │ │ ├── PlaybackCookie.md
│ │ │ ├── OnesieInnertubeResponse.md
│ │ │ ├── SabrContextUpdate.md
│ │ │ ├── OnesieInnertubeRequest.md
│ │ │ ├── StreamerContext.md
│ │ │ └── NextRequestPolicy.md
│ │ └── enumerations
│ │ │ ├── CompressionType.md
│ │ │ ├── NetworkMeteredState.md
│ │ │ ├── SabrContextWritePolicy.md
│ │ │ ├── VideoQualitySetting.md
│ │ │ ├── AudioQuality.md
│ │ │ └── OnesieRequestTarget.md
│ ├── utils
│ │ ├── variables
│ │ │ └── MAX_INT32_VALUE.md
│ │ ├── functions
│ │ │ ├── u8ToBase64.md
│ │ │ ├── base64ToU8.md
│ │ │ ├── wait.md
│ │ │ ├── concatenateChunks.md
│ │ │ ├── parseRangeHeader.md
│ │ │ ├── buildSabrFormat.md
│ │ │ └── isGoogleVideoURL.md
│ │ ├── namespaces
│ │ │ └── FormatKeyUtils
│ │ │ │ ├── README.md
│ │ │ │ └── functions
│ │ │ │ ├── createKey.md
│ │ │ │ ├── fromMediaHeader.md
│ │ │ │ ├── fromFormat.md
│ │ │ │ ├── getUniqueFormatId.md
│ │ │ │ ├── createSegmentCacheKeyFromMetadata.md
│ │ │ │ ├── fromFormatInitializationMetadata.md
│ │ │ │ └── createSegmentCacheKey.md
│ │ ├── interfaces
│ │ │ └── CacheEntry.md
│ │ ├── enumerations
│ │ │ ├── EnabledTrackTypes.md
│ │ │ └── LogLevel.md
│ │ ├── README.md
│ │ └── classes
│ │ │ └── RequestMetadataManager.md
│ ├── sabr-stream
│ │ ├── README.md
│ │ └── interfaces
│ │ │ └── InitializedFormat.md
│ └── sabr-streaming-adapter
│ │ ├── type-aliases
│ │ ├── RequestFilter.md
│ │ └── ResponseFilter.md
│ │ ├── interfaces
│ │ ├── UmpProcessingResult.md
│ │ ├── RequestSegment.md
│ │ ├── PlayerHttpRequest.md
│ │ ├── PlayerHttpResponse.md
│ │ └── SabrOptions.md
│ │ ├── README.md
│ │ ├── variables
│ │ └── SABR_CONSTANTS.md
│ │ └── classes
│ │ └── SabrUmpProcessor.md
│ ├── README.md
│ └── types
│ └── shared
│ ├── type-aliases
│ ├── FetchFunction.md
│ └── Part.md
│ └── README.md
├── typedoc.json
├── examples
├── onesie-request
│ ├── package.json
│ ├── utils.ts
│ └── package-lock.json
├── sabr-shaka-example
│ ├── tsconfig.json
│ ├── package.json
│ ├── scripts
│ │ └── patchShaka.mjs
│ ├── index.html
│ └── README.md
├── README.md
└── downloader
│ ├── package.json
│ ├── utils
│ └── webpo-helper.ts
│ └── main.ts
├── release-please-config.json
├── jsr.json
├── LICENSE
├── .gitignore
├── dev-scripts
└── generate-proto.mjs
└── package.json
/.release-please-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | ".": "4.0.4"
3 | }
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | **
2 |
3 | src/
4 | docs/
5 | !dist/**
6 | !README.md
7 | !LICENSE
8 | !bundle/**
--------------------------------------------------------------------------------
/src/exports/utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains general utilities.
3 | * @module
4 | */
5 |
6 | export * from '../utils/index.js';
--------------------------------------------------------------------------------
/src/exports/protos.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains protobuf definitions.
3 | * @module
4 | */
5 |
6 | export * from '../utils/Protos.js';
--------------------------------------------------------------------------------
/protos/video_streaming/sabr_redirect.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message SabrRedirect {
5 | optional string url = 1;
6 | }
7 |
--------------------------------------------------------------------------------
/protos/video_streaming/snackbar_message.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message SnackbarMessage {
5 | optional int32 id = 1;
6 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules\\typescript\\lib",
3 | "protoc": {
4 | "options": [
5 | "--proto_path=protos",
6 | ]
7 | }
8 | }
--------------------------------------------------------------------------------
/protos/video_streaming/request_identifier.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 |
3 | package video_streaming;
4 |
5 | message RequestIdentifier {
6 | optional string token = 1;
7 | }
--------------------------------------------------------------------------------
/protos/video_streaming/sabr_error.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message SabrError {
5 | optional string type = 1;
6 | optional int32 code = 2;
7 | }
8 |
--------------------------------------------------------------------------------
/src/exports/sabr-stream.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains a SABR client for downloading videos.
3 | * @module
4 | */
5 |
6 | export * from '../core/SabrStream.js';
7 | export type * from '../types/sabrStreamTypes.js';
--------------------------------------------------------------------------------
/protos/video_streaming/stream_protection_status.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message StreamProtectionStatus {
5 | optional int32 status = 1;
6 | optional int32 max_retries = 2;
7 | }
8 |
--------------------------------------------------------------------------------
/protos/video_streaming/time_range.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message TimeRange {
5 | optional int64 start_ticks = 1;
6 | optional int64 duration_ticks = 2;
7 | optional int32 timescale = 3;
8 | }
9 |
--------------------------------------------------------------------------------
/src/exports/ump.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains utilities for writing and reading UMP data.
3 | * @module
4 | */
5 |
6 | export * from '../core/UmpReader.js';
7 | export * from '../core/UmpWriter.js';
8 | export * from '../core/CompositeBuffer.js';
--------------------------------------------------------------------------------
/protos/video_streaming/format_selection_config.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 |
3 | package video_streaming;
4 |
5 | message FormatSelectionConfig {
6 | repeated int32 itags = 2;
7 | optional string video_id = 3;
8 | optional int32 resolution = 4;
9 | }
--------------------------------------------------------------------------------
/protos/video_streaming/sabr_context_sending_policy.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message SabrContextSendingPolicy {
5 | repeated int32 start_policy = 1;
6 | repeated int32 stop_policy = 2;
7 | repeated int32 discard_policy = 3;
8 | }
--------------------------------------------------------------------------------
/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Logger.js';
2 | export * from './shared.js';
3 | export * from './CacheManager.js';
4 | export * from './EventEmitterLike.js';
5 | export * from './RequestMetadataManager.js';
6 | export * as FormatKeyUtils from './formatKeyUtils.js';
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: https://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 2
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = false
12 | insert_final_newline = false
--------------------------------------------------------------------------------
/protos/video_streaming/crypto_params.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 |
6 | message CryptoParams {
7 | optional bytes hmac = 4;
8 | optional bytes iv = 5;
9 | optional .misc.CompressionType compression_type = 6;
10 | }
11 |
--------------------------------------------------------------------------------
/protos/video_streaming/reload_player_response.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 |
3 | package video_streaming;
4 |
5 | message ReloadPlaybackParams {
6 | optional string token = 1;
7 | }
8 |
9 | message ReloadPlaybackContext {
10 | optional ReloadPlaybackParams reload_playback_params = 1;
11 | }
--------------------------------------------------------------------------------
/protos/video_streaming/sabr_seek.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 |
6 | message SabrSeek {
7 | optional int64 seek_media_time = 1;
8 | optional int32 seek_media_timescale = 2;
9 | optional .misc.SeekSource seek_source = 3;
10 | }
11 |
--------------------------------------------------------------------------------
/docs/api/exports/ump/README.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../README.md) / exports/ump
2 |
3 | # exports/ump
4 |
5 | This module contains utilities for writing and reading UMP data.
6 |
7 | ## Classes
8 |
9 | - [CompositeBuffer](classes/CompositeBuffer.md)
10 | - [UmpReader](classes/UmpReader.md)
11 | - [UmpWriter](classes/UmpWriter.md)
12 |
--------------------------------------------------------------------------------
/docs/api/README.md:
--------------------------------------------------------------------------------
1 | # googlevideo
2 |
3 | ## Modules
4 |
5 | - [exports/protos](exports/protos/README.md)
6 | - [exports/sabr-stream](exports/sabr-stream/README.md)
7 | - [exports/sabr-streaming-adapter](exports/sabr-streaming-adapter/README.md)
8 | - [exports/ump](exports/ump/README.md)
9 | - [exports/utils](exports/utils/README.md)
10 | - [types/shared](types/shared/README.md)
11 |
--------------------------------------------------------------------------------
/docs/api/types/shared/type-aliases/FetchFunction.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [types/shared](../README.md) / FetchFunction
2 |
3 | # Type Alias: FetchFunction
4 |
5 | > **FetchFunction** = *typeof* `fetch`
6 |
7 | Defined in: [codeberg/googlevideo/src/types/shared.ts:71](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/shared.ts#L71)
8 |
--------------------------------------------------------------------------------
/protos/video_streaming/request_cancellation_policy.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message RequestCancellationPolicy {
5 | message Item {
6 | optional int32 fR = 1;
7 | optional int32 NK = 2;
8 | optional int32 minReadaheadMs = 3;
9 | }
10 |
11 | optional int32 N0 = 1;
12 | repeated Item items = 2;
13 | optional int32 jq = 3;
14 | }
15 |
--------------------------------------------------------------------------------
/src/exports/sabr-streaming-adapter.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains the core classes, types, and utilities required to integrate YouTube's SABR streaming protocol
3 | * into a media player.
4 | * @module
5 | */
6 |
7 | export * from '../core/SabrStreamingAdapter.js';
8 | export * from '../core/SabrUmpProcessor.js';
9 | export type * from '../types/sabrStreamingAdapterTypes.js';
10 |
--------------------------------------------------------------------------------
/protos/video_streaming/onesie_innertube_request.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 |
6 | message OnesieInnertubeRequest {
7 | optional string url = 1;
8 | repeated misc.HttpHeader headers = 2;
9 | optional string body = 3;
10 | optional bool proxied_by_trusted_bandaid = 4;
11 | optional bool skip_response_encryption = 6;
12 | }
13 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/Range.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / Range
2 |
3 | # Variable: Range
4 |
5 | > **Range**: `MessageFns`\<[`Range`](../interfaces/Range.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:192](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L192)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/variables/MAX_INT32_VALUE.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / MAX\_INT32\_VALUE
2 |
3 | # Variable: MAX\_INT32\_VALUE
4 |
5 | > `const` **MAX\_INT32\_VALUE**: `2147483647` = `2147483647`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:3](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L3)
8 |
--------------------------------------------------------------------------------
/docs/api/types/shared/README.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../README.md) / types/shared
2 |
3 | # types/shared
4 |
5 | This module contains type definitions used across the library.
6 |
7 | ## Interfaces
8 |
9 | - [FormatStream](interfaces/FormatStream.md)
10 | - [SabrFormat](interfaces/SabrFormat.md)
11 |
12 | ## Type Aliases
13 |
14 | - [FetchFunction](type-aliases/FetchFunction.md)
15 | - [Part](type-aliases/Part.md)
16 |
--------------------------------------------------------------------------------
/protos/video_streaming/onesie_innertube_response.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 | import "video_streaming/onesie_proxy_status.proto";
6 |
7 | message OnesieInnertubeResponse {
8 | optional OnesieProxyStatus onesie_proxy_status = 1;
9 | optional int32 http_status = 2;
10 | repeated .misc.HttpHeader headers = 3;
11 | optional bytes body = 4;
12 | }
13 |
--------------------------------------------------------------------------------
/protos/video_streaming/playback_start_policy.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message PlaybackStartPolicy {
5 | message ReadaheadPolicy {
6 | optional int32 min_readahead_ms = 2;
7 | optional int32 min_bandwidth_bytes_per_sec = 1;
8 | }
9 |
10 | optional ReadaheadPolicy start_min_readahead_policy = 1;
11 | optional ReadaheadPolicy resume_min_readahead_policy = 2;
12 | }
13 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/FormatId.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / FormatId
2 |
3 | # Variable: FormatId
4 |
5 | > **FormatId**: `MessageFns`\<[`FormatId`](../interfaces/FormatId.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:186](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L186)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/HttpHeader.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / HttpHeader
2 |
3 | # Variable: HttpHeader
4 |
5 | > **HttpHeader**: `MessageFns`\<[`HttpHeader`](../interfaces/HttpHeader.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:181](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L181)
8 |
--------------------------------------------------------------------------------
/protos/video_streaming/playback_cookie.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 |
6 | message PlaybackCookie {
7 | optional int32 resolution = 1; // Always 999999 when resolution is set manually, or if the auto selected one is the max available resolution.
8 | optional int32 field2 = 2;
9 | optional .misc.FormatId video_fmt = 7;
10 | optional .misc.FormatId audio_fmt = 8;
11 | }
12 |
--------------------------------------------------------------------------------
/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "readme": "none",
3 | "entryPoints": [
4 | "src/exports/ump.ts",
5 | "src/exports/sabr-streaming-adapter.ts",
6 | "src/exports/sabr-stream.ts",
7 | "src/exports/protos.ts",
8 | "src/exports/utils.ts",
9 | "src/types/shared.ts"
10 | ],
11 | "out": "docs/api",
12 | "plugin": [
13 | "typedoc-plugin-markdown"
14 | ],
15 | "hidePageHeader": true,
16 | "tsconfig": "tsconfig.json"
17 | }
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/KeyValuePair.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / KeyValuePair
2 |
3 | # Variable: KeyValuePair
4 |
5 | > **KeyValuePair**: `MessageFns`\<[`KeyValuePair`](../interfaces/KeyValuePair.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:204](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L204)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/SabrError.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrError
2 |
3 | # Variable: SabrError
4 |
5 | > **SabrError**: `MessageFns`\<[`SabrError`](../interfaces/SabrError.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_error.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_error.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/IdentifierToken.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / IdentifierToken
2 |
3 | # Variable: IdentifierToken
4 |
5 | > **IdentifierToken**: `MessageFns`\<[`IdentifierToken`](../interfaces/IdentifierToken.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:199](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L199)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/AuthorizedFormat.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / AuthorizedFormat
2 |
3 | # Variable: AuthorizedFormat
4 |
5 | > **AuthorizedFormat**: `MessageFns`\<[`AuthorizedFormat`](../interfaces/AuthorizedFormat.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:209](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L209)
8 |
--------------------------------------------------------------------------------
/examples/onesie-request/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module",
3 | "name": "onesie-request",
4 | "version": "1.0.0",
5 | "description": "",
6 | "main": "main.js",
7 | "module": "main.js",
8 | "scripts": {
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "dependencies": {
15 | "googlevideo": "file:../..",
16 | "youtubei.js": "^16.0.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/MediaHeader.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / MediaHeader
2 |
3 | # Variable: MediaHeader
4 |
5 | > **MediaHeader**: `MessageFns`\<[`MediaHeader`](../interfaces/MediaHeader.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/media\_header.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/media_header.ts#L14)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/ClientInfo.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / ClientInfo
2 |
3 | # Variable: ClientInfo
4 |
5 | > **ClientInfo**: `MessageFns`\<[`ClientInfo`](../interfaces/ClientInfo.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:30](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L30)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/CryptoParams.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / CryptoParams
2 |
3 | # Variable: CryptoParams
4 |
5 | > **CryptoParams**: `MessageFns`\<[`CryptoParams`](../interfaces/CryptoParams.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/crypto\_params.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/crypto_params.ts#L13)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/LiveMetadata.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / LiveMetadata
2 |
3 | # Variable: LiveMetadata
4 |
5 | > **LiveMetadata**: `MessageFns`\<[`LiveMetadata`](../interfaces/LiveMetadata.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/live\_metadata.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/live_metadata.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/OnesieHeader.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / OnesieHeader
2 |
3 | # Variable: OnesieHeader
4 |
5 | > **OnesieHeader**: `MessageFns`\<[`OnesieHeader`](../interfaces/OnesieHeader.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_header.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_header.ts#L14)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/SabrRedirect.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrRedirect
2 |
3 | # Variable: SabrRedirect
4 |
5 | > **SabrRedirect**: `MessageFns`\<[`SabrRedirect`](../interfaces/SabrRedirect.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_redirect.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_redirect.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/BufferedRange.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / BufferedRange
2 |
3 | # Variable: BufferedRange
4 |
5 | > **BufferedRange**: `MessageFns`\<[`BufferedRange`](../interfaces/BufferedRange.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/buffered\_range.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/buffered_range.ts#L14)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/OnesieRequest.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / OnesieRequest
2 |
3 | # Variable: OnesieRequest
4 |
5 | > **OnesieRequest**: `MessageFns`\<[`OnesieRequest`](../interfaces/OnesieRequest.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_request.ts:18](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_request.ts#L18)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/PlaybackAuthorization.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / PlaybackAuthorization
2 |
3 | # Variable: PlaybackAuthorization
4 |
5 | > **PlaybackAuthorization**: `MessageFns`\<[`PlaybackAuthorization`](../interfaces/PlaybackAuthorization.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:214](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L214)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/PlaybackCookie.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / PlaybackCookie
2 |
3 | # Variable: PlaybackCookie
4 |
5 | > **PlaybackCookie**: `MessageFns`\<[`PlaybackCookie`](../interfaces/PlaybackCookie.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_cookie.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_cookie.ts#L13)
8 |
--------------------------------------------------------------------------------
/examples/sabr-shaka-example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "module": "ESNext",
6 | "lib": ["ESNext", "DOM"],
7 | "moduleResolution": "bundler",
8 | "strict": true,
9 | "sourceMap": true,
10 | "resolveJsonModule": true,
11 | "esModuleInterop": true,
12 | "noUnusedLocals": true,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true
15 | },
16 | "include": ["src"]
17 | }
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/ClientAbrState.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / ClientAbrState
2 |
3 | # Variable: ClientAbrState
4 |
5 | > **ClientAbrState**: `MessageFns`\<[`ClientAbrState`](../interfaces/ClientAbrState.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/client\_abr\_state.ts:20](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/client_abr_state.ts#L20)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/UstreamerFlags.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / UstreamerFlags
2 |
3 | # Variable: UstreamerFlags
4 |
5 | > **UstreamerFlags**: `MessageFns`\<[`UstreamerFlags`](../interfaces/UstreamerFlags.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/innertube\_request.ts:27](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/innertube_request.ts#L27)
8 |
--------------------------------------------------------------------------------
/protos/video_streaming/onesie_header_type.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | enum OnesieHeaderType {
5 | ONESIE_PLAYER_RESPONSE = 0;
6 | MEDIA = 1;
7 | MEDIA_DECRYPTION_KEY = 2;
8 | CLEAR_MEDIA = 3;
9 | CLEAR_INIT_SEGMENT = 4;
10 | ACK = 5;
11 | MEDIA_STREAMER_HOSTNAME = 6;
12 | MEDIA_SIZE_HINT = 7;
13 | PLAYER_SERVICE_RESPONSE_PUSH_URL = 8;
14 | LAST_HIGH_PRIORITY_HINT = 9;
15 | STREAM_METADATA = 16;
16 | ENCRYPTED_INNERTUBE_RESPONSE_PART = 25;
17 | }
18 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/SnackbarMessage.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SnackbarMessage
2 |
3 | # Variable: SnackbarMessage
4 |
5 | > **SnackbarMessage**: `MessageFns`\<[`SnackbarMessage`](../interfaces/SnackbarMessage.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/snackbar\_message.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/snackbar_message.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/StreamerContext.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / StreamerContext
2 |
3 | # Variable: StreamerContext
4 |
5 | > **StreamerContext**: `MessageFns`\<[`StreamerContext`](../interfaces/StreamerContext.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/InnertubeRequest.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / InnertubeRequest
2 |
3 | # Variable: InnertubeRequest
4 |
5 | > **InnertubeRequest**: `MessageFns`\<[`InnertubeRequest`](../interfaces/InnertubeRequest.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/innertube\_request.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/innertube_request.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/SabrContextValue.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrContextValue
2 |
3 | # Variable: SabrContextValue
4 |
5 | > **SabrContextValue**: `MessageFns`\<[`SabrContextValue`](../interfaces/SabrContextValue.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:37](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L37)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/MediaCapabilities.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / MediaCapabilities
2 |
3 | # Variable: MediaCapabilities
4 |
5 | > **MediaCapabilities**: `MessageFns`\<[`MediaCapabilities`](../interfaces/MediaCapabilities.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/media\_capabilities.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/media_capabilities.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/NextRequestPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / NextRequestPolicy
2 |
3 | # Variable: NextRequestPolicy
4 |
5 | > **NextRequestPolicy**: `MessageFns`\<[`NextRequestPolicy`](../interfaces/NextRequestPolicy.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L13)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/RequestIdentifier.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / RequestIdentifier
2 |
3 | # Variable: RequestIdentifier
4 |
5 | > **RequestIdentifier**: `MessageFns`\<[`RequestIdentifier`](../interfaces/RequestIdentifier.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_identifier.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_identifier.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/SabrContextUpdate.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrContextUpdate
2 |
3 | # Variable: SabrContextUpdate
4 |
5 | > **SabrContextUpdate**: `MessageFns`\<[`SabrContextUpdate`](../interfaces/SabrContextUpdate.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-stream/README.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../README.md) / exports/sabr-stream
2 |
3 | # exports/sabr-stream
4 |
5 | This module contains a SABR client for downloading videos.
6 |
7 | ## Classes
8 |
9 | - [SabrStream](classes/SabrStream.md)
10 |
11 | ## Interfaces
12 |
13 | - [InitializedFormat](interfaces/InitializedFormat.md)
14 | - [SabrPlaybackOptions](interfaces/SabrPlaybackOptions.md)
15 | - [SabrStreamConfig](interfaces/SabrStreamConfig.md)
16 | - [SabrStreamState](interfaces/SabrStreamState.md)
17 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/functions/u8ToBase64.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / u8ToBase64
2 |
3 | # Function: u8ToBase64()
4 |
5 | > **u8ToBase64**(`u8`): `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:71](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L71)
8 |
9 | Converts a Uint8Array to a Base64 string.
10 |
11 | ## Parameters
12 |
13 | ### u8
14 |
15 | `Uint8Array`
16 |
17 | ## Returns
18 |
19 | `string`
20 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | ## SABR/UMP Player
2 | See [sabr-shaka-example/README.md](./sabr-shaka-example/README.md).
3 |
4 | ## Downloader Example
5 |
6 | ```bash
7 | npm run build # If you haven't built the library yet.
8 | cd examples/downloader
9 | npm install
10 | npx tsx main.ts
11 |
12 | # Example with ffmpeg
13 | npx tsx ffmpeg-example.ts
14 | ```
15 |
16 | ## "Onesie" Request Example
17 |
18 | ```bash
19 | npm run build # If you haven't built the library yet.
20 | cd examples/onesie-request
21 | npm install
22 | npx tsx main.ts
23 | ```
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/PlaybackStartPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / PlaybackStartPolicy
2 |
3 | # Variable: PlaybackStartPolicy
4 |
5 | > **PlaybackStartPolicy**: `MessageFns`\<[`PlaybackStartPolicy`](../interfaces/PlaybackStartPolicy.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_start\_policy.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_start_policy.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/functions/base64ToU8.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / base64ToU8
2 |
3 | # Function: base64ToU8()
4 |
5 | > **base64ToU8**(`base64`): `Uint8Array`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:79](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L79)
8 |
9 | Converts a Base64 string to a Uint8Array.
10 |
11 | ## Parameters
12 |
13 | ### base64
14 |
15 | `string`
16 |
17 | ## Returns
18 |
19 | `Uint8Array`
20 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/ReloadPlaybackParams.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / ReloadPlaybackParams
2 |
3 | # Variable: ReloadPlaybackParams
4 |
5 | > **ReloadPlaybackParams**: `MessageFns`\<[`ReloadPlaybackParams`](../interfaces/ReloadPlaybackParams.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/reload\_player\_response.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/reload_player_response.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/ReloadPlaybackContext.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / ReloadPlaybackContext
2 |
3 | # Variable: ReloadPlaybackContext
4 |
5 | > **ReloadPlaybackContext**: `MessageFns`\<[`ReloadPlaybackContext`](../interfaces/ReloadPlaybackContext.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/reload\_player\_response.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/reload_player_response.ts#L16)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/FormatSelectionConfig.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / FormatSelectionConfig
2 |
3 | # Variable: FormatSelectionConfig
4 |
5 | > **FormatSelectionConfig**: `MessageFns`\<[`FormatSelectionConfig`](../interfaces/FormatSelectionConfig.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/format\_selection\_config.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/format_selection_config.ts#L12)
8 |
--------------------------------------------------------------------------------
/protos/video_streaming/onesie_proxy_status.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | enum OnesieProxyStatus {
5 | UNKNOWN = 0;
6 | OK = 1;
7 | DECRYPTION_FAILED = 2;
8 | PARSING_FAILED = 3;
9 | MISSING_X_FORWARDED_FOR = 4;
10 | INVALID_X_FORWARDED_FOR = 5;
11 | INVALID_CONTENT_TYPE = 6;
12 | BACKEND_ERROR = 7;
13 | CLIENT_ERROR = 8;
14 | MISSING_CRYPTER = 9;
15 | RESPONSE_JSON_SERIALIZATION_FAILED = 10;
16 | DECOMPRESSION_FAILED = 11;
17 | JSON_PARSING_FAILED = 12;
18 | UNKNOWN_COMPRESSION_TYPE = 13;
19 | }
20 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/OnesieInnertubeRequest.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / OnesieInnertubeRequest
2 |
3 | # Variable: OnesieInnertubeRequest
4 |
5 | > **OnesieInnertubeRequest**: `MessageFns`\<[`OnesieInnertubeRequest`](../interfaces/OnesieInnertubeRequest.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_request.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_request.ts#L13)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/StreamProtectionStatus.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / StreamProtectionStatus
2 |
3 | # Variable: StreamProtectionStatus
4 |
5 | > **StreamProtectionStatus**: `MessageFns`\<[`StreamProtectionStatus`](../interfaces/StreamProtectionStatus.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/stream\_protection\_status.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/stream_protection_status.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/OnesieInnertubeResponse.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / OnesieInnertubeResponse
2 |
3 | # Variable: OnesieInnertubeResponse
4 |
5 | > **OnesieInnertubeResponse**: `MessageFns`\<[`OnesieInnertubeResponse`](../interfaces/OnesieInnertubeResponse.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_response.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_response.ts#L14)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/VideoPlaybackAbrRequest.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / VideoPlaybackAbrRequest
2 |
3 | # Variable: VideoPlaybackAbrRequest
4 |
5 | > **VideoPlaybackAbrRequest**: `MessageFns`\<[`VideoPlaybackAbrRequest`](../interfaces/VideoPlaybackAbrRequest.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/video\_playback\_abr\_request.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/video_playback_abr_request.ts#L17)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/SabrContextSendingPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrContextSendingPolicy
2 |
3 | # Variable: SabrContextSendingPolicy
4 |
5 | > **SabrContextSendingPolicy**: `MessageFns`\<[`SabrContextSendingPolicy`](../interfaces/SabrContextSendingPolicy.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_sending\_policy.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_sending_policy.ts#L12)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/RequestCancellationPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / RequestCancellationPolicy
2 |
3 | # Variable: RequestCancellationPolicy
4 |
5 | > **RequestCancellationPolicy**: `MessageFns`\<[`RequestCancellationPolicy`](../interfaces/RequestCancellationPolicy.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_cancellation\_policy.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_cancellation_policy.ts#L12)
8 |
--------------------------------------------------------------------------------
/examples/sabr-shaka-example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sabr-shaka-example",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "tsc && vite build",
8 | "patch:shaka": "node ./scripts/patchShaka.mjs",
9 | "postinstall": "npm run patch:shaka"
10 | },
11 | "dependencies": {
12 | "bgutils-js": "^3.2.0",
13 | "googlevideo": "^4.0.4",
14 | "shaka-player": "^4.16.2",
15 | "youtubei.js": "^16.0.0"
16 | },
17 | "devDependencies": {
18 | "typescript": "^5.4.5",
19 | "vite": "^7.1.11"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/release-please-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": {
3 | ".": {
4 | "changelog-path": "CHANGELOG.md",
5 | "release-type": "node",
6 | "bump-minor-pre-major": false,
7 | "bump-patch-for-minor-pre-major": false,
8 | "draft": false,
9 | "prerelease": false,
10 | "extra-files": [
11 | {
12 | "type": "json",
13 | "path": "jsr.json",
14 | "jsonpath": "$.version"
15 | }
16 | ]
17 | }
18 | },
19 | "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
20 | }
--------------------------------------------------------------------------------
/protos/video_streaming/format_initialization_metadata.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 |
6 | message FormatInitializationMetadata {
7 | optional string video_id = 1;
8 | optional .misc.FormatId format_id = 2;
9 | optional int64 end_time_ms = 3;
10 | optional int64 end_segment_number = 4;
11 | optional string mime_type = 5;
12 | optional .misc.Range init_range = 6;
13 | optional .misc.Range index_range = 7;
14 | optional int64 field8 = 8;
15 | optional int64 duration_units = 9;
16 | optional int64 duration_timescale = 10;
17 | }
--------------------------------------------------------------------------------
/protos/video_streaming/next_request_policy.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "video_streaming/playback_cookie.proto";
5 |
6 | message NextRequestPolicy {
7 | optional int32 target_audio_readahead_ms = 1;
8 | optional int32 target_video_readahead_ms = 2;
9 | optional int32 max_time_since_last_request_ms = 3;
10 | optional int32 backoff_time_ms = 4;
11 | optional int32 min_audio_readahead_ms = 5;
12 | optional int32 min_video_readahead_ms = 6;
13 | optional .video_streaming.PlaybackCookie playback_cookie = 7;
14 | optional string video_id = 8;
15 | }
16 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/functions/wait.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / wait
2 |
3 | # Function: wait()
4 |
5 | > **wait**(`ms`): `Promise`\<`void`\>
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:136](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L136)
8 |
9 | Returns a promise that resolves after a specified number of milliseconds.
10 |
11 | ## Parameters
12 |
13 | ### ms
14 |
15 | `number`
16 |
17 | The number of milliseconds to wait.
18 |
19 | ## Returns
20 |
21 | `Promise`\<`void`\>
22 |
--------------------------------------------------------------------------------
/protos/video_streaming/live_metadata.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message LiveMetadata {
5 | optional string broadcast_id = 1;
6 | optional int64 head_sequence_number = 3;
7 | optional int64 head_time_ms = 4;
8 | optional int64 wall_time_ms = 5;
9 | optional string video_id = 6;
10 | optional bool post_live_dvr = 8;
11 | optional int64 headm = 10;
12 | optional int64 min_seekable_time_ticks = 12;
13 | optional int32 min_seekable_timescale = 13;
14 | optional int64 max_seekable_time_ticks = 14;
15 | optional int32 max_seekable_timescale = 15;
16 | }
17 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/variables/FormatInitializationMetadata.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / FormatInitializationMetadata
2 |
3 | # Variable: FormatInitializationMetadata
4 |
5 | > **FormatInitializationMetadata**: `MessageFns`\<[`FormatInitializationMetadata`](../interfaces/FormatInitializationMetadata.md)\>
6 |
7 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/format\_initialization\_metadata.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/format_initialization_metadata.ts#L13)
8 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/functions/concatenateChunks.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / concatenateChunks
2 |
3 | # Function: concatenateChunks()
4 |
5 | > **concatenateChunks**(`chunks`): `Uint8Array`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:89](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L89)
8 |
9 | Concatenates multiple Uint8Array chunks into a single Uint8Array.
10 |
11 | ## Parameters
12 |
13 | ### chunks
14 |
15 | `Uint8Array`\<`ArrayBufferLike`\>[]
16 |
17 | ## Returns
18 |
19 | `Uint8Array`
20 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/README.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../README.md) / [exports/utils](../../README.md) / FormatKeyUtils
2 |
3 | # FormatKeyUtils
4 |
5 | ## Functions
6 |
7 | - [createKey](functions/createKey.md)
8 | - [createSegmentCacheKey](functions/createSegmentCacheKey.md)
9 | - [createSegmentCacheKeyFromMetadata](functions/createSegmentCacheKeyFromMetadata.md)
10 | - [fromFormat](functions/fromFormat.md)
11 | - [fromFormatInitializationMetadata](functions/fromFormatInitializationMetadata.md)
12 | - [fromMediaHeader](functions/fromMediaHeader.md)
13 | - [getUniqueFormatId](functions/getUniqueFormatId.md)
14 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/functions/parseRangeHeader.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / parseRangeHeader
2 |
3 | # Function: parseRangeHeader()
4 |
5 | > **parseRangeHeader**(`rangeHeaderValue`): `undefined` \| `Range`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:54](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L54)
8 |
9 | Parses the Range header value to extract the start and end byte positions.
10 |
11 | ## Parameters
12 |
13 | ### rangeHeaderValue
14 |
15 | `undefined` | `string`
16 |
17 | ## Returns
18 |
19 | `undefined` \| `Range`
20 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/SabrRedirect.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrRedirect
2 |
3 | # Interface: SabrRedirect
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_redirect.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_redirect.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### url?
10 |
11 | > `optional` **url**: `string`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_redirect.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_redirect.ts#L13)
14 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/functions/createKey.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../../README.md) / [exports/utils](../../../README.md) / [FormatKeyUtils](../README.md) / createKey
2 |
3 | # Function: createKey()
4 |
5 | > **createKey**(`itag`, `xtags`): `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/formatKeyUtils.ts:10](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/formatKeyUtils.ts#L10)
8 |
9 | Creates a format key based on itag and xtags.
10 |
11 | ## Parameters
12 |
13 | ### itag
14 |
15 | `undefined` | `number`
16 |
17 | ### xtags
18 |
19 | `undefined` | `string`
20 |
21 | ## Returns
22 |
23 | `string`
24 |
25 | A string format key.
26 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/SnackbarMessage.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SnackbarMessage
2 |
3 | # Interface: SnackbarMessage
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/snackbar\_message.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/snackbar_message.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### id?
10 |
11 | > `optional` **id**: `number`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/snackbar\_message.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/snackbar_message.ts#L13)
14 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/functions/fromMediaHeader.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../../README.md) / [exports/utils](../../../README.md) / [FormatKeyUtils](../README.md) / fromMediaHeader
2 |
3 | # Function: fromMediaHeader()
4 |
5 | > **fromMediaHeader**(`mediaHeader`): `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/formatKeyUtils.ts:27](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/formatKeyUtils.ts#L27)
8 |
9 | Creates a format key from a MediaHeader object.
10 |
11 | ## Parameters
12 |
13 | ### mediaHeader
14 |
15 | [`MediaHeader`](../../../../protos/interfaces/MediaHeader.md)
16 |
17 | ## Returns
18 |
19 | `string`
20 |
21 | A string format key.
22 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/functions/buildSabrFormat.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / buildSabrFormat
2 |
3 | # Function: buildSabrFormat()
4 |
5 | > **buildSabrFormat**(`formatStream`): [`SabrFormat`](../../../types/shared/interfaces/SabrFormat.md)
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:104](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L104)
8 |
9 | Converts a FormatStream object to a SabrFormat object.
10 |
11 | ## Parameters
12 |
13 | ### formatStream
14 |
15 | [`FormatStream`](../../../types/shared/interfaces/FormatStream.md)
16 |
17 | ## Returns
18 |
19 | [`SabrFormat`](../../../types/shared/interfaces/SabrFormat.md)
20 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/RequestIdentifier.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / RequestIdentifier
2 |
3 | # Interface: RequestIdentifier
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_identifier.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_identifier.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### token?
10 |
11 | > `optional` **token**: `string`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_identifier.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_identifier.ts#L13)
14 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: lint
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | lint:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v3
14 | - uses: actions/setup-node@v3
15 | with:
16 | node-version: 20
17 | - name: Install protoc
18 | run: |
19 | sudo apt-get update
20 | sudo apt-get install -y unzip
21 | curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protoc-21.12-linux-x86_64.zip
22 | unzip protoc-21.12-linux-x86_64.zip -d protoc21
23 | sudo mv protoc21/bin/protoc /usr/local/bin/
24 | - run: npm ci
25 | - run: npm run lint
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/ReloadPlaybackParams.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / ReloadPlaybackParams
2 |
3 | # Interface: ReloadPlaybackParams
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/reload\_player\_response.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/reload_player_response.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### token?
10 |
11 | > `optional` **token**: `string`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/reload\_player\_response.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/reload_player_response.ts#L13)
14 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/UstreamerFlags.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / UstreamerFlags
2 |
3 | # Interface: UstreamerFlags
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/innertube\_request.ts:27](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/innertube_request.ts#L27)
6 |
7 | ## Properties
8 |
9 | ### sendVideoPlaybackConfig?
10 |
11 | > `optional` **sendVideoPlaybackConfig**: `boolean`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/innertube\_request.ts:28](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/innertube_request.ts#L28)
14 |
--------------------------------------------------------------------------------
/jsr.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@luanrt/googlevideo",
3 | "version": "4.0.4",
4 | "exports": {
5 | "./ump": "./src/exports/ump.ts",
6 | "./sabr-streaming-adapter": "./src/exports/sabr-streaming-adapter.ts",
7 | "./sabr-stream": "./src/exports/sabr-stream.ts",
8 | "./protos": "./src/exports/protos.ts",
9 | "./utils": "./src/exports/utils.ts",
10 | "./shared-types": "./src/types/shared.ts"
11 | },
12 | "imports": {
13 | "@bufbuild/protobuf": "npm:@bufbuild/protobuf@^2.0.0"
14 | },
15 | "publish": {
16 | "include": [
17 | "LICENSE",
18 | "README.md",
19 | "protos/generated/**/*.ts",
20 | "src/**/*.ts"
21 | ],
22 | "exclude": [
23 | "tests",
24 | "dev-scripts",
25 | "examples"
26 | ]
27 | }
28 | }
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/functions/fromFormat.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../../README.md) / [exports/utils](../../../README.md) / [FormatKeyUtils](../README.md) / fromFormat
2 |
3 | # Function: fromFormat()
4 |
5 | > **fromFormat**(`format?`): `undefined` \| `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/formatKeyUtils.ts:18](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/formatKeyUtils.ts#L18)
8 |
9 | Creates a format key from a SabrFormat object.
10 |
11 | ## Parameters
12 |
13 | ### format?
14 |
15 | #### itag?
16 |
17 | `number`
18 |
19 | #### xtags?
20 |
21 | `string`
22 |
23 | ## Returns
24 |
25 | `undefined` \| `string`
26 |
27 | A string format key or undefined if format is undefined.
28 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/onesie_header_type.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/onesie_header_type.proto
6 |
7 | /* eslint-disable */
8 |
9 | export const protobufPackage = "video_streaming";
10 |
11 | export enum OnesieHeaderType {
12 | ONESIE_PLAYER_RESPONSE = 0,
13 | MEDIA = 1,
14 | MEDIA_DECRYPTION_KEY = 2,
15 | CLEAR_MEDIA = 3,
16 | CLEAR_INIT_SEGMENT = 4,
17 | ACK = 5,
18 | MEDIA_STREAMER_HOSTNAME = 6,
19 | MEDIA_SIZE_HINT = 7,
20 | PLAYER_SERVICE_RESPONSE_PUSH_URL = 8,
21 | LAST_HIGH_PRIORITY_HINT = 9,
22 | STREAM_METADATA = 16,
23 | ENCRYPTED_INNERTUBE_RESPONSE_PART = 25,
24 | UNRECOGNIZED = -1,
25 | }
26 |
--------------------------------------------------------------------------------
/protos/video_streaming/innertube_request.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message InnertubeRequest {
5 | optional bytes context = 1;
6 | optional bytes encrypted_onesie_innertube_request = 2;
7 | optional bytes encrypted_client_key = 5;
8 | optional bytes iv = 6;
9 | optional bytes hmac = 7;
10 | optional string reverse_proxy_config = 9;
11 | optional bool serialize_response_as_json = 10;
12 | optional bool enable_ad_placements_preroll = 13;
13 | optional bool enable_compression = 14;
14 | optional UstreamerFlags ustreamer_flags = 15;
15 | optional bytes unencrypted_onesie_innertube_request = 16;
16 | optional bool use_jsonformatter_to_parse_player_response = 17;
17 | }
18 |
19 | message UstreamerFlags {
20 | optional bool send_video_playback_config = 2;
21 | }
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/functions/getUniqueFormatId.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../../README.md) / [exports/utils](../../../README.md) / [FormatKeyUtils](../README.md) / getUniqueFormatId
2 |
3 | # Function: getUniqueFormatId()
4 |
5 | > **getUniqueFormatId**(`format`): `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/formatKeyUtils.ts:85](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/formatKeyUtils.ts#L85)
8 |
9 | Generates a unique format ID based on the SabrFormat properties.
10 |
11 | ## Parameters
12 |
13 | ### format
14 |
15 | [`SabrFormat`](../../../../../types/shared/interfaces/SabrFormat.md)
16 |
17 | The SabrFormat object.
18 |
19 | ## Returns
20 |
21 | `string`
22 |
23 | A unique string identifier for the format.
24 |
--------------------------------------------------------------------------------
/examples/downloader/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "downloader",
3 | "version": "1.0.0",
4 | "description": "",
5 | "type": "module",
6 | "module": "main.js",
7 | "main": "main.js",
8 | "scripts": {
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "dependencies": {
15 | "bgutils-js": "^3.1.0",
16 | "cli-progress": "^3.12.0",
17 | "fluent-ffmpeg": "^2.1.3",
18 | "googlevideo": "file:../..",
19 | "jsdom": "^25.0.1",
20 | "shaka-player": "^4.11.2",
21 | "youtubei.js": "^16.0.0"
22 | },
23 | "devDependencies": {
24 | "@types/cli-progress": "^3.11.6",
25 | "@types/fluent-ffmpeg": "^2.1.26",
26 | "@types/jsdom": "^21.1.7",
27 | "typescript": "^5.6.2"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/onesie_proxy_status.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/onesie_proxy_status.proto
6 |
7 | /* eslint-disable */
8 |
9 | export const protobufPackage = "video_streaming";
10 |
11 | export enum OnesieProxyStatus {
12 | UNKNOWN = 0,
13 | OK = 1,
14 | DECRYPTION_FAILED = 2,
15 | PARSING_FAILED = 3,
16 | MISSING_X_FORWARDED_FOR = 4,
17 | INVALID_X_FORWARDED_FOR = 5,
18 | INVALID_CONTENT_TYPE = 6,
19 | BACKEND_ERROR = 7,
20 | CLIENT_ERROR = 8,
21 | MISSING_CRYPTER = 9,
22 | RESPONSE_JSON_SERIALIZATION_FAILED = 10,
23 | DECOMPRESSION_FAILED = 11,
24 | JSON_PARSING_FAILED = 12,
25 | UNKNOWN_COMPRESSION_TYPE = 13,
26 | UNRECOGNIZED = -1,
27 | }
28 |
--------------------------------------------------------------------------------
/protos/video_streaming/media_header.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 | import "video_streaming/time_range.proto";
6 |
7 | message MediaHeader {
8 | optional uint32 header_id = 1;
9 | optional string video_id = 2;
10 | optional int32 itag = 3;
11 | optional uint64 lmt = 4;
12 | optional string xtags = 5;
13 | optional int64 start_range = 6;
14 | optional .misc.CompressionType compression_algorithm = 7;
15 | optional bool is_init_seg = 8;
16 | optional int32 sequence_number = 9;
17 | optional int64 bitrate_bps = 10;
18 | optional int64 start_ms = 11;
19 | optional int64 duration_ms = 12;
20 | optional .misc.FormatId format_id = 13;
21 | optional int64 content_length = 14;
22 | optional TimeRange time_range = 15;
23 | optional uint64 sequence_lmt = 16;
24 | }
25 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/ReloadPlaybackContext.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / ReloadPlaybackContext
2 |
3 | # Interface: ReloadPlaybackContext
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/reload\_player\_response.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/reload_player_response.ts#L16)
6 |
7 | ## Properties
8 |
9 | ### reloadPlaybackParams?
10 |
11 | > `optional` **reloadPlaybackParams**: [`ReloadPlaybackParams`](ReloadPlaybackParams.md)
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/reload\_player\_response.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/reload_player_response.ts#L17)
14 |
--------------------------------------------------------------------------------
/protos/video_streaming/media_capabilities.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message MediaCapabilities {
5 | repeated VideoFormatCapability video_format_capabilities = 1;
6 | repeated AudioFormatCapability audio_format_capabilities = 2;
7 | optional int32 hdr_mode_bitmask = 5;
8 |
9 | message VideoFormatCapability {
10 | optional int32 video_codec = 1;
11 | optional int32 max_height = 3;
12 | optional int32 max_width = 4;
13 | optional int32 max_framerate = 11;
14 | optional int32 max_bitrate_bps = 12;
15 | optional bool is_10_bit_supported = 15;
16 | }
17 |
18 | message AudioFormatCapability {
19 | optional int32 audio_codec = 1;
20 | optional int32 num_channels = 2;
21 | optional int32 max_bitrate_bps = 3;
22 | optional int32 spatial_capability_bitmask = 6;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/functions/createSegmentCacheKeyFromMetadata.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../../README.md) / [exports/utils](../../../README.md) / [FormatKeyUtils](../README.md) / createSegmentCacheKeyFromMetadata
2 |
3 | # Function: createSegmentCacheKeyFromMetadata()
4 |
5 | > **createSegmentCacheKeyFromMetadata**(`requestMetadata`): `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/formatKeyUtils.ts:61](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/formatKeyUtils.ts#L61)
8 |
9 | Creates a cache key from request metadata.
10 |
11 | ## Parameters
12 |
13 | ### requestMetadata
14 |
15 | [`SabrRequestMetadata`](../../../../sabr-streaming-adapter/interfaces/SabrRequestMetadata.md)
16 |
17 | ## Returns
18 |
19 | `string`
20 |
21 | A string key for caching segments.
22 |
--------------------------------------------------------------------------------
/protos/video_streaming/onesie_header.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "video_streaming/crypto_params.proto";
5 | import "video_streaming/onesie_header_type.proto";
6 |
7 | message OnesieHeader {
8 | message UnknownMessage1 {
9 | optional string video_id = 2;
10 | }
11 |
12 | message UnknownMessage2 {
13 | repeated string itag_denylist = 1;
14 | }
15 |
16 | optional OnesieHeaderType type = 1;
17 | optional string video_id = 2;
18 | optional string itag = 3;
19 | optional CryptoParams crypto_params = 4;
20 | optional uint64 last_modified = 5;
21 | optional int64 expected_media_size_bytes = 7;
22 | repeated string restricted_formats = 11;
23 | optional string xtags = 15;
24 | optional int64 sequence_number = 18;
25 | optional UnknownMessage1 field23 = 23;
26 | optional UnknownMessage2 field34 = 34;
27 | }
28 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/functions/fromFormatInitializationMetadata.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../../README.md) / [exports/utils](../../../README.md) / [FormatKeyUtils](../README.md) / fromFormatInitializationMetadata
2 |
3 | # Function: fromFormatInitializationMetadata()
4 |
5 | > **fromFormatInitializationMetadata**(`formatInitMetadata`): `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/formatKeyUtils.ts:35](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/formatKeyUtils.ts#L35)
8 |
9 | Creates a format key from FormatInitializationMetadata.
10 |
11 | ## Parameters
12 |
13 | ### formatInitMetadata
14 |
15 | [`FormatInitializationMetadata`](../../../../protos/interfaces/FormatInitializationMetadata.md)
16 |
17 | ## Returns
18 |
19 | `string`
20 |
21 | A string format key or undefined if formatId is undefined.
22 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/HttpHeader.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / HttpHeader
2 |
3 | # Interface: HttpHeader
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:181](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L181)
6 |
7 | ## Properties
8 |
9 | ### name?
10 |
11 | > `optional` **name**: `string`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:182](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L182)
14 |
15 | ***
16 |
17 | ### value?
18 |
19 | > `optional` **value**: `string`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:183](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L183)
22 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/type-aliases/RequestFilter.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / RequestFilter
2 |
3 | # Type Alias: RequestFilter()
4 |
5 | > **RequestFilter** = (`request`) => `Promise`\<[`PlayerHttpRequest`](../interfaces/PlayerHttpRequest.md) \| `undefined`\> \| [`PlayerHttpRequest`](../interfaces/PlayerHttpRequest.md) \| `undefined`
6 |
7 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:96](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L96)
8 |
9 | ## Parameters
10 |
11 | ### request
12 |
13 | [`PlayerHttpRequest`](../interfaces/PlayerHttpRequest.md)
14 |
15 | ## Returns
16 |
17 | `Promise`\<[`PlayerHttpRequest`](../interfaces/PlayerHttpRequest.md) \| `undefined`\> \| [`PlayerHttpRequest`](../interfaces/PlayerHttpRequest.md) \| `undefined`
18 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/KeyValuePair.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / KeyValuePair
2 |
3 | # Interface: KeyValuePair
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:204](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L204)
6 |
7 | ## Properties
8 |
9 | ### key?
10 |
11 | > `optional` **key**: `string`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:205](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L205)
14 |
15 | ***
16 |
17 | ### value?
18 |
19 | > `optional` **value**: `string`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:206](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L206)
22 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/type-aliases/ResponseFilter.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / ResponseFilter
2 |
3 | # Type Alias: ResponseFilter()
4 |
5 | > **ResponseFilter** = (`response`) => `Promise`\<[`PlayerHttpResponse`](../interfaces/PlayerHttpResponse.md) \| `undefined`\> \| [`PlayerHttpResponse`](../interfaces/PlayerHttpResponse.md) \| `undefined`
6 |
7 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:97](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L97)
8 |
9 | ## Parameters
10 |
11 | ### response
12 |
13 | [`PlayerHttpResponse`](../interfaces/PlayerHttpResponse.md)
14 |
15 | ## Returns
16 |
17 | `Promise`\<[`PlayerHttpResponse`](../interfaces/PlayerHttpResponse.md) \| `undefined`\> \| [`PlayerHttpResponse`](../interfaces/PlayerHttpResponse.md) \| `undefined`
18 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/AuthorizedFormat.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / AuthorizedFormat
2 |
3 | # Interface: AuthorizedFormat
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:209](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L209)
6 |
7 | ## Properties
8 |
9 | ### isHdr?
10 |
11 | > `optional` **isHdr**: `boolean`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:211](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L211)
14 |
15 | ***
16 |
17 | ### trackType?
18 |
19 | > `optional` **trackType**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:210](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L210)
22 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/IdentifierToken.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / IdentifierToken
2 |
3 | # Interface: IdentifierToken
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:199](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L199)
6 |
7 | ## Properties
8 |
9 | ### field5?
10 |
11 | > `optional` **field5**: `number`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:201](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L201)
14 |
15 | ***
16 |
17 | ### requestNumber?
18 |
19 | > `optional` **requestNumber**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:200](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L200)
22 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/namespaces/FormatKeyUtils/functions/createSegmentCacheKey.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../../../README.md) / [exports/utils](../../../README.md) / [FormatKeyUtils](../README.md) / createSegmentCacheKey
2 |
3 | # Function: createSegmentCacheKey()
4 |
5 | > **createSegmentCacheKey**(`mediaHeader`, `format?`): `string`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/formatKeyUtils.ts:47](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/formatKeyUtils.ts#L47)
8 |
9 | Creates a segment cache key.
10 |
11 | ## Parameters
12 |
13 | ### mediaHeader
14 |
15 | [`MediaHeader`](../../../../protos/interfaces/MediaHeader.md)
16 |
17 | The MediaHeader object.
18 |
19 | ### format?
20 |
21 | [`SabrFormat`](../../../../../types/shared/interfaces/SabrFormat.md)
22 |
23 | Format object (needed for init segments.)
24 |
25 | ## Returns
26 |
27 | `string`
28 |
29 | A string key for caching segments.
30 |
--------------------------------------------------------------------------------
/protos/video_streaming/onesie_request.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 | import "video_streaming/buffered_range.proto";
6 | import "video_streaming/client_abr_state.proto";
7 | import "video_streaming/innertube_request.proto";
8 | import "video_streaming/streamer_context.proto";
9 | import "video_streaming/reload_player_response.proto";
10 |
11 | message OnesieRequest {
12 | repeated string urls = 1;
13 | optional ClientAbrState client_abr_state = 2;
14 | optional InnertubeRequest innertube_request = 3;
15 | optional bytes onesie_ustreamer_config = 4;
16 | optional int32 max_vp9_height = 5;
17 | optional int32 client_display_height = 6;
18 | optional StreamerContext streamer_context = 10;
19 | optional .misc.OnesieRequestTarget request_target = 13; // MLOnesieRequestTarget
20 | repeated BufferedRange buffered_ranges = 14;
21 | optional ReloadPlaybackParams reload_playback_params = 15;
22 | }
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/interfaces/UmpProcessingResult.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / UmpProcessingResult
2 |
3 | # Interface: UmpProcessingResult
4 |
5 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:33](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L33)
6 |
7 | ## Properties
8 |
9 | ### data?
10 |
11 | > `optional` **data**: `Uint8Array`\<`ArrayBufferLike`\>
12 |
13 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:34](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L34)
14 |
15 | ***
16 |
17 | ### done
18 |
19 | > **done**: `boolean`
20 |
21 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:35](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L35)
22 |
--------------------------------------------------------------------------------
/protos/video_streaming/buffered_range.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 | import "video_streaming/time_range.proto";
6 |
7 | message BufferedRange {
8 | message UnknownMessage1 {
9 | message UnknownInnerMessage {
10 | optional string video_id = 1;
11 | optional uint64 lmt = 2;
12 | }
13 | repeated UnknownInnerMessage field1 = 1;
14 | }
15 |
16 | message UnknownMessage2 {
17 | optional int32 field1 = 1;
18 | optional int32 field2 = 2;
19 | optional int32 field3 = 3;
20 | }
21 |
22 | required .misc.FormatId format_id = 1;
23 | required int64 start_time_ms = 2;
24 | required int64 duration_ms = 3;
25 | required int32 start_segment_index = 4;
26 | required int32 end_segment_index = 5;
27 | optional TimeRange time_range = 6;
28 | optional UnknownMessage1 field9 = 9;
29 | optional UnknownMessage2 field11 = 11;
30 | optional UnknownMessage2 field12 = 12;
31 | }
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/SabrError.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrError
2 |
3 | # Interface: SabrError
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_error.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_error.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### code?
10 |
11 | > `optional` **code**: `number`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_error.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_error.ts#L14)
14 |
15 | ***
16 |
17 | ### type?
18 |
19 | > `optional` **type**: `string`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_error.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_error.ts#L13)
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.yml:
--------------------------------------------------------------------------------
1 | name: Question
2 | description: Use this template to ask a question about the project
3 | labels: [question]
4 | body:
5 |
6 | - type: textarea
7 | id: question
8 | attributes:
9 | label: Question
10 | placeholder: What do you want to know?
11 | validations:
12 | required: true
13 |
14 | - type: textarea
15 | id: other-details
16 | attributes:
17 | label: Other details
18 | placeholder: |
19 | Additional details and attachments.
20 |
21 | - type: checkboxes
22 | id: checklist
23 | attributes:
24 | label: Checklist
25 | options:
26 | - label: I am running the latest version.
27 | required: true
28 | - label: I checked the documentation and found no answer.
29 | required: true
30 | - label: I have searched the existing issues and made sure this is not a duplicate.
31 | required: true
32 | - label: I have provided sufficient information.
33 | required: true
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature.yml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | description: Use this template to suggest new features
3 | labels: [enhancement]
4 | body:
5 |
6 | - type: textarea
7 | id: feature-description
8 | attributes:
9 | label: Describe your suggestion
10 | placeholder: How would it work?
11 | validations:
12 | required: true
13 |
14 | - type: textarea
15 | id: other-details
16 | attributes:
17 | label: Other details
18 | placeholder: |
19 | Additional details and attachments.
20 |
21 | - type: checkboxes
22 | id: checklist
23 | attributes:
24 | label: Checklist
25 | options:
26 | - label: I am running the latest version.
27 | required: true
28 | - label: I checked the documentation and found no answer.
29 | required: true
30 | - label: I have searched the existing issues and made sure this is not a duplicate.
31 | required: true
32 | - label: I have provided sufficient information.
33 | required: true
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/PlaybackAuthorization.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / PlaybackAuthorization
2 |
3 | # Interface: PlaybackAuthorization
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:214](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L214)
6 |
7 | ## Properties
8 |
9 | ### authorizedFormats
10 |
11 | > **authorizedFormats**: [`AuthorizedFormat`](AuthorizedFormat.md)[]
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:215](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L215)
14 |
15 | ***
16 |
17 | ### sabrLicenseConstraint?
18 |
19 | > `optional` **sabrLicenseConstraint**: `Uint8Array`\<`ArrayBufferLike`\>
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:216](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L216)
22 |
--------------------------------------------------------------------------------
/examples/sabr-shaka-example/scripts/patchShaka.mjs:
--------------------------------------------------------------------------------
1 | import { readFile, appendFile } from 'node:fs/promises';
2 | import path from 'node:path';
3 | import * as url from 'node:url';
4 |
5 | const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
6 |
7 | async function main() {
8 | const fileNames = [ 'shaka-player.ui.d.ts', 'shaka-player.ui.debug.d.ts' ];
9 |
10 | for (const filename of fileNames) {
11 | await fixTypes(filename);
12 | }
13 | }
14 |
15 | async function fixTypes(filename) {
16 | const filePath = path.join(__dirname, '..', 'node_modules', 'shaka-player', 'dist', filename);
17 |
18 | const shakaTs = await readFile(filePath, 'utf-8');
19 |
20 | if (!shakaTs.includes('export default shaka')) {
21 | await appendFile(filePath, 'export default shaka;');
22 | console.log(`[PatchShaka] Fixed types in ${filename}`);
23 | } else {
24 | console.log(`[PatchShaka] No changes needed in ${filename}`);
25 | }
26 | }
27 |
28 | main().catch(() => {
29 | console.error('[PatchShaka]', 'Failed to patch shaka-player');
30 | });
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 LuanRT
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Run Tests
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | test:
11 | runs-on: ubuntu-latest
12 |
13 | strategy:
14 | matrix:
15 | node-version: [20.x]
16 |
17 | steps:
18 | - name: Checkout repository
19 | uses: actions/checkout@v4
20 |
21 | - name: Use Node.js ${{ matrix.node-version }}
22 | uses: actions/setup-node@v4
23 | with:
24 | node-version: ${{ matrix.node-version }}
25 | cache: 'npm'
26 |
27 | - name: Install protoc
28 | run: |
29 | sudo apt-get update
30 | sudo apt-get install -y unzip
31 | curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protoc-21.12-linux-x86_64.zip
32 | unzip protoc-21.12-linux-x86_64.zip -d protoc21
33 | sudo mv protoc21/bin/protoc /usr/local/bin/
34 |
35 | - name: Install dependencies
36 | run: npm install
37 |
38 | - name: Run tests
39 | run: npm test
40 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/README.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../README.md) / exports/sabr-streaming-adapter
2 |
3 | # exports/sabr-streaming-adapter
4 |
5 | This module contains the core classes, types, and utilities required to integrate YouTube's SABR streaming protocol
6 | into a media player.
7 |
8 | ## Classes
9 |
10 | - [SabrStreamingAdapter](classes/SabrStreamingAdapter.md)
11 | - [SabrUmpProcessor](classes/SabrUmpProcessor.md)
12 |
13 | ## Interfaces
14 |
15 | - [PlayerHttpRequest](interfaces/PlayerHttpRequest.md)
16 | - [PlayerHttpResponse](interfaces/PlayerHttpResponse.md)
17 | - [RequestSegment](interfaces/RequestSegment.md)
18 | - [SabrOptions](interfaces/SabrOptions.md)
19 | - [SabrPlayerAdapter](interfaces/SabrPlayerAdapter.md)
20 | - [SabrRequestMetadata](interfaces/SabrRequestMetadata.md)
21 | - [UmpProcessingResult](interfaces/UmpProcessingResult.md)
22 |
23 | ## Type Aliases
24 |
25 | - [RequestFilter](type-aliases/RequestFilter.md)
26 | - [ResponseFilter](type-aliases/ResponseFilter.md)
27 |
28 | ## Variables
29 |
30 | - [SABR\_CONSTANTS](variables/SABR_CONSTANTS.md)
31 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/interfaces/CacheEntry.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / CacheEntry
2 |
3 | # Interface: CacheEntry
4 |
5 | Defined in: [codeberg/googlevideo/src/utils/CacheManager.ts:3](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/CacheManager.ts#L3)
6 |
7 | ## Properties
8 |
9 | ### data
10 |
11 | > **data**: `Uint8Array`
12 |
13 | Defined in: [codeberg/googlevideo/src/utils/CacheManager.ts:4](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/CacheManager.ts#L4)
14 |
15 | ***
16 |
17 | ### size
18 |
19 | > **size**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/src/utils/CacheManager.ts:6](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/CacheManager.ts#L6)
22 |
23 | ***
24 |
25 | ### timestamp
26 |
27 | > **timestamp**: `number`
28 |
29 | Defined in: [codeberg/googlevideo/src/utils/CacheManager.ts:5](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/CacheManager.ts#L5)
30 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/interfaces/RequestSegment.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / RequestSegment
2 |
3 | # Interface: RequestSegment
4 |
5 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:91](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L91)
6 |
7 | ## Properties
8 |
9 | ### getStartTime()
10 |
11 | > **getStartTime**: () => `null` \| `number`
12 |
13 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:92](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L92)
14 |
15 | #### Returns
16 |
17 | `null` \| `number`
18 |
19 | ***
20 |
21 | ### isInit()
22 |
23 | > **isInit**: () => `boolean`
24 |
25 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:93](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L93)
26 |
27 | #### Returns
28 |
29 | `boolean`
30 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/enumerations/EnabledTrackTypes.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / EnabledTrackTypes
2 |
3 | # Enumeration: EnabledTrackTypes
4 |
5 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:5](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L5)
6 |
7 | ## Enumeration Members
8 |
9 | ### AUDIO\_ONLY
10 |
11 | > **AUDIO\_ONLY**: `1`
12 |
13 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:7](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L7)
14 |
15 | ***
16 |
17 | ### VIDEO\_AND\_AUDIO
18 |
19 | > **VIDEO\_AND\_AUDIO**: `0`
20 |
21 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:6](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L6)
22 |
23 | ***
24 |
25 | ### VIDEO\_ONLY
26 |
27 | > **VIDEO\_ONLY**: `2`
28 |
29 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:8](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L8)
30 |
--------------------------------------------------------------------------------
/docs/api/types/shared/type-aliases/Part.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [types/shared](../README.md) / Part
2 |
3 | # Type Alias: Part
4 |
5 | > **Part** = `object`
6 |
7 | Defined in: [codeberg/googlevideo/src/types/shared.ts:8](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/shared.ts#L8)
8 |
9 | ## Properties
10 |
11 | ### data
12 |
13 | > **data**: [`CompositeBuffer`](../../../exports/ump/classes/CompositeBuffer.md)
14 |
15 | Defined in: [codeberg/googlevideo/src/types/shared.ts:11](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/shared.ts#L11)
16 |
17 | ***
18 |
19 | ### size
20 |
21 | > **size**: `number`
22 |
23 | Defined in: [codeberg/googlevideo/src/types/shared.ts:10](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/shared.ts#L10)
24 |
25 | ***
26 |
27 | ### type
28 |
29 | > **type**: `number`
30 |
31 | Defined in: [codeberg/googlevideo/src/types/shared.ts:9](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/shared.ts#L9)
32 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/StreamProtectionStatus.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / StreamProtectionStatus
2 |
3 | # Interface: StreamProtectionStatus
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/stream\_protection\_status.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/stream_protection_status.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### maxRetries?
10 |
11 | > `optional` **maxRetries**: `number`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/stream\_protection\_status.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/stream_protection_status.ts#L14)
14 |
15 | ***
16 |
17 | ### status?
18 |
19 | > `optional` **status**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/stream\_protection\_status.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/stream_protection_status.ts#L13)
22 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/functions/isGoogleVideoURL.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / isGoogleVideoURL
2 |
3 | # Function: isGoogleVideoURL()
4 |
5 | > **isGoogleVideoURL**(`url`): `boolean`
6 |
7 | Defined in: [codeberg/googlevideo/src/utils/shared.ts:23](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/shared.ts#L23)
8 |
9 | Determines if a given URL is a Google video URL, specifically for YouTube or SABR-related content.
10 |
11 | ## Parameters
12 |
13 | ### url
14 |
15 | `string`
16 |
17 | The URL to check.
18 |
19 | The function checks the following conditions:
20 | 1. If the URL starts with the `sabr://` protocol, it is considered a Google video URL.
21 | 2. If the URL ends with `/videoplayback`, it parses the query parameters to check for specific keys
22 | (`source=youtube`, `sabr`, `lsig`, or `expire`) that indicate a Google video URL.
23 | 3. If the URL contains `/videoplayback/` (e.g., for live or post-live content), it checks the path
24 | segments for specific keywords (`videoplayback`, `sabr`, `lsig`, or `expire`).
25 |
26 | ## Returns
27 |
28 | `boolean`
29 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/variables/SABR_CONSTANTS.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / SABR\_CONSTANTS
2 |
3 | # Variable: SABR\_CONSTANTS
4 |
5 | > `const` **SABR\_CONSTANTS**: `object`
6 |
7 | Defined in: [codeberg/googlevideo/src/core/SabrStreamingAdapter.ts:49](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrStreamingAdapter.ts#L49)
8 |
9 | ## Type declaration
10 |
11 | ### DEFAULT\_OPTIONS
12 |
13 | > `readonly` **DEFAULT\_OPTIONS**: `object`
14 |
15 | #### DEFAULT\_OPTIONS.enableCaching
16 |
17 | > `readonly` **enableCaching**: `true` = `true`
18 |
19 | #### DEFAULT\_OPTIONS.enableVerboseRequestLogging
20 |
21 | > `readonly` **enableVerboseRequestLogging**: `false` = `false`
22 |
23 | #### DEFAULT\_OPTIONS.maxCacheAgeSeconds
24 |
25 | > `readonly` **maxCacheAgeSeconds**: `300` = `300`
26 |
27 | #### DEFAULT\_OPTIONS.maxCacheSizeMB
28 |
29 | > `readonly` **maxCacheSizeMB**: `3` = `3`
30 |
31 | ### KEY\_PARAM
32 |
33 | > `readonly` **KEY\_PARAM**: `"key"` = `'key'`
34 |
35 | ### PROTOCOL
36 |
37 | > `readonly` **PROTOCOL**: `"sabr:"` = `'sabr:'`
38 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/README.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../README.md) / exports/utils
2 |
3 | # exports/utils
4 |
5 | This module contains general utilities.
6 |
7 | ## Namespaces
8 |
9 | - [FormatKeyUtils](namespaces/FormatKeyUtils/README.md)
10 |
11 | ## Enumerations
12 |
13 | - [EnabledTrackTypes](enumerations/EnabledTrackTypes.md)
14 | - [LogLevel](enumerations/LogLevel.md)
15 |
16 | ## Classes
17 |
18 | - [CacheManager](classes/CacheManager.md)
19 | - [EventEmitterLike](classes/EventEmitterLike.md)
20 | - [Logger](classes/Logger.md)
21 | - [RequestMetadataManager](classes/RequestMetadataManager.md)
22 | - [SabrAdapterError](classes/SabrAdapterError.md)
23 |
24 | ## Interfaces
25 |
26 | - [CacheEntry](interfaces/CacheEntry.md)
27 |
28 | ## Variables
29 |
30 | - [MAX\_INT32\_VALUE](variables/MAX_INT32_VALUE.md)
31 |
32 | ## Functions
33 |
34 | - [base64ToU8](functions/base64ToU8.md)
35 | - [buildSabrFormat](functions/buildSabrFormat.md)
36 | - [concatenateChunks](functions/concatenateChunks.md)
37 | - [isGoogleVideoURL](functions/isGoogleVideoURL.md)
38 | - [parseRangeHeader](functions/parseRangeHeader.md)
39 | - [u8ToBase64](functions/u8ToBase64.md)
40 | - [wait](functions/wait.md)
41 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/FormatId.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / FormatId
2 |
3 | # Interface: FormatId
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:186](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L186)
6 |
7 | ## Properties
8 |
9 | ### itag?
10 |
11 | > `optional` **itag**: `number`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:187](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L187)
14 |
15 | ***
16 |
17 | ### lastModified?
18 |
19 | > `optional` **lastModified**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:188](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L188)
22 |
23 | ***
24 |
25 | ### xtags?
26 |
27 | > `optional` **xtags**: `string`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:189](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L189)
30 |
--------------------------------------------------------------------------------
/protos/video_streaming/sabr_context_update.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message SabrContextUpdate {
5 | enum SabrContextScope {
6 | UNKNOWN = 0;
7 | PLAYBACK = 1;
8 | REQUEST = 2;
9 | WATCH_ENDPOINT = 3;
10 | CONTENT_ADS = 4;
11 | }
12 |
13 | enum SabrContextWritePolicy {
14 | UNSPECIFIED = 0;
15 | OVERWRITE = 1;
16 | KEEP_EXISTING = 2;
17 | }
18 |
19 | optional int32 type = 1;
20 | optional SabrContextScope scope = 2;
21 |
22 | optional bytes value = 3;
23 | optional bool send_by_default = 4;
24 | optional SabrContextWritePolicy write_policy = 5;
25 | }
26 |
27 | // For debugging
28 | message SabrContextValue {
29 | message ContentInfo {
30 | optional string content_id = 1; // Looks like a content identifier of some sort "mQxOaLekHJ2f-LAPtq3hwQ4"
31 | optional int32 content_type = 2; // Value of 1 observed (unsure what it truly means/is)
32 | }
33 |
34 | message TimingInfo {
35 | optional int64 timestamp_ms = 1;
36 | optional int32 duration_ms = 2;
37 | optional ContentInfo content = 3;
38 | }
39 |
40 | optional TimingInfo timing = 1;
41 | optional bytes signature = 2;
42 | optional int32 field5 = 5;
43 | }
44 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/PlaybackStartPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / PlaybackStartPolicy
2 |
3 | # Interface: PlaybackStartPolicy
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_start\_policy.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_start_policy.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### resumeMinReadaheadPolicy?
10 |
11 | > `optional` **resumeMinReadaheadPolicy**: `PlaybackStartPolicy_ReadaheadPolicy`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_start\_policy.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_start_policy.ts#L14)
14 |
15 | ***
16 |
17 | ### startMinReadaheadPolicy?
18 |
19 | > `optional` **startMinReadaheadPolicy**: `PlaybackStartPolicy_ReadaheadPolicy`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_start\_policy.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_start_policy.ts#L13)
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # YouTube player cache directory
2 | cache/
3 |
4 | # Logs
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 | lerna-debug.log*
11 | .pnpm-debug.log*
12 |
13 | # WebStorm
14 | .idea/
15 |
16 | # Coverage directory used by tools like istanbul
17 | coverage
18 | *.lcov
19 |
20 | # Dependency directories
21 | node_modules/
22 | jspm_packages/
23 |
24 | # TypeScript cache
25 | *.tsbuildinfo
26 |
27 | # Optional npm cache directory
28 | .npm
29 |
30 | # Optional eslint cache
31 | .eslintcache
32 |
33 | # Optional stylelint cache
34 | .stylelintcache
35 |
36 | # Output of 'npm pack'
37 | *.tgz
38 |
39 | # Yarn Integrity file
40 | .yarn-integrity
41 |
42 | # dotenv environment variable files
43 | .env
44 | .env.development.local
45 | .env.test.local
46 | .env.production.local
47 | .env.local
48 |
49 | # yarn v2
50 | .yarn/cache
51 | .yarn/unplugged
52 | .yarn/build-state.yml
53 | .yarn/install-state.gz
54 | .pnp.*
55 |
56 | # pnpm
57 | .pnpm-debug.log*
58 | pnpm-lock.yaml
59 |
60 | # Downloaded assets
61 | *.mp4
62 | *.webm
63 | *.mkv
64 |
65 | # Temporary files for testing
66 | tmp/
67 |
68 | # Build output
69 | dist/
70 | bundle/*.js.*
71 | bundle/*.js
72 | bundle/*.cjs
73 | bundle/*.cjs.*
74 | deno/
75 |
76 | # MacOS
77 | .DS_Store
78 |
--------------------------------------------------------------------------------
/examples/sabr-shaka-example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SABR Shaka Player Example
7 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Ready. Enter a video ID and click "Load Video".
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/sabr-shaka-example/README.md:
--------------------------------------------------------------------------------
1 | # SABR + Shaka Player Example
2 |
3 | This project provides a minimal, self-contained example of how to use [Shaka Player](https://shaka-player-demo.appspot.com/) with the `SabrStreamingAdapter` from the [googlevideo](https://github.com/LuanRT/googlevideo) library to play YouTube videos.
4 |
5 | ## Note
6 |
7 | For an implementation that includes a proper user interface, advanced features, and best practices, please see the main **[Kira](https://github.com/LuanRT/kira)** project this example is derived from.
8 |
9 | Things **not included** in this minimal example but available in the main project:
10 | * A proper watch page and user interface.
11 | * Support for DRM-protected content.
12 | * A recommendation system and persistent user sessions.
13 | * Saving and resuming playback position.
14 | * Advanced error handling and UI feedback.
15 | * A video/audio downloader.
16 |
17 | ## How to Run
18 |
19 | 1. **Install dependencies:**
20 | ```bash
21 | npm install
22 | ```
23 |
24 | 2. **Start the development server:**
25 | ```bash
26 | npm run dev
27 | ```
28 |
29 | 3. Open your browser and navigate to the local URL provided by Vite (e.g., `http://localhost:5173`).
30 |
31 | ## License
32 | Distributed under the [MIT](../../LICENSE) License.
--------------------------------------------------------------------------------
/docs/api/exports/sabr-stream/interfaces/InitializedFormat.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-stream](../README.md) / InitializedFormat
2 |
3 | # Interface: InitializedFormat
4 |
5 | Defined in: [codeberg/googlevideo/src/core/SabrStream.ts:57](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrStream.ts#L57)
6 |
7 | ## Properties
8 |
9 | ### downloadedSegments
10 |
11 | > **downloadedSegments**: `Map`\<`number`, `Segment`\>
12 |
13 | Defined in: [codeberg/googlevideo/src/core/SabrStream.ts:59](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrStream.ts#L59)
14 |
15 | ***
16 |
17 | ### formatInitializationMetadata
18 |
19 | > **formatInitializationMetadata**: [`FormatInitializationMetadata`](../../protos/interfaces/FormatInitializationMetadata.md)
20 |
21 | Defined in: [codeberg/googlevideo/src/core/SabrStream.ts:58](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrStream.ts#L58)
22 |
23 | ***
24 |
25 | ### lastMediaHeaders
26 |
27 | > **lastMediaHeaders**: [`MediaHeader`](../../protos/interfaces/MediaHeader.md)[]
28 |
29 | Defined in: [codeberg/googlevideo/src/core/SabrStream.ts:60](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrStream.ts#L60)
30 |
--------------------------------------------------------------------------------
/docs/api/exports/ump/classes/UmpWriter.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/ump](../README.md) / UmpWriter
2 |
3 | # Class: UmpWriter
4 |
5 | Defined in: [codeberg/googlevideo/src/core/UmpWriter.ts:6](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/UmpWriter.ts#L6)
6 |
7 | A serialization module that encodes data into the UMP binary format with proper type and size encoding.
8 |
9 | ## Constructors
10 |
11 | ### Constructor
12 |
13 | > **new UmpWriter**(`compositeBuffer`): `UmpWriter`
14 |
15 | Defined in: [codeberg/googlevideo/src/core/UmpWriter.ts:7](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/UmpWriter.ts#L7)
16 |
17 | #### Parameters
18 |
19 | ##### compositeBuffer
20 |
21 | [`CompositeBuffer`](CompositeBuffer.md)
22 |
23 | #### Returns
24 |
25 | `UmpWriter`
26 |
27 | ## Methods
28 |
29 | ### write()
30 |
31 | > **write**(`partType`, `partData`): `void`
32 |
33 | Defined in: [codeberg/googlevideo/src/core/UmpWriter.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/UmpWriter.ts#L16)
34 |
35 | Writes a part to the buffer.
36 |
37 | #### Parameters
38 |
39 | ##### partType
40 |
41 | `number`
42 |
43 | The type of the part.
44 |
45 | ##### partData
46 |
47 | `Uint8Array`
48 |
49 | The data of the part.
50 |
51 | #### Returns
52 |
53 | `void`
54 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/enumerations/CompressionType.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / CompressionType
2 |
3 | # Enumeration: CompressionType
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L12)
6 |
7 | ## Enumeration Members
8 |
9 | ### BROTLI
10 |
11 | > **BROTLI**: `2`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L15)
14 |
15 | ***
16 |
17 | ### GZIP
18 |
19 | > **GZIP**: `1`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L14)
22 |
23 | ***
24 |
25 | ### UNKNOWN
26 |
27 | > **UNKNOWN**: `0`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L13)
30 |
31 | ***
32 |
33 | ### UNRECOGNIZED
34 |
35 | > **UNRECOGNIZED**: `-1`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L16)
38 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/CryptoParams.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / CryptoParams
2 |
3 | # Interface: CryptoParams
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/crypto\_params.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/crypto_params.ts#L13)
6 |
7 | ## Properties
8 |
9 | ### compressionType?
10 |
11 | > `optional` **compressionType**: [`CompressionType`](../enumerations/CompressionType.md)
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/crypto\_params.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/crypto_params.ts#L16)
14 |
15 | ***
16 |
17 | ### hmac?
18 |
19 | > `optional` **hmac**: `Uint8Array`\<`ArrayBufferLike`\>
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/crypto\_params.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/crypto_params.ts#L14)
22 |
23 | ***
24 |
25 | ### iv?
26 |
27 | > `optional` **iv**: `Uint8Array`\<`ArrayBufferLike`\>
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/crypto\_params.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/crypto_params.ts#L15)
30 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/FormatSelectionConfig.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / FormatSelectionConfig
2 |
3 | # Interface: FormatSelectionConfig
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/format\_selection\_config.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/format_selection_config.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### itags
10 |
11 | > **itags**: `number`[]
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/format\_selection\_config.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/format_selection_config.ts#L13)
14 |
15 | ***
16 |
17 | ### resolution?
18 |
19 | > `optional` **resolution**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/format\_selection\_config.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/format_selection_config.ts#L15)
22 |
23 | ***
24 |
25 | ### videoId?
26 |
27 | > `optional` **videoId**: `string`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/format\_selection\_config.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/format_selection_config.ts#L14)
30 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/enumerations/NetworkMeteredState.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / NetworkMeteredState
2 |
3 | # Enumeration: NetworkMeteredState
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:53](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L53)
6 |
7 | ## Enumeration Members
8 |
9 | ### METERED
10 |
11 | > **METERED**: `2`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:56](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L56)
14 |
15 | ***
16 |
17 | ### UNKNOWN
18 |
19 | > **UNKNOWN**: `0`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:54](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L54)
22 |
23 | ***
24 |
25 | ### UNMETERED
26 |
27 | > **UNMETERED**: `1`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:55](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L55)
30 |
31 | ***
32 |
33 | ### UNRECOGNIZED
34 |
35 | > **UNRECOGNIZED**: `-1`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:57](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L57)
38 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/Range.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / Range
2 |
3 | # Interface: Range
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:192](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L192)
6 |
7 | ## Properties
8 |
9 | ### end?
10 |
11 | > `optional` **end**: `number`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:196](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L196)
14 |
15 | ***
16 |
17 | ### legacyEnd?
18 |
19 | > `optional` **legacyEnd**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:194](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L194)
22 |
23 | ***
24 |
25 | ### legacyStart?
26 |
27 | > `optional` **legacyStart**: `number`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:193](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L193)
30 |
31 | ***
32 |
33 | ### start?
34 |
35 | > `optional` **start**: `number`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:195](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L195)
38 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/SabrContextValue.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrContextValue
2 |
3 | # Interface: SabrContextValue
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:37](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L37)
6 |
7 | For debugging
8 |
9 | ## Properties
10 |
11 | ### field5?
12 |
13 | > `optional` **field5**: `number`
14 |
15 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:40](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L40)
16 |
17 | ***
18 |
19 | ### signature?
20 |
21 | > `optional` **signature**: `Uint8Array`\<`ArrayBufferLike`\>
22 |
23 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:39](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L39)
24 |
25 | ***
26 |
27 | ### timing?
28 |
29 | > `optional` **timing**: `SabrContextValue_TimingInfo`
30 |
31 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:38](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L38)
32 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/RequestCancellationPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / RequestCancellationPolicy
2 |
3 | # Interface: RequestCancellationPolicy
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_cancellation\_policy.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_cancellation_policy.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### items
10 |
11 | > **items**: `RequestCancellationPolicy_Item`[]
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_cancellation\_policy.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_cancellation_policy.ts#L14)
14 |
15 | ***
16 |
17 | ### jq?
18 |
19 | > `optional` **jq**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_cancellation\_policy.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_cancellation_policy.ts#L15)
22 |
23 | ***
24 |
25 | ### N0?
26 |
27 | > `optional` **N0**: `number`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/request\_cancellation\_policy.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/request_cancellation_policy.ts#L13)
30 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/SabrContextSendingPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrContextSendingPolicy
2 |
3 | # Interface: SabrContextSendingPolicy
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_sending\_policy.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_sending_policy.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### discardPolicy
10 |
11 | > **discardPolicy**: `number`[]
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_sending\_policy.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_sending_policy.ts#L15)
14 |
15 | ***
16 |
17 | ### startPolicy
18 |
19 | > **startPolicy**: `number`[]
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_sending\_policy.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_sending_policy.ts#L13)
22 |
23 | ***
24 |
25 | ### stopPolicy
26 |
27 | > **stopPolicy**: `number`[]
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_sending\_policy.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_sending_policy.ts#L14)
30 |
--------------------------------------------------------------------------------
/examples/downloader/utils/webpo-helper.ts:
--------------------------------------------------------------------------------
1 | import { BG, type BgConfig } from 'bgutils-js';
2 | import { JSDOM } from 'jsdom';
3 |
4 | export async function generateWebPoToken(contentBinding: string) {
5 | const requestKey = 'O43z0dpjhgX20SCx4KAo';
6 |
7 | if (!contentBinding)
8 | throw new Error('Could not get visitor data');
9 |
10 | const dom = new JSDOM();
11 |
12 | Object.assign(globalThis, {
13 | window: dom.window,
14 | document: dom.window.document
15 | });
16 |
17 | const bgConfig: BgConfig = {
18 | fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => fetch(input, init),
19 | globalObj: globalThis,
20 | identifier: contentBinding,
21 | requestKey
22 | };
23 |
24 | const bgChallenge = await BG.Challenge.create(bgConfig);
25 |
26 | if (!bgChallenge)
27 | throw new Error('Could not get challenge');
28 |
29 | const interpreterJavascript = bgChallenge.interpreterJavascript.privateDoNotAccessOrElseSafeScriptWrappedValue;
30 |
31 | if (interpreterJavascript) {
32 | new Function(interpreterJavascript)();
33 | } else throw new Error('Could not load VM');
34 |
35 | const poTokenResult = await BG.PoToken.generate({
36 | program: bgChallenge.program,
37 | globalName: bgChallenge.globalName,
38 | bgConfig
39 | });
40 |
41 | const placeholderPoToken = BG.PoToken.generatePlaceholder(contentBinding);
42 |
43 | return {
44 | visitorData: contentBinding,
45 | placeholderPoToken,
46 | poToken: poTokenResult.poToken,
47 | };
48 | }
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/MediaCapabilities.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / MediaCapabilities
2 |
3 | # Interface: MediaCapabilities
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/media\_capabilities.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/media_capabilities.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### audioFormatCapabilities
10 |
11 | > **audioFormatCapabilities**: `MediaCapabilities_AudioFormatCapability`[]
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/media\_capabilities.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/media_capabilities.ts#L14)
14 |
15 | ***
16 |
17 | ### hdrModeBitmask?
18 |
19 | > `optional` **hdrModeBitmask**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/media\_capabilities.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/media_capabilities.ts#L15)
22 |
23 | ***
24 |
25 | ### videoFormatCapabilities
26 |
27 | > **videoFormatCapabilities**: `MediaCapabilities_VideoFormatCapability`[]
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/media\_capabilities.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/media_capabilities.ts#L13)
30 |
--------------------------------------------------------------------------------
/docs/api/exports/utils/enumerations/LogLevel.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / LogLevel
2 |
3 | # Enumeration: LogLevel
4 |
5 | Defined in: [codeberg/googlevideo/src/utils/Logger.ts:1](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/Logger.ts#L1)
6 |
7 | ## Enumeration Members
8 |
9 | ### ALL
10 |
11 | > **ALL**: `99`
12 |
13 | Defined in: [codeberg/googlevideo/src/utils/Logger.ts:7](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/Logger.ts#L7)
14 |
15 | ***
16 |
17 | ### DEBUG
18 |
19 | > **DEBUG**: `4`
20 |
21 | Defined in: [codeberg/googlevideo/src/utils/Logger.ts:6](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/Logger.ts#L6)
22 |
23 | ***
24 |
25 | ### ERROR
26 |
27 | > **ERROR**: `1`
28 |
29 | Defined in: [codeberg/googlevideo/src/utils/Logger.ts:3](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/Logger.ts#L3)
30 |
31 | ***
32 |
33 | ### INFO
34 |
35 | > **INFO**: `3`
36 |
37 | Defined in: [codeberg/googlevideo/src/utils/Logger.ts:5](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/Logger.ts#L5)
38 |
39 | ***
40 |
41 | ### NONE
42 |
43 | > **NONE**: `0`
44 |
45 | Defined in: [codeberg/googlevideo/src/utils/Logger.ts:2](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/Logger.ts#L2)
46 |
47 | ***
48 |
49 | ### WARN
50 |
51 | > **WARN**: `2`
52 |
53 | Defined in: [codeberg/googlevideo/src/utils/Logger.ts:4](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/Logger.ts#L4)
54 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/enumerations/SabrContextWritePolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrContextWritePolicy
2 |
3 | # Enumeration: SabrContextWritePolicy
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:29](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L29)
6 |
7 | ## Enumeration Members
8 |
9 | ### KEEP\_EXISTING
10 |
11 | > **KEEP\_EXISTING**: `2`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:32](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L32)
14 |
15 | ***
16 |
17 | ### OVERWRITE
18 |
19 | > **OVERWRITE**: `1`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:31](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L31)
22 |
23 | ***
24 |
25 | ### UNRECOGNIZED
26 |
27 | > **UNRECOGNIZED**: `-1`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:33](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L33)
30 |
31 | ***
32 |
33 | ### UNSPECIFIED
34 |
35 | > **UNSPECIFIED**: `0`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:30](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L30)
38 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/enumerations/VideoQualitySetting.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / VideoQualitySetting
2 |
3 | # Enumeration: VideoQualitySetting
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:28](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L28)
6 |
7 | ## Enumeration Members
8 |
9 | ### ADVANCED\_MENU
10 |
11 | > **ADVANCED\_MENU**: `3`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:32](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L32)
14 |
15 | ***
16 |
17 | ### DATA\_SAVER
18 |
19 | > **DATA\_SAVER**: `2`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:31](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L31)
22 |
23 | ***
24 |
25 | ### HIGHER\_QUALITY
26 |
27 | > **HIGHER\_QUALITY**: `1`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:30](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L30)
30 |
31 | ***
32 |
33 | ### UNKNOWN
34 |
35 | > **UNKNOWN**: `0`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:29](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L29)
38 |
39 | ***
40 |
41 | ### UNRECOGNIZED
42 |
43 | > **UNRECOGNIZED**: `-1`
44 |
45 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:33](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L33)
46 |
--------------------------------------------------------------------------------
/dev-scripts/generate-proto.mjs:
--------------------------------------------------------------------------------
1 | import { exec } from 'child_process';
2 | import { existsSync, mkdirSync, readdirSync, statSync } from 'fs';
3 | import { join } from 'path';
4 | import path from 'path';
5 | import url from 'url';
6 | import os from 'os';
7 |
8 | const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
9 |
10 | const protoDir = './protos';
11 | const outDir = './protos/generated';
12 |
13 | if (!existsSync(outDir)) {
14 | mkdirSync(outDir, { recursive: true });
15 | }
16 |
17 | const protocGenTs = path.join(
18 | __dirname,
19 | '../node_modules',
20 | '.bin',
21 | os.platform() === 'win32' ? 'protoc-gen-ts_proto.cmd' : 'protoc-gen-ts_proto'
22 | );
23 |
24 | function listProtoFiles(dir) {
25 | let protoFiles = [];
26 | const items = readdirSync(dir);
27 |
28 | for (const item of items) {
29 | const fullPath = join(dir, item);
30 | if (statSync(fullPath).isDirectory()) {
31 | protoFiles = protoFiles.concat(listProtoFiles(fullPath));
32 | } else if (item.endsWith('.proto')) {
33 | protoFiles.push(fullPath);
34 | }
35 | }
36 |
37 | return protoFiles;
38 | }
39 |
40 | const protoFiles = listProtoFiles(protoDir);
41 |
42 | if (!protoFiles.length) {
43 | console.log('No .proto files found.');
44 | process.exit(0);
45 | }
46 |
47 | protoFiles.forEach((file) => {
48 | const command = `protoc --proto_path=${protoDir} --plugin=protoc-gen-ts=${protocGenTs} --ts_opt=env=browser --ts_opt=forceLong=string --ts_opt=importSuffix=.js --ts_out=${outDir} --ts_opt=outputJsonMethods=false --ts_opt=outputPartialMethods=false --ts_opt=removeEnumPrefix=true ${file}`;
49 | exec(command, (error, _stdout, stderr) => {
50 | if (error) {
51 | console.error(`Error compiling ${file}:`, stderr);
52 | }
53 | });
54 | });
--------------------------------------------------------------------------------
/protos/generated/video_streaming/sabr_redirect.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/sabr_redirect.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 |
10 | export const protobufPackage = "video_streaming";
11 |
12 | export interface SabrRedirect {
13 | url?: string | undefined;
14 | }
15 |
16 | function createBaseSabrRedirect(): SabrRedirect {
17 | return { url: "" };
18 | }
19 |
20 | export const SabrRedirect: MessageFns = {
21 | encode(message: SabrRedirect, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
22 | if (message.url !== undefined && message.url !== "") {
23 | writer.uint32(10).string(message.url);
24 | }
25 | return writer;
26 | },
27 |
28 | decode(input: BinaryReader | Uint8Array, length?: number): SabrRedirect {
29 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
30 | const end = length === undefined ? reader.len : reader.pos + length;
31 | const message = createBaseSabrRedirect();
32 | while (reader.pos < end) {
33 | const tag = reader.uint32();
34 | switch (tag >>> 3) {
35 | case 1: {
36 | if (tag !== 10) {
37 | break;
38 | }
39 |
40 | message.url = reader.string();
41 | continue;
42 | }
43 | }
44 | if ((tag & 7) === 4 || tag === 0) {
45 | break;
46 | }
47 | reader.skip(tag & 7);
48 | }
49 | return message;
50 | },
51 | };
52 |
53 | export interface MessageFns {
54 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
55 | decode(input: BinaryReader | Uint8Array, length?: number): T;
56 | }
57 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/PlaybackCookie.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / PlaybackCookie
2 |
3 | # Interface: PlaybackCookie
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_cookie.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_cookie.ts#L13)
6 |
7 | ## Properties
8 |
9 | ### audioFmt?
10 |
11 | > `optional` **audioFmt**: [`FormatId`](FormatId.md)
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_cookie.ts:18](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_cookie.ts#L18)
14 |
15 | ***
16 |
17 | ### field2?
18 |
19 | > `optional` **field2**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_cookie.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_cookie.ts#L16)
22 |
23 | ***
24 |
25 | ### resolution?
26 |
27 | > `optional` **resolution**: `number`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_cookie.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_cookie.ts#L15)
30 |
31 | Always 999999 when resolution is set manually, or if the auto selected one is the max available resolution.
32 |
33 | ***
34 |
35 | ### videoFmt?
36 |
37 | > `optional` **videoFmt**: [`FormatId`](FormatId.md)
38 |
39 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/playback\_cookie.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/playback_cookie.ts#L17)
40 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/snackbar_message.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/snackbar_message.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 |
10 | export const protobufPackage = "video_streaming";
11 |
12 | export interface SnackbarMessage {
13 | id?: number | undefined;
14 | }
15 |
16 | function createBaseSnackbarMessage(): SnackbarMessage {
17 | return { id: 0 };
18 | }
19 |
20 | export const SnackbarMessage: MessageFns = {
21 | encode(message: SnackbarMessage, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
22 | if (message.id !== undefined && message.id !== 0) {
23 | writer.uint32(8).int32(message.id);
24 | }
25 | return writer;
26 | },
27 |
28 | decode(input: BinaryReader | Uint8Array, length?: number): SnackbarMessage {
29 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
30 | const end = length === undefined ? reader.len : reader.pos + length;
31 | const message = createBaseSnackbarMessage();
32 | while (reader.pos < end) {
33 | const tag = reader.uint32();
34 | switch (tag >>> 3) {
35 | case 1: {
36 | if (tag !== 8) {
37 | break;
38 | }
39 |
40 | message.id = reader.int32();
41 | continue;
42 | }
43 | }
44 | if ((tag & 7) === 4 || tag === 0) {
45 | break;
46 | }
47 | reader.skip(tag & 7);
48 | }
49 | return message;
50 | },
51 | };
52 |
53 | export interface MessageFns {
54 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
55 | decode(input: BinaryReader | Uint8Array, length?: number): T;
56 | }
57 |
--------------------------------------------------------------------------------
/src/types/shared.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains type definitions used across the library.
3 | * @module
4 | */
5 |
6 | import type { CompositeBuffer } from '../core/CompositeBuffer.js';
7 |
8 | export type Part = {
9 | type: number;
10 | size: number;
11 | data: CompositeBuffer;
12 | };
13 |
14 | export interface SabrFormat {
15 | itag: number;
16 | lastModified: string;
17 | xtags?: string;
18 | width?: number;
19 | height?: number;
20 | contentLength?: number;
21 | audioTrackId?: string;
22 | mimeType?: string;
23 | isDrc?: boolean;
24 | quality?: string;
25 | qualityLabel?: string;
26 | averageBitrate?: number;
27 | bitrate: number;
28 | audioQuality?: string;
29 | approxDurationMs: number;
30 | language?: string | null;
31 | isDubbed?: boolean;
32 | isAutoDubbed?: boolean;
33 | isDescriptive?: boolean;
34 | isSecondary?: boolean;
35 | isOriginal?: boolean;
36 | }
37 |
38 | export interface FormatStream {
39 | itag: number;
40 | last_modified_ms?: string;
41 | lastModified?: string;
42 | xtags?: string;
43 | width?: number;
44 | height?: number;
45 | mime_type?: string;
46 | mimeType?: string;
47 | audio_quality?: string;
48 | audioQuality?: string;
49 | bitrate: number;
50 | average_bitrate?: number;
51 | averageBitrate?: number;
52 | quality?: string;
53 | quality_label?: string;
54 | qualityLabel?: string;
55 | audio_track?: { id: string };
56 | audioTrackId?: string;
57 | is_drc?: boolean;
58 | isDrc?: boolean;
59 | approx_duration_ms?: number;
60 | approxDurationMs?: string;
61 | content_length?: number;
62 | contentLength?: string;
63 | is_auto_dubbed?: boolean;
64 | is_descriptive?: boolean;
65 | is_dubbed?: boolean;
66 | language?: string | null;
67 | is_original?: boolean;
68 | is_secondary?: boolean;
69 | }
70 |
71 | export type FetchFunction = typeof fetch;
--------------------------------------------------------------------------------
/protos/generated/video_streaming/request_identifier.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/request_identifier.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 |
10 | export const protobufPackage = "video_streaming";
11 |
12 | export interface RequestIdentifier {
13 | token?: string | undefined;
14 | }
15 |
16 | function createBaseRequestIdentifier(): RequestIdentifier {
17 | return { token: "" };
18 | }
19 |
20 | export const RequestIdentifier: MessageFns = {
21 | encode(message: RequestIdentifier, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
22 | if (message.token !== undefined && message.token !== "") {
23 | writer.uint32(10).string(message.token);
24 | }
25 | return writer;
26 | },
27 |
28 | decode(input: BinaryReader | Uint8Array, length?: number): RequestIdentifier {
29 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
30 | const end = length === undefined ? reader.len : reader.pos + length;
31 | const message = createBaseRequestIdentifier();
32 | while (reader.pos < end) {
33 | const tag = reader.uint32();
34 | switch (tag >>> 3) {
35 | case 1: {
36 | if (tag !== 10) {
37 | break;
38 | }
39 |
40 | message.token = reader.string();
41 | continue;
42 | }
43 | }
44 | if ((tag & 7) === 4 || tag === 0) {
45 | break;
46 | }
47 | reader.skip(tag & 7);
48 | }
49 | return message;
50 | },
51 | };
52 |
53 | export interface MessageFns {
54 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
55 | decode(input: BinaryReader | Uint8Array, length?: number): T;
56 | }
57 |
--------------------------------------------------------------------------------
/protos/video_streaming/video_playback_abr_request.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 | import "video_streaming/buffered_range.proto";
6 | import "video_streaming/client_abr_state.proto";
7 | import "video_streaming/streamer_context.proto";
8 | import "video_streaming/time_range.proto";
9 |
10 | message VideoPlaybackAbrRequest {
11 | optional ClientAbrState client_abr_state = 1;
12 | repeated .misc.FormatId selected_format_ids = 2;
13 | repeated BufferedRange buffered_ranges = 3;
14 | optional int64 player_time_ms = 4; // `osts` (Onesie Start Time Seconds) param on Onesie requests.
15 | optional bytes video_playback_ustreamer_config = 5;
16 | optional UnknownMessage1 field6 = 6;
17 | repeated .misc.FormatId preferred_audio_format_ids = 16; // `pai` (Preferred Audio Itags) param on Onesie requests.
18 | repeated .misc.FormatId preferred_video_format_ids = 17; // `pvi` (Preferred Video Itags) param on Onesie requests.
19 | repeated .misc.FormatId preferred_subtitle_format_ids = 18;
20 | optional StreamerContext streamer_context = 19;
21 | optional UnknownMessage2 field21 = 21;
22 | optional int32 field22 = 22;
23 | optional int32 field23 = 23;
24 | repeated UnknownMessage3 field1000 = 1000;
25 | }
26 |
27 | message UnknownMessage1 {
28 | optional .misc.FormatId format_id = 1;
29 | optional sint64 lmt = 2;
30 | optional int32 sequence_number = 3;
31 | optional TimeRange time_range = 4;
32 | optional int32 field5 = 5;
33 | }
34 |
35 | message UnknownMessage2 {
36 | repeated string field1 = 1;
37 | optional bytes field2 = 2;
38 | optional string field3 = 3;
39 | optional int32 field4 = 4;
40 | optional int32 field5 = 5;
41 | optional string field6 = 6;
42 | }
43 |
44 | message UnknownMessage3 {
45 | repeated .misc.FormatId format_ids = 1;
46 | repeated BufferedRange ud = 2;
47 | optional string clip_id = 3;
48 | }
--------------------------------------------------------------------------------
/.github/workflows/release-please.yml:
--------------------------------------------------------------------------------
1 | name: release-please
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | permissions:
9 | contents: write
10 | pull-requests: write
11 | id-token: write
12 |
13 | jobs:
14 | release-please:
15 | permissions:
16 | contents: write
17 | pull-requests: write
18 | id-token: write
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: googleapis/release-please-action@v4
22 | id: release
23 | with:
24 | token: ${{ secrets.GITHUB_TOKEN }}
25 | config-file: release-please-config.json
26 | manifest-file: .release-please-manifest.json
27 |
28 | - uses: actions/checkout@v4
29 | if: ${{ steps.release.outputs.release_created }}
30 |
31 | - uses: actions/setup-node@v4
32 | with:
33 | node-version: "20"
34 | registry-url: "https://registry.npmjs.org"
35 | if: ${{ steps.release.outputs.release_created }}
36 |
37 | - name: Install protoc
38 | run: |
39 | sudo apt-get update
40 | sudo apt-get install -y unzip
41 | curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protoc-21.12-linux-x86_64.zip
42 | unzip protoc-21.12-linux-x86_64.zip -d protoc21
43 | sudo mv protoc21/bin/protoc /usr/local/bin/
44 | if: ${{ steps.release.outputs.release_created }}
45 |
46 | - run: npm ci
47 | if: ${{ steps.release.outputs.release_created }}
48 |
49 | - name: Publish to NPM
50 | run: |
51 | npm publish
52 | env:
53 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
54 | if: ${{ steps.release.outputs.release_created }}
55 |
56 | - name: Publish to JSR
57 | run: |
58 | npm run build
59 | npx jsr publish --allow-dirty
60 | if: ${{ steps.release.outputs.release_created }}
--------------------------------------------------------------------------------
/src/core/UmpWriter.ts:
--------------------------------------------------------------------------------
1 | import type { CompositeBuffer } from './CompositeBuffer.js';
2 |
3 | /**
4 | * A serialization module that encodes data into the UMP binary format with proper type and size encoding.
5 | */
6 | export class UmpWriter {
7 | constructor(
8 | private compositeBuffer: CompositeBuffer
9 | ) { }
10 |
11 | /**
12 | * Writes a part to the buffer.
13 | * @param partType - The type of the part.
14 | * @param partData - The data of the part.
15 | */
16 | public write(partType: number, partData: Uint8Array): void {
17 | const partSize = partData.length;
18 | this.writeVarInt(partType);
19 | this.writeVarInt(partSize);
20 | this.compositeBuffer.append(partData);
21 | }
22 |
23 | /**
24 | * Writes a variable-length integer to the buffer.
25 | * @param value - The integer to write.
26 | */
27 | private writeVarInt(value: number): void {
28 | if (value < 0)
29 | throw new Error('VarInt value cannot be negative.');
30 |
31 | if (value < 128) {
32 | this.compositeBuffer.append(new Uint8Array([ value ]));
33 | } else if (value < 16384) {
34 | this.compositeBuffer.append(new Uint8Array([
35 | (value & 0x3F) | 0x80,
36 | value >> 6
37 | ]));
38 | } else if (value < 2097152) {
39 | this.compositeBuffer.append(new Uint8Array([
40 | (value & 0x1F) | 0xC0,
41 | (value >> 5) & 0xFF,
42 | value >> 13
43 | ]));
44 | } else if (value < 268435456) {
45 | this.compositeBuffer.append(new Uint8Array([
46 | (value & 0x0F) | 0xE0,
47 | (value >> 4) & 0xFF,
48 | (value >> 12) & 0xFF,
49 | value >> 20
50 | ]));
51 | } else {
52 | const data = new Uint8Array(5);
53 | const view = new DataView(data.buffer);
54 | data[0] = 0xF0;
55 | view.setUint32(1, value, true);
56 | this.compositeBuffer.append(data);
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/OnesieInnertubeResponse.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / OnesieInnertubeResponse
2 |
3 | # Interface: OnesieInnertubeResponse
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_response.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_response.ts#L14)
6 |
7 | ## Properties
8 |
9 | ### body?
10 |
11 | > `optional` **body**: `Uint8Array`\<`ArrayBufferLike`\>
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_response.ts:18](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_response.ts#L18)
14 |
15 | ***
16 |
17 | ### headers
18 |
19 | > **headers**: [`HttpHeader`](HttpHeader.md)[]
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_response.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_response.ts#L17)
22 |
23 | ***
24 |
25 | ### httpStatus?
26 |
27 | > `optional` **httpStatus**: `number`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_response.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_response.ts#L16)
30 |
31 | ***
32 |
33 | ### onesieProxyStatus?
34 |
35 | > `optional` **onesieProxyStatus**: [`OnesieProxyStatus`](../enumerations/OnesieProxyStatus.md)
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_response.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_response.ts#L15)
38 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/interfaces/PlayerHttpRequest.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / PlayerHttpRequest
2 |
3 | # Interface: PlayerHttpRequest
4 |
5 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:83](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L83)
6 |
7 | ## Properties
8 |
9 | ### body?
10 |
11 | > `optional` **body**: `null` \| `ArrayBuffer` \| `ArrayBufferView`\<`ArrayBufferLike`\>
12 |
13 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:88](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L88)
14 |
15 | ***
16 |
17 | ### headers
18 |
19 | > **headers**: `Record`\<`string`, `string`\>
20 |
21 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:86](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L86)
22 |
23 | ***
24 |
25 | ### method
26 |
27 | > **method**: `string`
28 |
29 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:85](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L85)
30 |
31 | ***
32 |
33 | ### segment
34 |
35 | > **segment**: [`RequestSegment`](RequestSegment.md)
36 |
37 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:87](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L87)
38 |
39 | ***
40 |
41 | ### url
42 |
43 | > **url**: `string`
44 |
45 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:84](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L84)
46 |
--------------------------------------------------------------------------------
/examples/downloader/main.ts:
--------------------------------------------------------------------------------
1 | import { EnabledTrackTypes } from 'googlevideo/utils';
2 |
3 | import {
4 | createOutputStream,
5 | createStreamSink,
6 | createSabrStream,
7 | createMultiProgressBar,
8 | setupProgressBar
9 | } from './utils/sabr-stream-factory.js';
10 |
11 | import type { SabrPlaybackOptions } from 'googlevideo/sabr-stream';
12 |
13 | const VIDEO_ID = 'xjHO_02jZco';
14 | const OPTIONS: SabrPlaybackOptions = {
15 | preferWebM: true,
16 | preferOpus: true,
17 | videoQuality: '720p',
18 | audioQuality: 'AUDIO_QUALITY_MEDIUM',
19 | enabledTrackTypes: EnabledTrackTypes.VIDEO_AND_AUDIO
20 | };
21 |
22 | async function main() {
23 | const progressBars = createMultiProgressBar();
24 |
25 | try {
26 | const { streamResults } = await createSabrStream(VIDEO_ID, OPTIONS);
27 | const { videoStream, audioStream, selectedFormats, videoTitle } = streamResults;
28 |
29 | const audioOutputStream = createOutputStream(videoTitle, selectedFormats.audioFormat.mimeType!);
30 | const videoOutputStream = createOutputStream(videoTitle, selectedFormats.videoFormat.mimeType!);
31 |
32 | const audioBar = setupProgressBar(progressBars, 'audio', selectedFormats.audioFormat.contentLength || 0);
33 | const videoBar = setupProgressBar(progressBars, 'video', selectedFormats.videoFormat.contentLength || 0);
34 |
35 | await Promise.all([
36 | videoStream.pipeTo(createStreamSink(selectedFormats.videoFormat, videoOutputStream.stream, videoBar)),
37 | audioStream.pipeTo(createStreamSink(selectedFormats.audioFormat, audioOutputStream.stream, audioBar))
38 | ]);
39 |
40 | progressBars.stop();
41 |
42 | console.log(`Download completed! Files saved as:
43 | Audio: ${audioOutputStream.filePath},
44 | Video: ${videoOutputStream.filePath}`);
45 | } catch (error) {
46 | console.error('Download failed:', error);
47 | progressBars.stop();
48 | process.exit(1);
49 | }
50 | }
51 |
52 | main().then();
--------------------------------------------------------------------------------
/docs/api/exports/protos/enumerations/AudioQuality.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / AudioQuality
2 |
3 | # Enumeration: AudioQuality
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:19](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L19)
6 |
7 | ## Enumeration Members
8 |
9 | ### HIGH
10 |
11 | > **HIGH**: `30`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:24](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L24)
14 |
15 | ***
16 |
17 | ### LOW
18 |
19 | > **LOW**: `10`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:22](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L22)
22 |
23 | ***
24 |
25 | ### MEDIUM
26 |
27 | > **MEDIUM**: `20`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:23](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L23)
30 |
31 | ***
32 |
33 | ### ULTRALOW
34 |
35 | > **ULTRALOW**: `5`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:21](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L21)
38 |
39 | ***
40 |
41 | ### UNKNOWN
42 |
43 | > **UNKNOWN**: `0`
44 |
45 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:20](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L20)
46 |
47 | ***
48 |
49 | ### UNRECOGNIZED
50 |
51 | > **UNRECOGNIZED**: `-1`
52 |
53 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:25](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L25)
54 |
--------------------------------------------------------------------------------
/src/utils/RequestMetadataManager.ts:
--------------------------------------------------------------------------------
1 | import type { SabrRequestMetadata } from '../types/sabrStreamingAdapterTypes.js';
2 |
3 | /**
4 | * Manages request metadata objects.
5 | */
6 | export class RequestMetadataManager {
7 | public metadataMap: Map;
8 | private lastCleanup: number;
9 | private readonly CLEANUP_INTERVAL = 30000;
10 | private readonly ENTRY_EXPIRATION_TIME = 1000 * 60 * 3;
11 |
12 | constructor() {
13 | this.metadataMap = new Map();
14 | this.lastCleanup = Date.now();
15 | }
16 |
17 | public getRequestMetadata(url: string, del = false): SabrRequestMetadata | undefined {
18 | const requestNumber = new URL(url).searchParams.get('rn') || '';
19 |
20 | const streamingContext = this.metadataMap.get(requestNumber);
21 |
22 | // Check if this specific entry is expired.
23 | if (streamingContext && Date.now() - streamingContext.timestamp > this.ENTRY_EXPIRATION_TIME) {
24 | this.metadataMap.delete(requestNumber);
25 | return undefined;
26 | }
27 |
28 | if (del) {
29 | this.metadataMap.delete(requestNumber);
30 | }
31 |
32 | this.conditionalCleanUp();
33 |
34 | return streamingContext;
35 | }
36 |
37 | public setRequestMetadata(url: string, context: SabrRequestMetadata) {
38 | const requestNumber = new URL(url).searchParams.get('rn');
39 | if (requestNumber) {
40 | this.metadataMap.set(requestNumber, context);
41 | this.conditionalCleanUp();
42 | }
43 | }
44 |
45 | private conditionalCleanUp() {
46 | const now = Date.now();
47 | if (now - this.lastCleanup > this.CLEANUP_INTERVAL) {
48 | this.cleanUp();
49 | this.lastCleanup = now;
50 | }
51 | }
52 |
53 | private cleanUp() {
54 | // Should rarely run. This is only for requests that fail and never get handled (e.g., network errors).
55 | for (const [ key, context ] of this.metadataMap.entries()) {
56 | if (Date.now() - context.timestamp > this.ENTRY_EXPIRATION_TIME) {
57 | this.metadataMap.delete(key);
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/sabr_error.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/sabr_error.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 |
10 | export const protobufPackage = "video_streaming";
11 |
12 | export interface SabrError {
13 | type?: string | undefined;
14 | code?: number | undefined;
15 | }
16 |
17 | function createBaseSabrError(): SabrError {
18 | return { type: "", code: 0 };
19 | }
20 |
21 | export const SabrError: MessageFns = {
22 | encode(message: SabrError, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
23 | if (message.type !== undefined && message.type !== "") {
24 | writer.uint32(10).string(message.type);
25 | }
26 | if (message.code !== undefined && message.code !== 0) {
27 | writer.uint32(16).int32(message.code);
28 | }
29 | return writer;
30 | },
31 |
32 | decode(input: BinaryReader | Uint8Array, length?: number): SabrError {
33 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
34 | const end = length === undefined ? reader.len : reader.pos + length;
35 | const message = createBaseSabrError();
36 | while (reader.pos < end) {
37 | const tag = reader.uint32();
38 | switch (tag >>> 3) {
39 | case 1: {
40 | if (tag !== 10) {
41 | break;
42 | }
43 |
44 | message.type = reader.string();
45 | continue;
46 | }
47 | case 2: {
48 | if (tag !== 16) {
49 | break;
50 | }
51 |
52 | message.code = reader.int32();
53 | continue;
54 | }
55 | }
56 | if ((tag & 7) === 4 || tag === 0) {
57 | break;
58 | }
59 | reader.skip(tag & 7);
60 | }
61 | return message;
62 | },
63 | };
64 |
65 | export interface MessageFns {
66 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
67 | decode(input: BinaryReader | Uint8Array, length?: number): T;
68 | }
69 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/enumerations/OnesieRequestTarget.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / OnesieRequestTarget
2 |
3 | # Enumeration: OnesieRequestTarget
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:172](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L172)
6 |
7 | ## Enumeration Members
8 |
9 | ### ENCRYPTED\_PLAYER\_SERVICE
10 |
11 | > **ENCRYPTED\_PLAYER\_SERVICE**: `1`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:174](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L174)
14 |
15 | ***
16 |
17 | ### ENCRYPTED\_WATCH\_SERVICE
18 |
19 | > **ENCRYPTED\_WATCH\_SERVICE**: `3`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:176](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L176)
22 |
23 | ***
24 |
25 | ### ENCRYPTED\_WATCH\_SERVICE\_DEPRECATED
26 |
27 | > **ENCRYPTED\_WATCH\_SERVICE\_DEPRECATED**: `2`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:175](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L175)
30 |
31 | ***
32 |
33 | ### INNERTUBE\_ENCRYPTED\_SERVICE
34 |
35 | > **INNERTUBE\_ENCRYPTED\_SERVICE**: `4`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:177](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L177)
38 |
39 | ***
40 |
41 | ### UNKNOWN
42 |
43 | > **UNKNOWN**: `0`
44 |
45 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:173](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L173)
46 |
47 | ***
48 |
49 | ### UNRECOGNIZED
50 |
51 | > **UNRECOGNIZED**: `-1`
52 |
53 | Defined in: [codeberg/googlevideo/protos/generated/misc/common.ts:178](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/misc/common.ts#L178)
54 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/SabrContextUpdate.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / SabrContextUpdate
2 |
3 | # Interface: SabrContextUpdate
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### scope?
10 |
11 | > `optional` **scope**: `SabrContextUpdate_SabrContextScope`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L14)
14 |
15 | ***
16 |
17 | ### sendByDefault?
18 |
19 | > `optional` **sendByDefault**: `boolean`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L16)
22 |
23 | ***
24 |
25 | ### type?
26 |
27 | > `optional` **type**: `number`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L13)
30 |
31 | ***
32 |
33 | ### value?
34 |
35 | > `optional` **value**: `Uint8Array`\<`ArrayBufferLike`\>
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L15)
38 |
39 | ***
40 |
41 | ### writePolicy?
42 |
43 | > `optional` **writePolicy**: [`SabrContextWritePolicy`](../enumerations/SabrContextWritePolicy.md)
44 |
45 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/sabr\_context\_update.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/sabr_context_update.ts#L17)
46 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/interfaces/PlayerHttpResponse.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / PlayerHttpResponse
2 |
3 | # Interface: PlayerHttpResponse
4 |
5 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:75](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L75)
6 |
7 | ## Properties
8 |
9 | ### data?
10 |
11 | > `optional` **data**: `ArrayBuffer` \| `ArrayBufferView`\<`ArrayBufferLike`\>
12 |
13 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:79](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L79)
14 |
15 | ***
16 |
17 | ### headers
18 |
19 | > **headers**: `Record`\<`string`, `string`\>
20 |
21 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:78](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L78)
22 |
23 | ***
24 |
25 | ### makeRequest()
26 |
27 | > **makeRequest**: (`url`, `headers`) => `Promise`\<`Omit`\<`PlayerHttpResponse`, `"makeRequest"`\>\>
28 |
29 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:80](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L80)
30 |
31 | #### Parameters
32 |
33 | ##### url
34 |
35 | `string`
36 |
37 | ##### headers
38 |
39 | `Record`\<`string`, `string`\>
40 |
41 | #### Returns
42 |
43 | `Promise`\<`Omit`\<`PlayerHttpResponse`, `"makeRequest"`\>\>
44 |
45 | ***
46 |
47 | ### method
48 |
49 | > **method**: `string`
50 |
51 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:77](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L77)
52 |
53 | ***
54 |
55 | ### url
56 |
57 | > **url**: `string`
58 |
59 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:76](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L76)
60 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/OnesieInnertubeRequest.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / OnesieInnertubeRequest
2 |
3 | # Interface: OnesieInnertubeRequest
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_request.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_request.ts#L13)
6 |
7 | ## Properties
8 |
9 | ### body?
10 |
11 | > `optional` **body**: `string`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_request.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_request.ts#L16)
14 |
15 | ***
16 |
17 | ### headers
18 |
19 | > **headers**: [`HttpHeader`](HttpHeader.md)[]
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_request.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_request.ts#L15)
22 |
23 | ***
24 |
25 | ### proxiedByTrustedBandaid?
26 |
27 | > `optional` **proxiedByTrustedBandaid**: `boolean`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_request.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_request.ts#L17)
30 |
31 | ***
32 |
33 | ### skipResponseEncryption?
34 |
35 | > `optional` **skipResponseEncryption**: `boolean`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_request.ts:18](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_request.ts#L18)
38 |
39 | ***
40 |
41 | ### url?
42 |
43 | > `optional` **url**: `string`
44 |
45 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/onesie\_innertube\_request.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/onesie_innertube_request.ts#L14)
46 |
--------------------------------------------------------------------------------
/protos/video_streaming/streamer_context.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | message StreamerContext {
5 | message ClientInfo {
6 | optional string device_make = 12;
7 | optional string device_model = 13;
8 | optional int32 client_name = 16;
9 | optional string client_version = 17;
10 | optional string os_name = 18;
11 | optional string os_version = 19;
12 | optional string accept_language = 21;
13 | optional string accept_region = 22;
14 | optional int32 screen_width_points = 37;
15 | optional int32 screen_height_points = 38;
16 | optional float screen_width_inches = 39;
17 | optional float screen_height_inches = 40;
18 | optional int32 screen_pixel_density = 41;
19 | optional ClientFormFactor client_form_factor = 46;
20 | optional int32 gmscore_version_code = 50; // e.g. 243731017
21 | optional int32 window_width_points = 55;
22 | optional int32 window_height_points = 56;
23 | optional int32 android_sdk_version = 64;
24 | optional float screen_density_float = 65;
25 | optional int64 utc_offset_minutes = 67;
26 | optional string time_zone = 80;
27 | optional string chipset = 92; // e.g. "qcom;taro"
28 | optional GLDeviceInfo gl_device_info = 102;
29 | }
30 |
31 | enum ClientFormFactor {
32 | UNKNOWN_FORM_FACTOR = 0;
33 | FORM_FACTOR_VAL1 = 1;
34 | FORM_FACTOR_VAL2 = 2;
35 | }
36 |
37 | message GLDeviceInfo {
38 | optional string gl_renderer = 1;
39 | optional int32 gl_es_version_major = 2;
40 | optional int32 gl_es_version_minor = 3;
41 | }
42 |
43 | message SabrContext {
44 | optional int32 type = 1;
45 | optional bytes value = 2;
46 | }
47 |
48 | message UnknownMessage1 {
49 | message UnknownInnerMessage1 {
50 | optional int32 code = 1;
51 | optional string message = 2;
52 | }
53 |
54 | optional bytes field1 = 1;
55 | optional UnknownInnerMessage1 field2 = 2;
56 | }
57 |
58 | optional ClientInfo client_info = 1;
59 | optional bytes po_token = 2;
60 | optional bytes playback_cookie = 3;
61 | optional bytes field4 = 4;
62 | repeated SabrContext sabr_contexts = 5;
63 | repeated int32 unsent_sabr_contexts = 6;
64 | optional string field7 = 7;
65 | optional UnknownMessage1 field8 = 8;
66 | }
--------------------------------------------------------------------------------
/protos/generated/video_streaming/stream_protection_status.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/stream_protection_status.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 |
10 | export const protobufPackage = "video_streaming";
11 |
12 | export interface StreamProtectionStatus {
13 | status?: number | undefined;
14 | maxRetries?: number | undefined;
15 | }
16 |
17 | function createBaseStreamProtectionStatus(): StreamProtectionStatus {
18 | return { status: 0, maxRetries: 0 };
19 | }
20 |
21 | export const StreamProtectionStatus: MessageFns = {
22 | encode(message: StreamProtectionStatus, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
23 | if (message.status !== undefined && message.status !== 0) {
24 | writer.uint32(8).int32(message.status);
25 | }
26 | if (message.maxRetries !== undefined && message.maxRetries !== 0) {
27 | writer.uint32(16).int32(message.maxRetries);
28 | }
29 | return writer;
30 | },
31 |
32 | decode(input: BinaryReader | Uint8Array, length?: number): StreamProtectionStatus {
33 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
34 | const end = length === undefined ? reader.len : reader.pos + length;
35 | const message = createBaseStreamProtectionStatus();
36 | while (reader.pos < end) {
37 | const tag = reader.uint32();
38 | switch (tag >>> 3) {
39 | case 1: {
40 | if (tag !== 8) {
41 | break;
42 | }
43 |
44 | message.status = reader.int32();
45 | continue;
46 | }
47 | case 2: {
48 | if (tag !== 16) {
49 | break;
50 | }
51 |
52 | message.maxRetries = reader.int32();
53 | continue;
54 | }
55 | }
56 | if ((tag & 7) === 4 || tag === 0) {
57 | break;
58 | }
59 | reader.skip(tag & 7);
60 | }
61 | return message;
62 | },
63 | };
64 |
65 | export interface MessageFns {
66 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
67 | decode(input: BinaryReader | Uint8Array, length?: number): T;
68 | }
69 |
--------------------------------------------------------------------------------
/protos/video_streaming/ump_part_id.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 |
3 | package video_streaming;
4 |
5 | enum UMPPartId {
6 | UNKNOWN = 0;
7 | ONESIE_HEADER = 10;
8 | ONESIE_DATA = 11;
9 | ONESIE_ENCRYPTED_MEDIA = 12;
10 | // Header for a media segment; includes sequence and timing information.
11 | MEDIA_HEADER = 20;
12 | // Chunk of media segment data.
13 | MEDIA = 21;
14 | // Indicates end of media segment; finalizes segment processing.
15 | MEDIA_END = 22;
16 | CONFIG = 30;
17 | LIVE_METADATA = 31;
18 | HOSTNAME_CHANGE_HINT_DEPRECATED = 32;
19 | LIVE_METADATA_PROMISE = 33;
20 | LIVE_METADATA_PROMISE_CANCELLATION = 34;
21 | // Server's policy for the next request; includes backoff time and playback cookie.
22 | NEXT_REQUEST_POLICY = 35;
23 | USTREAMER_VIDEO_AND_FORMAT_METADATA = 36;
24 | FORMAT_SELECTION_CONFIG = 37;
25 | USTREAMER_SELECTED_MEDIA_STREAM = 38;
26 | // Metadata for format initialization; contains total number of segments, duration, etc.
27 | FORMAT_INITIALIZATION_METADATA = 42;
28 | // Indicates a redirect to a different streaming URL.
29 | SABR_REDIRECT = 43;
30 | // Indicates a SABR error; happens when the payload is invalid or the server cannot process the request.
31 | SABR_ERROR = 44;
32 | SABR_SEEK = 45;
33 | // Directive to reload the player with new parameters.
34 | RELOAD_PLAYER_RESPONSE = 46;
35 | PLAYBACK_START_POLICY = 47;
36 | ALLOWED_CACHED_FORMATS = 48;
37 | START_BW_SAMPLING_HINT = 49;
38 | PAUSE_BW_SAMPLING_HINT = 50;
39 | SELECTABLE_FORMATS = 51;
40 | REQUEST_IDENTIFIER = 52;
41 | REQUEST_CANCELLATION_POLICY = 53;
42 | ONESIE_PREFETCH_REJECTION = 54;
43 | TIMELINE_CONTEXT = 55;
44 | REQUEST_PIPELINING = 56;
45 | // Updates SABR context data; usually used for ads.
46 | SABR_CONTEXT_UPDATE = 57;
47 | // Status of stream protection; indicates whether attestation is required.
48 | STREAM_PROTECTION_STATUS = 58;
49 | // Policy indicating which SABR contexts to send or discard in future requests.
50 | SABR_CONTEXT_SENDING_POLICY = 59;
51 | LAWNMOWER_POLICY = 60;
52 | SABR_ACK = 61;
53 | END_OF_TRACK = 62;
54 | CACHE_LOAD_POLICY = 63;
55 | LAWNMOWER_MESSAGING_POLICY = 64;
56 | PREWARM_CONNECTION = 65;
57 | PLAYBACK_DEBUG_INFO = 66;
58 | // Directive to show the user a notification message.
59 | SNACKBAR_MESSAGE = 67;
60 | }
--------------------------------------------------------------------------------
/examples/onesie-request/utils.ts:
--------------------------------------------------------------------------------
1 | import crypto from 'crypto';
2 |
3 | type Encrypted = {
4 | encrypted: Uint8Array;
5 | hmac: Uint8Array;
6 | iv: Uint8Array;
7 | };
8 |
9 | export async function encryptRequest(clientKey: Uint8Array, data: Uint8Array): Promise {
10 | if (clientKey.length !== 32)
11 | throw new Error('Invalid client key length');
12 |
13 | const aesKeyData = clientKey.slice(0, 16);
14 | const hmacKeyData = clientKey.slice(16, 32);
15 |
16 | const iv = crypto.getRandomValues(new Uint8Array(16));
17 |
18 | const aesKey = await crypto.subtle.importKey(
19 | 'raw',
20 | aesKeyData,
21 | { name: 'AES-CTR', length: 128 },
22 | false,
23 | [ 'encrypt' ]
24 | );
25 |
26 | const encrypted = new Uint8Array(await crypto.subtle.encrypt(
27 | { name: 'AES-CTR', counter: iv, length: 128 },
28 | aesKey,
29 | data
30 | ));
31 |
32 | const hmacKey = await crypto.subtle.importKey(
33 | 'raw',
34 | hmacKeyData,
35 | { name: 'HMAC', hash: { name: 'SHA-256' } },
36 | false,
37 | [ 'sign' ]
38 | );
39 |
40 | const hmac = new Uint8Array(await crypto.subtle.sign(
41 | 'HMAC',
42 | hmacKey,
43 | new Uint8Array([ ...encrypted, ...iv ])
44 | ));
45 |
46 | return { encrypted, hmac, iv };
47 | }
48 |
49 | export async function decryptResponse(iv?: Uint8Array, hmac?: Uint8Array, data?: Uint8Array, clientKeyData?: Uint8Array): Promise {
50 | if (!iv || !hmac || !data || !clientKeyData)
51 | throw new Error('Invalid input');
52 |
53 | const aesKey = await crypto.subtle.importKey(
54 | 'raw',
55 | clientKeyData.slice(0, 16),
56 | { name: 'AES-CTR', length: 128 },
57 | false,
58 | [ 'decrypt' ]
59 | );
60 |
61 | const decryptedData = new Uint8Array(await crypto.subtle.decrypt(
62 | { name: 'AES-CTR', counter: iv, length: 128 },
63 | aesKey,
64 | data
65 | ));
66 |
67 | const hmacKey = await crypto.subtle.importKey(
68 | 'raw',
69 | clientKeyData.slice(16, 32),
70 | { name: 'HMAC', hash: { name: 'SHA-256' } },
71 | false,
72 | [ 'verify' ]
73 | );
74 |
75 | const isValid = await crypto.subtle.verify(
76 | 'HMAC',
77 | hmacKey,
78 | hmac,
79 | new Uint8Array([ ...data, ...iv ])
80 | );
81 |
82 | if (!isValid)
83 | throw new Error('HMAC verification failed');
84 |
85 | return decryptedData;
86 | }
--------------------------------------------------------------------------------
/docs/api/exports/utils/classes/RequestMetadataManager.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/utils](../README.md) / RequestMetadataManager
2 |
3 | # Class: RequestMetadataManager
4 |
5 | Defined in: [codeberg/googlevideo/src/utils/RequestMetadataManager.ts:6](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/RequestMetadataManager.ts#L6)
6 |
7 | Manages request metadata objects.
8 |
9 | ## Constructors
10 |
11 | ### Constructor
12 |
13 | > **new RequestMetadataManager**(): `RequestMetadataManager`
14 |
15 | Defined in: [codeberg/googlevideo/src/utils/RequestMetadataManager.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/RequestMetadataManager.ts#L12)
16 |
17 | #### Returns
18 |
19 | `RequestMetadataManager`
20 |
21 | ## Properties
22 |
23 | ### metadataMap
24 |
25 | > **metadataMap**: `Map`\<`string`, [`SabrRequestMetadata`](../../sabr-streaming-adapter/interfaces/SabrRequestMetadata.md)\>
26 |
27 | Defined in: [codeberg/googlevideo/src/utils/RequestMetadataManager.ts:7](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/RequestMetadataManager.ts#L7)
28 |
29 | ## Methods
30 |
31 | ### getRequestMetadata()
32 |
33 | > **getRequestMetadata**(`url`, `del`): `undefined` \| [`SabrRequestMetadata`](../../sabr-streaming-adapter/interfaces/SabrRequestMetadata.md)
34 |
35 | Defined in: [codeberg/googlevideo/src/utils/RequestMetadataManager.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/RequestMetadataManager.ts#L17)
36 |
37 | #### Parameters
38 |
39 | ##### url
40 |
41 | `string`
42 |
43 | ##### del
44 |
45 | `boolean` = `false`
46 |
47 | #### Returns
48 |
49 | `undefined` \| [`SabrRequestMetadata`](../../sabr-streaming-adapter/interfaces/SabrRequestMetadata.md)
50 |
51 | ***
52 |
53 | ### setRequestMetadata()
54 |
55 | > **setRequestMetadata**(`url`, `context`): `void`
56 |
57 | Defined in: [codeberg/googlevideo/src/utils/RequestMetadataManager.ts:37](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/utils/RequestMetadataManager.ts#L37)
58 |
59 | #### Parameters
60 |
61 | ##### url
62 |
63 | `string`
64 |
65 | ##### context
66 |
67 | [`SabrRequestMetadata`](../../sabr-streaming-adapter/interfaces/SabrRequestMetadata.md)
68 |
69 | #### Returns
70 |
71 | `void`
72 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/issue.yml:
--------------------------------------------------------------------------------
1 | name: Issue Report
2 | title: " "
3 | description: Use this template to report a problem
4 | labels: [bug]
5 | body:
6 | - type: textarea
7 | id: reproduce-steps
8 | attributes:
9 | label: Steps to reproduce
10 | description: Please provide detailed steps for reproducing the issue.
11 | placeholder: |
12 | Example:
13 | 1. Step 1
14 | 2. Step 2
15 | 3. You get it..
16 | validations:
17 | required: true
18 |
19 | - type: textarea
20 | id: failure-logs
21 | attributes:
22 | label: Failure Logs
23 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
24 | render: shell
25 | validations:
26 | required: true
27 |
28 | - type: textarea
29 | id: expected-behavior
30 | attributes:
31 | label: Expected behavior
32 | description: What did you expect to happen?
33 | validations:
34 | required: true
35 |
36 | - type: textarea
37 | id: current-behavior
38 | attributes:
39 | label: Current behavior
40 | description: What is the current behavior?
41 | validations:
42 | required: true
43 |
44 | - type: dropdown
45 | id: version
46 | attributes:
47 | label: Version
48 | description: What version of the library are you running?
49 | options:
50 | - Default
51 | - Edge
52 | validations:
53 | required: true
54 |
55 | - type: textarea
56 | attributes:
57 | label: Anything else?
58 | description: |
59 | Links? References? Anything that will give us more context about the issue you are encountering!
60 |
61 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
62 | validations:
63 | required: false
64 |
65 | - type: checkboxes
66 | id: checklist
67 | attributes:
68 | label: Checklist
69 | options:
70 | - label: I am running the latest version.
71 | required: false
72 | - label: I checked the documentation and found no answer.
73 | required: true
74 | - label: I have searched the existing issues and made sure this is not a duplicate.
75 | required: true
76 | - label: I have provided sufficient information.
77 | required: true
--------------------------------------------------------------------------------
/examples/onesie-request/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "onesie-request",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "onesie-request",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "googlevideo": "file:../..",
13 | "youtubei.js": "^16.0.0"
14 | }
15 | },
16 | "../..": {
17 | "version": "4.0.4",
18 | "funding": [
19 | "https://github.com/sponsors/LuanRT"
20 | ],
21 | "license": "MIT",
22 | "dependencies": {
23 | "@bufbuild/protobuf": "^2.0.0"
24 | },
25 | "devDependencies": {
26 | "@eslint/js": "^9.9.0",
27 | "@stylistic/eslint-plugin": "^2.6.4",
28 | "@types/eslint__js": "^8.42.3",
29 | "eslint": "^9.9.0",
30 | "globals": "^15.9.0",
31 | "ts-patch": "^3.3.0",
32 | "ts-proto": "^2.2.0",
33 | "typedoc": "^0.28.7",
34 | "typedoc-plugin-markdown": "^4.7.1",
35 | "typescript": "^5.5.4",
36 | "typescript-eslint": "^8.2.0",
37 | "vitest": "^3.2.4"
38 | }
39 | },
40 | "node_modules/@bufbuild/protobuf": {
41 | "version": "2.2.3",
42 | "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.3.tgz",
43 | "integrity": "sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg=="
44 | },
45 | "node_modules/googlevideo": {
46 | "resolved": "../..",
47 | "link": true
48 | },
49 | "node_modules/meriyah": {
50 | "version": "6.1.4",
51 | "resolved": "https://registry.npmjs.org/meriyah/-/meriyah-6.1.4.tgz",
52 | "integrity": "sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==",
53 | "license": "ISC",
54 | "engines": {
55 | "node": ">=18.0.0"
56 | }
57 | },
58 | "node_modules/youtubei.js": {
59 | "version": "16.0.0",
60 | "resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-16.0.0.tgz",
61 | "integrity": "sha512-aMx+ulnrxzsgVsxTr7gbBVnIjti2NQUlMwCoo1/MzICCJS3iMLOPUFdo7bSpwskL6ljzQ/LxmmB4WQC3FtkBlA==",
62 | "funding": [
63 | "https://github.com/sponsors/LuanRT"
64 | ],
65 | "license": "MIT",
66 | "dependencies": {
67 | "@bufbuild/protobuf": "^2.0.0",
68 | "meriyah": "^6.1.4"
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/protos/video_streaming/client_abr_state.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package video_streaming;
3 |
4 | import "misc/common.proto";
5 | import "video_streaming/media_capabilities.proto";
6 |
7 | message ClientAbrState {
8 | optional int64 time_since_last_manual_format_selection_ms = 13;
9 | optional sint32 last_manual_direction = 14;
10 | optional int32 last_manual_selected_resolution = 16;
11 | optional int32 detailed_network_type = 17;
12 | optional int32 client_viewport_width = 18;
13 | optional int32 client_viewport_height = 19;
14 | optional int64 client_bitrate_cap_bytes_per_sec = 20;
15 | optional int32 sticky_resolution = 21;
16 | optional bool client_viewport_is_flexible = 22;
17 | optional int64 bandwidth_estimate = 23;
18 | optional .misc.AudioQuality min_audio_quality = 24;
19 | optional .misc.AudioQuality max_audio_quality = 25;
20 | optional .misc.VideoQualitySetting video_quality_setting = 26;
21 | optional .misc.PlaybackAudioRouteOutputType audio_route = 27;
22 | optional int64 player_time_ms = 28;
23 | optional int64 time_since_last_seek = 29;
24 | optional bool data_saver_mode = 30;
25 | optional .misc.NetworkMeteredState network_metered_state = 32;
26 | optional int32 visibility = 34;
27 | optional float playback_rate = 35;
28 | optional int64 elapsed_wall_time_ms = 36;
29 | optional MediaCapabilities media_capabilities = 38;
30 | optional int64 time_since_last_action_ms = 39;
31 | optional int32 enabled_track_types_bitfield = 40;
32 | optional int32 max_pacing_rate = 43;
33 | optional int64 player_state = 44;
34 | optional bool drc_enabled = 46;
35 | optional int32 field48 = 48;
36 | optional int32 field50 = 50;
37 | optional int32 field51 = 51;
38 | optional int32 sabr_report_request_cancellation_info = 54;
39 | optional bool disable_streaming_xhr = 56;
40 | optional int64 field57 = 57;
41 | optional bool prefer_vp9 = 58;
42 | optional int32 av1_quality_threshold = 59; // 2160
43 | optional int32 field60 = 60;
44 | optional bool is_prefetch = 61;
45 | optional bool sabr_support_quality_constraints = 62;
46 | optional bytes sabr_license_constraint = 63;
47 | optional int32 allow_proxima_live_latency = 64;
48 | optional int32 sabr_force_proxima = 66;
49 | optional int32 field67 = 67;
50 | optional int64 sabr_force_max_network_interruption_duration_ms = 68;
51 | optional string audio_track_id = 69;
52 | optional bool enable_voice_boost = 76;
53 | optional .misc.PlaybackAuthorization playback_authorization = 79;
54 | }
55 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/time_range.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/time_range.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 |
10 | export const protobufPackage = "video_streaming";
11 |
12 | export interface TimeRange {
13 | startTicks?: string | undefined;
14 | durationTicks?: string | undefined;
15 | timescale?: number | undefined;
16 | }
17 |
18 | function createBaseTimeRange(): TimeRange {
19 | return { startTicks: "0", durationTicks: "0", timescale: 0 };
20 | }
21 |
22 | export const TimeRange: MessageFns = {
23 | encode(message: TimeRange, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
24 | if (message.startTicks !== undefined && message.startTicks !== "0") {
25 | writer.uint32(8).int64(message.startTicks);
26 | }
27 | if (message.durationTicks !== undefined && message.durationTicks !== "0") {
28 | writer.uint32(16).int64(message.durationTicks);
29 | }
30 | if (message.timescale !== undefined && message.timescale !== 0) {
31 | writer.uint32(24).int32(message.timescale);
32 | }
33 | return writer;
34 | },
35 |
36 | decode(input: BinaryReader | Uint8Array, length?: number): TimeRange {
37 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
38 | const end = length === undefined ? reader.len : reader.pos + length;
39 | const message = createBaseTimeRange();
40 | while (reader.pos < end) {
41 | const tag = reader.uint32();
42 | switch (tag >>> 3) {
43 | case 1: {
44 | if (tag !== 8) {
45 | break;
46 | }
47 |
48 | message.startTicks = reader.int64().toString();
49 | continue;
50 | }
51 | case 2: {
52 | if (tag !== 16) {
53 | break;
54 | }
55 |
56 | message.durationTicks = reader.int64().toString();
57 | continue;
58 | }
59 | case 3: {
60 | if (tag !== 24) {
61 | break;
62 | }
63 |
64 | message.timescale = reader.int32();
65 | continue;
66 | }
67 | }
68 | if ((tag & 7) === 4 || tag === 0) {
69 | break;
70 | }
71 | reader.skip(tag & 7);
72 | }
73 | return message;
74 | },
75 | };
76 |
77 | export interface MessageFns {
78 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
79 | decode(input: BinaryReader | Uint8Array, length?: number): T;
80 | }
81 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/crypto_params.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/crypto_params.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 | import { CompressionType } from "../misc/common.js";
10 |
11 | export const protobufPackage = "video_streaming";
12 |
13 | export interface CryptoParams {
14 | hmac?: Uint8Array | undefined;
15 | iv?: Uint8Array | undefined;
16 | compressionType?: CompressionType | undefined;
17 | }
18 |
19 | function createBaseCryptoParams(): CryptoParams {
20 | return { hmac: new Uint8Array(0), iv: new Uint8Array(0), compressionType: 0 };
21 | }
22 |
23 | export const CryptoParams: MessageFns = {
24 | encode(message: CryptoParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
25 | if (message.hmac !== undefined && message.hmac.length !== 0) {
26 | writer.uint32(34).bytes(message.hmac);
27 | }
28 | if (message.iv !== undefined && message.iv.length !== 0) {
29 | writer.uint32(42).bytes(message.iv);
30 | }
31 | if (message.compressionType !== undefined && message.compressionType !== 0) {
32 | writer.uint32(48).int32(message.compressionType);
33 | }
34 | return writer;
35 | },
36 |
37 | decode(input: BinaryReader | Uint8Array, length?: number): CryptoParams {
38 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
39 | const end = length === undefined ? reader.len : reader.pos + length;
40 | const message = createBaseCryptoParams();
41 | while (reader.pos < end) {
42 | const tag = reader.uint32();
43 | switch (tag >>> 3) {
44 | case 4: {
45 | if (tag !== 34) {
46 | break;
47 | }
48 |
49 | message.hmac = reader.bytes();
50 | continue;
51 | }
52 | case 5: {
53 | if (tag !== 42) {
54 | break;
55 | }
56 |
57 | message.iv = reader.bytes();
58 | continue;
59 | }
60 | case 6: {
61 | if (tag !== 48) {
62 | break;
63 | }
64 |
65 | message.compressionType = reader.int32() as any;
66 | continue;
67 | }
68 | }
69 | if ((tag & 7) === 4 || tag === 0) {
70 | break;
71 | }
72 | reader.skip(tag & 7);
73 | }
74 | return message;
75 | },
76 | };
77 |
78 | export interface MessageFns {
79 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
80 | decode(input: BinaryReader | Uint8Array, length?: number): T;
81 | }
82 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/sabr_seek.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/sabr_seek.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 | import { SeekSource } from "../misc/common.js";
10 |
11 | export const protobufPackage = "video_streaming";
12 |
13 | export interface SabrSeek {
14 | seekMediaTime?: string | undefined;
15 | seekMediaTimescale?: number | undefined;
16 | seekSource?: SeekSource | undefined;
17 | }
18 |
19 | function createBaseSabrSeek(): SabrSeek {
20 | return { seekMediaTime: "0", seekMediaTimescale: 0, seekSource: 0 };
21 | }
22 |
23 | export const SabrSeek: MessageFns = {
24 | encode(message: SabrSeek, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
25 | if (message.seekMediaTime !== undefined && message.seekMediaTime !== "0") {
26 | writer.uint32(8).int64(message.seekMediaTime);
27 | }
28 | if (message.seekMediaTimescale !== undefined && message.seekMediaTimescale !== 0) {
29 | writer.uint32(16).int32(message.seekMediaTimescale);
30 | }
31 | if (message.seekSource !== undefined && message.seekSource !== 0) {
32 | writer.uint32(24).int32(message.seekSource);
33 | }
34 | return writer;
35 | },
36 |
37 | decode(input: BinaryReader | Uint8Array, length?: number): SabrSeek {
38 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
39 | const end = length === undefined ? reader.len : reader.pos + length;
40 | const message = createBaseSabrSeek();
41 | while (reader.pos < end) {
42 | const tag = reader.uint32();
43 | switch (tag >>> 3) {
44 | case 1: {
45 | if (tag !== 8) {
46 | break;
47 | }
48 |
49 | message.seekMediaTime = reader.int64().toString();
50 | continue;
51 | }
52 | case 2: {
53 | if (tag !== 16) {
54 | break;
55 | }
56 |
57 | message.seekMediaTimescale = reader.int32();
58 | continue;
59 | }
60 | case 3: {
61 | if (tag !== 24) {
62 | break;
63 | }
64 |
65 | message.seekSource = reader.int32() as any;
66 | continue;
67 | }
68 | }
69 | if ((tag & 7) === 4 || tag === 0) {
70 | break;
71 | }
72 | reader.skip(tag & 7);
73 | }
74 | return message;
75 | },
76 | };
77 |
78 | export interface MessageFns {
79 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
80 | decode(input: BinaryReader | Uint8Array, length?: number): T;
81 | }
82 |
--------------------------------------------------------------------------------
/src/utils/EventEmitterLike.ts:
--------------------------------------------------------------------------------
1 | // See https://github.com/nodejs/node/issues/40678#issuecomment-1126944677
2 | class CustomEvent extends Event {
3 | #detail;
4 |
5 | constructor(type: string, options?: CustomEventInit) {
6 | super(type, options);
7 | this.#detail = options?.detail ?? null;
8 | }
9 |
10 | get detail(): any[] | null {
11 | return this.#detail;
12 | }
13 | }
14 |
15 | export class SabrAdapterError extends Error {
16 | constructor(message: string, public code?: string) {
17 | super(`[SabrStreamingAdapter] ${message}`);
18 | this.name = 'SabrAdapterError';
19 | }
20 | }
21 |
22 | export class EventEmitterLike extends EventTarget {
23 | #legacyListeners = new Map<(...args: any[]) => void, { type: string, wrapper: EventListener }>();
24 |
25 | constructor() {
26 | super();
27 | }
28 |
29 | emit(type: string, ...args: any[]) {
30 | const event = new CustomEvent(type, { detail: args });
31 | this.dispatchEvent(event);
32 | }
33 |
34 | on(type: string, listener: (...args: any[]) => void) {
35 | const wrapper: EventListener = (ev) => {
36 | if (ev instanceof CustomEvent) {
37 | listener(...ev.detail as any[]);
38 | } else {
39 | listener(ev);
40 | }
41 | };
42 | this.#legacyListeners.set(listener, { type, wrapper });
43 | this.addEventListener(type, wrapper);
44 | }
45 |
46 | once(type: string, listener: (...args: any[]) => void) {
47 | const wrapper: EventListener = (ev) => {
48 | if (ev instanceof CustomEvent) {
49 | listener(...ev.detail as any[]);
50 | } else {
51 | listener(ev);
52 | }
53 | this.off(type, listener);
54 | };
55 | this.#legacyListeners.set(listener, { type, wrapper });
56 | this.addEventListener(type, wrapper);
57 | }
58 |
59 | off(type: string, listener: (...args: any[]) => void) {
60 | const listenerData = this.#legacyListeners.get(listener);
61 | if (listenerData && listenerData.type === type) {
62 | this.removeEventListener(type, listenerData.wrapper);
63 | this.#legacyListeners.delete(listener);
64 | }
65 | }
66 |
67 | removeAllListeners(type?: string) {
68 | if (type) {
69 | for (const [ listener, listenerData ] of this.#legacyListeners.entries()) {
70 | if (listenerData.type === type) {
71 | this.removeEventListener(type, listenerData.wrapper);
72 | this.#legacyListeners.delete(listener);
73 | }
74 | }
75 | } else {
76 | for (const [ listener, listenerData ] of this.#legacyListeners.entries()) {
77 | this.removeEventListener(listenerData.type, listenerData.wrapper);
78 | this.#legacyListeners.delete(listener);
79 | }
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/classes/SabrUmpProcessor.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / SabrUmpProcessor
2 |
3 | # Class: SabrUmpProcessor
4 |
5 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:47](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L47)
6 |
7 | This class is responsible for reading a UMP stream, handling different part types
8 | (like media headers, media data, and server directives), and populating a
9 | metadata object with the extracted information. It is supposed to be used
10 | in conjunction with a [`SabrPlayerAdapter`](../interfaces/SabrPlayerAdapter.md) in video player
11 | implementations.
12 |
13 | ## Constructors
14 |
15 | ### Constructor
16 |
17 | > **new SabrUmpProcessor**(`requestMetadata`, `cacheManager?`): `SabrUmpProcessor`
18 |
19 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:68](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L68)
20 |
21 | #### Parameters
22 |
23 | ##### requestMetadata
24 |
25 | [`SabrRequestMetadata`](../interfaces/SabrRequestMetadata.md)
26 |
27 | ##### cacheManager?
28 |
29 | [`CacheManager`](../../utils/classes/CacheManager.md)
30 |
31 | #### Returns
32 |
33 | `SabrUmpProcessor`
34 |
35 | ## Properties
36 |
37 | ### partialPart?
38 |
39 | > `optional` **partialPart**: [`Part`](../../../types/shared/type-aliases/Part.md)
40 |
41 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:48](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L48)
42 |
43 | ## Methods
44 |
45 | ### getSegmentInfo()
46 |
47 | > **getSegmentInfo**(): `undefined` \| `Segment`
48 |
49 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:106](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L106)
50 |
51 | #### Returns
52 |
53 | `undefined` \| `Segment`
54 |
55 | ***
56 |
57 | ### processChunk()
58 |
59 | > **processChunk**(`value`): `Promise`\<`undefined` \| [`UmpProcessingResult`](../interfaces/UmpProcessingResult.md)\>
60 |
61 | Defined in: [codeberg/googlevideo/src/core/SabrUmpProcessor.ts:78](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/core/SabrUmpProcessor.ts#L78)
62 |
63 | Processes a chunk of data from a UMP stream and updates the request context.
64 |
65 | #### Parameters
66 |
67 | ##### value
68 |
69 | `Uint8Array`
70 |
71 | #### Returns
72 |
73 | `Promise`\<`undefined` \| [`UmpProcessingResult`](../interfaces/UmpProcessingResult.md)\>
74 |
75 | A promise that resolves with a processing result if a terminal part is found (e.g., MediaEnd), or undefined otherwise.
76 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/ump_part_id.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/ump_part_id.proto
6 |
7 | /* eslint-disable */
8 |
9 | export const protobufPackage = "video_streaming";
10 |
11 | export enum UMPPartId {
12 | UNKNOWN = 0,
13 | ONESIE_HEADER = 10,
14 | ONESIE_DATA = 11,
15 | ONESIE_ENCRYPTED_MEDIA = 12,
16 | /** MEDIA_HEADER - Header for a media segment; includes sequence and timing information. */
17 | MEDIA_HEADER = 20,
18 | /** MEDIA - Chunk of media segment data. */
19 | MEDIA = 21,
20 | /** MEDIA_END - Indicates end of media segment; finalizes segment processing. */
21 | MEDIA_END = 22,
22 | CONFIG = 30,
23 | LIVE_METADATA = 31,
24 | HOSTNAME_CHANGE_HINT_DEPRECATED = 32,
25 | LIVE_METADATA_PROMISE = 33,
26 | LIVE_METADATA_PROMISE_CANCELLATION = 34,
27 | /** NEXT_REQUEST_POLICY - Server's policy for the next request; includes backoff time and playback cookie. */
28 | NEXT_REQUEST_POLICY = 35,
29 | USTREAMER_VIDEO_AND_FORMAT_METADATA = 36,
30 | FORMAT_SELECTION_CONFIG = 37,
31 | USTREAMER_SELECTED_MEDIA_STREAM = 38,
32 | /** FORMAT_INITIALIZATION_METADATA - Metadata for format initialization; contains total number of segments, duration, etc. */
33 | FORMAT_INITIALIZATION_METADATA = 42,
34 | /** SABR_REDIRECT - Indicates a redirect to a different streaming URL. */
35 | SABR_REDIRECT = 43,
36 | /** SABR_ERROR - Indicates a SABR error; happens when the payload is invalid or the server cannot process the request. */
37 | SABR_ERROR = 44,
38 | SABR_SEEK = 45,
39 | /** RELOAD_PLAYER_RESPONSE - Directive to reload the player with new parameters. */
40 | RELOAD_PLAYER_RESPONSE = 46,
41 | PLAYBACK_START_POLICY = 47,
42 | ALLOWED_CACHED_FORMATS = 48,
43 | START_BW_SAMPLING_HINT = 49,
44 | PAUSE_BW_SAMPLING_HINT = 50,
45 | SELECTABLE_FORMATS = 51,
46 | REQUEST_IDENTIFIER = 52,
47 | REQUEST_CANCELLATION_POLICY = 53,
48 | ONESIE_PREFETCH_REJECTION = 54,
49 | TIMELINE_CONTEXT = 55,
50 | REQUEST_PIPELINING = 56,
51 | /** SABR_CONTEXT_UPDATE - Updates SABR context data; usually used for ads. */
52 | SABR_CONTEXT_UPDATE = 57,
53 | /** STREAM_PROTECTION_STATUS - Status of stream protection; indicates whether attestation is required. */
54 | STREAM_PROTECTION_STATUS = 58,
55 | /** SABR_CONTEXT_SENDING_POLICY - Policy indicating which SABR contexts to send or discard in future requests. */
56 | SABR_CONTEXT_SENDING_POLICY = 59,
57 | LAWNMOWER_POLICY = 60,
58 | SABR_ACK = 61,
59 | END_OF_TRACK = 62,
60 | CACHE_LOAD_POLICY = 63,
61 | LAWNMOWER_MESSAGING_POLICY = 64,
62 | PREWARM_CONNECTION = 65,
63 | PLAYBACK_DEBUG_INFO = 66,
64 | /** SNACKBAR_MESSAGE - Directive to show the user a notification message. */
65 | SNACKBAR_MESSAGE = 67,
66 | UNRECOGNIZED = -1,
67 | }
68 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/format_selection_config.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/format_selection_config.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 |
10 | export const protobufPackage = "video_streaming";
11 |
12 | export interface FormatSelectionConfig {
13 | itags: number[];
14 | videoId?: string | undefined;
15 | resolution?: number | undefined;
16 | }
17 |
18 | function createBaseFormatSelectionConfig(): FormatSelectionConfig {
19 | return { itags: [], videoId: "", resolution: 0 };
20 | }
21 |
22 | export const FormatSelectionConfig: MessageFns = {
23 | encode(message: FormatSelectionConfig, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
24 | writer.uint32(18).fork();
25 | for (const v of message.itags) {
26 | writer.int32(v);
27 | }
28 | writer.join();
29 | if (message.videoId !== undefined && message.videoId !== "") {
30 | writer.uint32(26).string(message.videoId);
31 | }
32 | if (message.resolution !== undefined && message.resolution !== 0) {
33 | writer.uint32(32).int32(message.resolution);
34 | }
35 | return writer;
36 | },
37 |
38 | decode(input: BinaryReader | Uint8Array, length?: number): FormatSelectionConfig {
39 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
40 | const end = length === undefined ? reader.len : reader.pos + length;
41 | const message = createBaseFormatSelectionConfig();
42 | while (reader.pos < end) {
43 | const tag = reader.uint32();
44 | switch (tag >>> 3) {
45 | case 2: {
46 | if (tag === 16) {
47 | message.itags.push(reader.int32());
48 |
49 | continue;
50 | }
51 |
52 | if (tag === 18) {
53 | const end2 = reader.uint32() + reader.pos;
54 | while (reader.pos < end2) {
55 | message.itags.push(reader.int32());
56 | }
57 |
58 | continue;
59 | }
60 |
61 | break;
62 | }
63 | case 3: {
64 | if (tag !== 26) {
65 | break;
66 | }
67 |
68 | message.videoId = reader.string();
69 | continue;
70 | }
71 | case 4: {
72 | if (tag !== 32) {
73 | break;
74 | }
75 |
76 | message.resolution = reader.int32();
77 | continue;
78 | }
79 | }
80 | if ((tag & 7) === 4 || tag === 0) {
81 | break;
82 | }
83 | reader.skip(tag & 7);
84 | }
85 | return message;
86 | },
87 | };
88 |
89 | export interface MessageFns {
90 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
91 | decode(input: BinaryReader | Uint8Array, length?: number): T;
92 | }
93 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "googlevideo",
3 | "version": "4.0.4",
4 | "description": "A collection of modules for working with YouTube's proprietary video streaming protocols (UMP/SABR).",
5 | "type": "module",
6 | "scripts": {
7 | "watch": "npx tspc --watch",
8 | "lint": "npx eslint ./src/**/*.ts",
9 | "lint:fix": "npx eslint --fix ./src/**/*.ts",
10 | "clean": "npx rimraf ./dist ./protos/generated",
11 | "build": "npm run clean && npm run lint && npm run build:proto && npm run build:esm",
12 | "build:esm": "npx tspc",
13 | "build:proto": "node ./dev-scripts/generate-proto.mjs",
14 | "build:docs": "typedoc",
15 | "test": "vitest run --reporter verbose",
16 | "test:watch": "vitest",
17 | "prepare": "npm run build"
18 | },
19 | "author": "LuanRT (https://github.com/LuanRT)",
20 | "funding": [
21 | "https://github.com/sponsors/LuanRT"
22 | ],
23 | "keywords": [
24 | "UMP",
25 | "SABR",
26 | "Google",
27 | "YouTube"
28 | ],
29 | "license": "MIT",
30 | "exports": {
31 | "./ump": {
32 | "types": "./dist/src/exports/ump.d.ts",
33 | "import": "./dist/src/exports/ump.js",
34 | "default": "./dist/src/exports/ump.js"
35 | },
36 | "./sabr-streaming-adapter": {
37 | "types": "./dist/src/exports/sabr-streaming-adapter.d.ts",
38 | "import": "./dist/src/exports/sabr-streaming-adapter.js",
39 | "default": "./dist/src/exports/sabr-streaming-adapter.js"
40 | },
41 | "./sabr-stream": {
42 | "types": "./dist/src/exports/sabr-stream.d.ts",
43 | "import": "./dist/src/exports/sabr-stream.js",
44 | "default": "./dist/src/exports/sabr-stream.js"
45 | },
46 | "./protos": {
47 | "types": "./dist/src/exports/protos.d.ts",
48 | "import": "./dist/src/exports/protos.js",
49 | "default": "./dist/src/exports/protos.js"
50 | },
51 | "./utils": {
52 | "types": "./dist/src/exports/utils.d.ts",
53 | "import": "./dist/src/exports/utils.js",
54 | "default": "./dist/src/exports/utils.js"
55 | },
56 | "./shared-types": {
57 | "types": "./dist/src/types/shared.d.ts"
58 | }
59 | },
60 | "devDependencies": {
61 | "@eslint/js": "^9.9.0",
62 | "@stylistic/eslint-plugin": "^2.6.4",
63 | "@types/eslint__js": "^8.42.3",
64 | "eslint": "^9.9.0",
65 | "globals": "^15.9.0",
66 | "ts-patch": "^3.3.0",
67 | "ts-proto": "^2.2.0",
68 | "typedoc": "^0.28.7",
69 | "typedoc-plugin-markdown": "^4.7.1",
70 | "typescript": "^5.5.4",
71 | "typescript-eslint": "^8.2.0",
72 | "vitest": "^3.2.4"
73 | },
74 | "dependencies": {
75 | "@bufbuild/protobuf": "^2.0.0"
76 | },
77 | "bugs": {
78 | "url": "https://github.com/LuanRT/GoogleVideo/issues"
79 | },
80 | "homepage": "https://github.com/LuanRT/GoogleVideo#readme",
81 | "repository": {
82 | "type": "git",
83 | "url": "git+https://github.com/LuanRT/GoogleVideo.git"
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/docs/api/exports/sabr-streaming-adapter/interfaces/SabrOptions.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/sabr-streaming-adapter](../README.md) / SabrOptions
2 |
3 | # Interface: SabrOptions
4 |
5 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:43](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L43)
6 |
7 | ## Properties
8 |
9 | ### clientInfo?
10 |
11 | > `optional` **clientInfo**: [`ClientInfo`](../../protos/interfaces/ClientInfo.md)
12 |
13 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:72](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L72)
14 |
15 | Client information to send with SABR requests.
16 |
17 | ***
18 |
19 | ### enableCaching?
20 |
21 | > `optional` **enableCaching**: `boolean`
22 |
23 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:48](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L48)
24 |
25 | Whether to enable caching of SABR segments.
26 |
27 | #### Default
28 |
29 | ```ts
30 | true
31 | ```
32 |
33 | ***
34 |
35 | ### enableVerboseRequestLogging?
36 |
37 | > `optional` **enableVerboseRequestLogging**: `boolean`
38 |
39 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:54](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L54)
40 |
41 | Enables verbose logging of all SABR requests made by the player.
42 | @NOTE: `DEBUG` level logging must be enabled for this to take effect.
43 |
44 | #### Default
45 |
46 | ```ts
47 | false
48 | ```
49 |
50 | ***
51 |
52 | ### maxCacheAgeSeconds?
53 |
54 | > `optional` **maxCacheAgeSeconds**: `number`
55 |
56 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:64](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L64)
57 |
58 | Maximum age of cached segments in seconds.
59 |
60 | #### Default
61 |
62 | ```ts
63 | 300 (5 minutes)
64 | ```
65 |
66 | ***
67 |
68 | ### maxCacheSizeMB?
69 |
70 | > `optional` **maxCacheSizeMB**: `number`
71 |
72 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:59](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L59)
73 |
74 | Maximum size of the segment cache in megabytes.
75 |
76 | #### Default
77 |
78 | ```ts
79 | 3
80 | ```
81 |
82 | ***
83 |
84 | ### playerAdapter?
85 |
86 | > `optional` **playerAdapter**: [`SabrPlayerAdapter`](SabrPlayerAdapter.md)
87 |
88 | Defined in: [codeberg/googlevideo/src/types/sabrStreamingAdapterTypes.ts:68](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/src/types/sabrStreamingAdapterTypes.ts#L68)
89 |
90 | Player adapter to use for SABR streaming.
91 |
--------------------------------------------------------------------------------
/src/utils/Logger.ts:
--------------------------------------------------------------------------------
1 | export enum LogLevel {
2 | NONE = 0,
3 | ERROR = 1,
4 | WARN = 2,
5 | INFO = 3,
6 | DEBUG = 4,
7 | ALL = 99,
8 | }
9 |
10 | /**
11 | * Singleton logger utility.
12 | *
13 | * Allows enabling or disabling specific log levels (`ERROR`, `WARN`, `INFO`, `DEBUG`)
14 | * at runtime. Supports logging with tags and message arguments.
15 | *
16 | * Usage:
17 | * ```ts
18 | * const logger = Logger.getInstance();
19 | * logger.setLogLevels(LogLevel.ERROR, LogLevel.INFO);
20 | * logger.error('MyTag', 'An error occurred');
21 | * ```
22 | */
23 | export class Logger {
24 | private static instance: Logger;
25 | private currentLogLevels: Set = new Set([ LogLevel.INFO, LogLevel.ERROR ]);
26 |
27 | public static getInstance(): Logger {
28 | if (!Logger.instance) {
29 | Logger.instance = new Logger();
30 | }
31 | return Logger.instance;
32 | }
33 |
34 | /**
35 | * Sets the active log levels.
36 | * Call with LogLevel.NONE or no arguments to turn off all logging.
37 | * Otherwise, specify one or more log levels to be active.
38 | * Use LogLevel.ALL to enable all log levels.
39 | */
40 | public setLogLevels(...levels: LogLevel[]): void {
41 | if (levels.length === 0 || levels.includes(LogLevel.NONE)) {
42 | this.currentLogLevels = new Set(); // Turn off logging
43 | } else if (levels.includes(LogLevel.ALL)) {
44 | this.currentLogLevels = new Set([
45 | LogLevel.ERROR,
46 | LogLevel.WARN,
47 | LogLevel.INFO,
48 | LogLevel.DEBUG
49 | ]);
50 | } else {
51 | this.currentLogLevels = new Set(levels.filter((level) => level !== LogLevel.NONE && level !== LogLevel.ALL));
52 | }
53 | }
54 |
55 | /**
56 | * Gets the current set of active log levels.
57 | * @returns A new Set containing the active LogLevel enums.
58 | */
59 | public getLogLevels(): Set {
60 | return new Set(this.currentLogLevels);
61 | }
62 |
63 | private log(level: LogLevel, tag: string, ...messages: any[]): void {
64 | if (level !== LogLevel.NONE && this.currentLogLevels.has(level)) {
65 | const prefix = `[${LogLevel[level]}] [${tag}]`;
66 | switch (level) {
67 | case LogLevel.ERROR:
68 | console.error(prefix, ...messages);
69 | break;
70 | case LogLevel.WARN:
71 | console.warn(prefix, ...messages);
72 | break;
73 | case LogLevel.INFO:
74 | console.info(prefix, ...messages);
75 | break;
76 | case LogLevel.DEBUG:
77 | console.debug(prefix, ...messages);
78 | break;
79 | }
80 | }
81 | }
82 |
83 | public error(tag: string, ...messages: any[]): void {
84 | this.log(LogLevel.ERROR, tag, ...messages);
85 | }
86 |
87 | public warn(tag: string, ...messages: any[]): void {
88 | this.log(LogLevel.WARN, tag, ...messages);
89 | }
90 |
91 | public info(tag: string, ...messages: any[]): void {
92 | this.log(LogLevel.INFO, tag, ...messages);
93 | }
94 |
95 | public debug(tag: string, ...messages: any[]): void {
96 | this.log(LogLevel.DEBUG, tag, ...messages);
97 | }
98 | }
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/StreamerContext.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / StreamerContext
2 |
3 | # Interface: StreamerContext
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:12](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L12)
6 |
7 | ## Properties
8 |
9 | ### clientInfo?
10 |
11 | > `optional` **clientInfo**: [`ClientInfo`](ClientInfo.md)
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L13)
14 |
15 | ***
16 |
17 | ### field4?
18 |
19 | > `optional` **field4**: `Uint8Array`\<`ArrayBufferLike`\>
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L16)
22 |
23 | ***
24 |
25 | ### field7?
26 |
27 | > `optional` **field7**: `string`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:19](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L19)
30 |
31 | ***
32 |
33 | ### field8?
34 |
35 | > `optional` **field8**: `StreamerContext_UnknownMessage1`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:20](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L20)
38 |
39 | ***
40 |
41 | ### playbackCookie?
42 |
43 | > `optional` **playbackCookie**: `Uint8Array`\<`ArrayBufferLike`\>
44 |
45 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L15)
46 |
47 | ***
48 |
49 | ### poToken?
50 |
51 | > `optional` **poToken**: `Uint8Array`\<`ArrayBufferLike`\>
52 |
53 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L14)
54 |
55 | ***
56 |
57 | ### sabrContexts
58 |
59 | > **sabrContexts**: `StreamerContext_SabrContext`[]
60 |
61 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L17)
62 |
63 | ***
64 |
65 | ### unsentSabrContexts
66 |
67 | > **unsentSabrContexts**: `number`[]
68 |
69 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/streamer\_context.ts:18](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/streamer_context.ts#L18)
70 |
--------------------------------------------------------------------------------
/protos/generated/video_streaming/playback_cookie.ts:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-ts_proto v2.7.5
4 | // protoc v5.28.0
5 | // source: video_streaming/playback_cookie.proto
6 |
7 | /* eslint-disable */
8 | import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
9 | import { FormatId } from "../misc/common.js";
10 |
11 | export const protobufPackage = "video_streaming";
12 |
13 | export interface PlaybackCookie {
14 | /** Always 999999 when resolution is set manually, or if the auto selected one is the max available resolution. */
15 | resolution?: number | undefined;
16 | field2?: number | undefined;
17 | videoFmt?: FormatId | undefined;
18 | audioFmt?: FormatId | undefined;
19 | }
20 |
21 | function createBasePlaybackCookie(): PlaybackCookie {
22 | return { resolution: 0, field2: 0, videoFmt: undefined, audioFmt: undefined };
23 | }
24 |
25 | export const PlaybackCookie: MessageFns = {
26 | encode(message: PlaybackCookie, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
27 | if (message.resolution !== undefined && message.resolution !== 0) {
28 | writer.uint32(8).int32(message.resolution);
29 | }
30 | if (message.field2 !== undefined && message.field2 !== 0) {
31 | writer.uint32(16).int32(message.field2);
32 | }
33 | if (message.videoFmt !== undefined) {
34 | FormatId.encode(message.videoFmt, writer.uint32(58).fork()).join();
35 | }
36 | if (message.audioFmt !== undefined) {
37 | FormatId.encode(message.audioFmt, writer.uint32(66).fork()).join();
38 | }
39 | return writer;
40 | },
41 |
42 | decode(input: BinaryReader | Uint8Array, length?: number): PlaybackCookie {
43 | const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
44 | const end = length === undefined ? reader.len : reader.pos + length;
45 | const message = createBasePlaybackCookie();
46 | while (reader.pos < end) {
47 | const tag = reader.uint32();
48 | switch (tag >>> 3) {
49 | case 1: {
50 | if (tag !== 8) {
51 | break;
52 | }
53 |
54 | message.resolution = reader.int32();
55 | continue;
56 | }
57 | case 2: {
58 | if (tag !== 16) {
59 | break;
60 | }
61 |
62 | message.field2 = reader.int32();
63 | continue;
64 | }
65 | case 7: {
66 | if (tag !== 58) {
67 | break;
68 | }
69 |
70 | message.videoFmt = FormatId.decode(reader, reader.uint32());
71 | continue;
72 | }
73 | case 8: {
74 | if (tag !== 66) {
75 | break;
76 | }
77 |
78 | message.audioFmt = FormatId.decode(reader, reader.uint32());
79 | continue;
80 | }
81 | }
82 | if ((tag & 7) === 4 || tag === 0) {
83 | break;
84 | }
85 | reader.skip(tag & 7);
86 | }
87 | return message;
88 | },
89 | };
90 |
91 | export interface MessageFns {
92 | encode(message: T, writer?: BinaryWriter): BinaryWriter;
93 | decode(input: BinaryReader | Uint8Array, length?: number): T;
94 | }
95 |
--------------------------------------------------------------------------------
/docs/api/exports/protos/interfaces/NextRequestPolicy.md:
--------------------------------------------------------------------------------
1 | [googlevideo](../../../README.md) / [exports/protos](../README.md) / NextRequestPolicy
2 |
3 | # Interface: NextRequestPolicy
4 |
5 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:13](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L13)
6 |
7 | ## Properties
8 |
9 | ### backoffTimeMs?
10 |
11 | > `optional` **backoffTimeMs**: `number`
12 |
13 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:17](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L17)
14 |
15 | ***
16 |
17 | ### maxTimeSinceLastRequestMs?
18 |
19 | > `optional` **maxTimeSinceLastRequestMs**: `number`
20 |
21 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:16](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L16)
22 |
23 | ***
24 |
25 | ### minAudioReadaheadMs?
26 |
27 | > `optional` **minAudioReadaheadMs**: `number`
28 |
29 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:18](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L18)
30 |
31 | ***
32 |
33 | ### minVideoReadaheadMs?
34 |
35 | > `optional` **minVideoReadaheadMs**: `number`
36 |
37 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:19](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L19)
38 |
39 | ***
40 |
41 | ### playbackCookie?
42 |
43 | > `optional` **playbackCookie**: [`PlaybackCookie`](PlaybackCookie.md)
44 |
45 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:20](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L20)
46 |
47 | ***
48 |
49 | ### targetAudioReadaheadMs?
50 |
51 | > `optional` **targetAudioReadaheadMs**: `number`
52 |
53 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:14](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L14)
54 |
55 | ***
56 |
57 | ### targetVideoReadaheadMs?
58 |
59 | > `optional` **targetVideoReadaheadMs**: `number`
60 |
61 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:15](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L15)
62 |
63 | ***
64 |
65 | ### videoId?
66 |
67 | > `optional` **videoId**: `string`
68 |
69 | Defined in: [codeberg/googlevideo/protos/generated/video\_streaming/next\_request\_policy.ts:21](https://github.com/LuanRT/googlevideo/blob/19854137cadaf49fd755394883dfd7fe5fdaba20/protos/generated/video_streaming/next_request_policy.ts#L21)
70 |
--------------------------------------------------------------------------------