@vkontakte/videoplayer-core 2.0.173-dev.ebda080eb.0 → 2.0.174-dev.477cdf9b9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es2015.cjs +17 -17
- package/es2015.esm.js +17 -17
- package/esnext.cjs +16 -16
- package/esnext.esm.js +16 -16
- package/evergreen.esm.js +16 -16
- package/package.json +2 -2
- package/types/index.d.ts +2 -2
- package/types/providers/DashLiveProvider/DashLiveProvider.d.ts +1 -0
- package/types/providers/DashProvider/dashCmafLiveProvider.d.ts +1 -0
- package/types/providers/DashProvider/lib/buffer.d.ts +0 -2
- package/types/providers/DashProvider/lib/fetcher.d.ts +4 -8
- package/types/providers/DashProvider/lib/player.d.ts +0 -1
- package/types/providers/DashProvider/lib/urlsCache.d.ts +23 -0
- package/types/providers/DashProviderVirtual/lib/buffer/types.d.ts +0 -2
- package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/{baseVirtualBufferManager.versionA.d.ts → baseVirtualBufferManager.d.ts} +1 -3
- package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/{byteRangeVirtualBufferManager.versionA.d.ts → byteRangeVirtualBufferManager.d.ts} +1 -2
- package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/liveVirtualBuffer.d.ts +1 -1
- package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/{templateVirtualBufferManager.versionA.d.ts → templateVirtualBufferManager.d.ts} +1 -1
- package/types/providers/DashProviderVirtual/lib/fetcher.d.ts +4 -8
- package/types/providers/DashProviderVirtual/lib/player/basePlayer.d.ts +0 -2
- package/types/providers/DashProviderVirtual/lib/urlsCache.d.ts +22 -0
- package/types/providers/HlsLiveProvider/index.d.ts +1 -0
- package/types/providers/HlsProvider/manifestDataExtractor.d.ts +2 -0
- package/types/providers/ProviderContainer/index.d.ts +0 -3
- package/types/providers/utils/buildFmp4MasterUrl.d.ts +12 -0
- package/types/providers/utils/generateLiveUrl.d.ts +1 -0
- package/types/utils/ClientChecker/services/DeviceChecker.d.ts +14 -0
- package/types/utils/ClientChecker/services/DisplayChecker.d.ts +3 -0
- package/types/utils/tuningConfig.d.ts +36 -14
- package/types/providers/utils/segmentCache/IndexedDbSegmentCacheStorage.d.ts +0 -54
- package/types/providers/utils/segmentCache/SegmentCache.d.ts +0 -59
- package/types/providers/utils/segmentCache/constants.d.ts +0 -20
- package/types/providers/utils/segmentCache/index.d.ts +0 -8
- package/types/providers/utils/segmentCache/segmentCacheDb.d.ts +0 -25
- package/types/providers/utils/segmentCache/segmentCacheUtils.d.ts +0 -25
- package/types/providers/utils/segmentCache/types.d.ts +0 -76
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vkontakte/videoplayer-core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.174-dev.477cdf9b9.0",
|
|
4
4
|
"author": "vk.ru",
|
|
5
5
|
"description": "Videoplayer core library based on the vk.ru platform",
|
|
6
6
|
"homepage": "https://vk.ru",
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"**/*.d.ts"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@vkontakte/videoplayer-shared": "1.0.
|
|
45
|
+
"@vkontakte/videoplayer-shared": "1.0.103-dev.477cdf9b9.0"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { IMpegSource, IDashSource, IHLSSource, IDashURLSource, IHLSLiveSour
|
|
|
3
3
|
import type { VideoCodec } from "./player/types";
|
|
4
4
|
import { VideoFormat, Surface, PredefinedQualityLimits, VideoCodecName } from "./player/types";
|
|
5
5
|
import Player from "./player/Player";
|
|
6
|
-
import type { IPlayer, IPlayerInfo, IPlayerEvents, IConfig, ISources, ICueSettings, IExternalTextTrack, ITextTrack, PlaybackRate, IVideoStream, IAudioStream } from "./player/types";
|
|
6
|
+
import type { IPlayer, IPlayerInfo, IPlayerEvents, IConfig, ISources, ICueSettings, IExternalTextTrack, ITextTrack, PlaybackRate, IVideoStream, IAudioStream, StartEnd, HttpConnectionMetrics, HttpDownloadMetrics } from "./player/types";
|
|
7
7
|
import { PlaybackState, ChromecastState, HttpConnectionType } from "./player/types";
|
|
8
8
|
import type { IOptionalTuningConfig } from "./utils/tuningConfig";
|
|
9
9
|
export { clientChecker, isMobile } from "./utils/ClientChecker";
|
|
@@ -15,5 +15,5 @@ import { Subscription, Observable, Subject, ValueSubject, VideoQuality } from "@
|
|
|
15
15
|
* @deprecated
|
|
16
16
|
*/
|
|
17
17
|
declare const SDK_VERSION: string;
|
|
18
|
-
export type { IPlayer, IPlayerInfo, IPlayerEvents, IConfig, IOptionalTuningConfig, ILogEntry, ISources, IExternalTextTrack, ITextTrack, ISubscription, IUnsubscriber, IObservable, IEmitter, IValueObservable, IValue, IOperator, IListener, IMpegSource, IDashSource, IDashURLSource, IHLSSource, IHLSLiveSource, URLSource, RawSource, URLSourceWithSeek, ExactVideoQuality, IRange, ISeekRequest, ICueSettings, PlaybackRate, IVideoStream, IAudioStream };
|
|
18
|
+
export type { IPlayer, IPlayerInfo, IPlayerEvents, IConfig, IOptionalTuningConfig, ILogEntry, ISources, IExternalTextTrack, ITextTrack, ISubscription, IUnsubscriber, IObservable, IEmitter, IValueObservable, IValue, IOperator, IListener, IMpegSource, IDashSource, IDashURLSource, IHLSSource, IHLSLiveSource, URLSource, RawSource, URLSourceWithSeek, ExactVideoQuality, IRange, ISeekRequest, ICueSettings, PlaybackRate, IVideoStream, IAudioStream, StartEnd, HttpConnectionMetrics, HttpDownloadMetrics };
|
|
19
19
|
export { Player, PlaybackState, ChromecastState, HttpConnectionType, Surface, Subscription, VideoFormat, VideoQuality, Observable, Subject, ValueSubject, VERSION, SDK_VERSION, PredefinedQualityLimits, VideoCodec, VideoCodecName };
|
|
@@ -42,7 +42,6 @@ export declare class BufferManager {
|
|
|
42
42
|
private parsedInitData;
|
|
43
43
|
private representations;
|
|
44
44
|
private segments;
|
|
45
|
-
private segmentIndexMap;
|
|
46
45
|
private allInitsLoaded;
|
|
47
46
|
private activeSegments;
|
|
48
47
|
private forwardBufferRepresentations;
|
|
@@ -110,7 +109,6 @@ export declare class BufferManager {
|
|
|
110
109
|
private feedPreDownloadedFirstSegment;
|
|
111
110
|
private loadByteRangeSegments;
|
|
112
111
|
private prepareByteRangeFetchSegmentParams;
|
|
113
|
-
private buildCacheMetadata;
|
|
114
112
|
private prepareTemplateFetchSegmentParams;
|
|
115
113
|
private abortActiveSegments;
|
|
116
114
|
private onSomeTemplateDataLoaded;
|
|
@@ -4,7 +4,6 @@ import type { Byte, IValueSubject, ISubject, Milliseconds, IRange, ITracer, IErr
|
|
|
4
4
|
import { abortable } from "@vkontakte/videoplayer-shared";
|
|
5
5
|
import type { ExactVideoQuality } from "@vkontakte/videoplayer-shared";
|
|
6
6
|
import type { CommonInit, GenericContainerParser, Segment, SegmentReference } from "../../utils/parsers/types";
|
|
7
|
-
import type { ISegmentCacheStorage, CacheMetadata } from "../../utils/segmentCache";
|
|
8
7
|
declare global {
|
|
9
8
|
interface Navigator {
|
|
10
9
|
connection: {
|
|
@@ -25,11 +24,11 @@ export interface IParams {
|
|
|
25
24
|
tracer: ITracer;
|
|
26
25
|
useEnableSubtitlesParam?: boolean;
|
|
27
26
|
handleExtendedNetworkErrorsSet?: boolean;
|
|
27
|
+
useUrlCacheMechanism?: boolean;
|
|
28
28
|
measureNonSegmentRequests?: boolean;
|
|
29
29
|
measureFastSamples?: boolean;
|
|
30
30
|
preloadFirstSegment?: boolean;
|
|
31
31
|
maxQualityForFirstSegmentPreload?: ExactVideoQuality;
|
|
32
|
-
segmentCacheService?: ISegmentCacheStorage;
|
|
33
32
|
}
|
|
34
33
|
export type Priority = "high" | "low" | "auto";
|
|
35
34
|
export interface FetchParamsWithUrl extends FetchParams {
|
|
@@ -46,8 +45,8 @@ export interface FetchParams {
|
|
|
46
45
|
isLowLatency?: boolean;
|
|
47
46
|
bufferOptimisation?: boolean;
|
|
48
47
|
ignoreNetworkErrors?: boolean;
|
|
48
|
+
urlCacheMechanismEnabled?: boolean;
|
|
49
49
|
representationHeight?: number;
|
|
50
|
-
cacheMetadata?: CacheMetadata;
|
|
51
50
|
}
|
|
52
51
|
export type RepresentationFetchResult = {
|
|
53
52
|
init: CommonInit | null;
|
|
@@ -74,17 +73,16 @@ export declare class Fetcher {
|
|
|
74
73
|
private readonly subscription;
|
|
75
74
|
private compatibilityMode;
|
|
76
75
|
private useEnableSubtitlesParam;
|
|
76
|
+
private useUrlCacheMechanism;
|
|
77
77
|
private measureNonSegmentRequests;
|
|
78
78
|
private measureFastSamples;
|
|
79
79
|
private preloadFirstSegment;
|
|
80
80
|
private maxQualityForFirstSegmentPreload;
|
|
81
|
-
private segmentCacheService;
|
|
82
|
-
private segmentCache;
|
|
83
81
|
private startupPhase;
|
|
84
82
|
private performanceObserver;
|
|
85
83
|
private pendingConnectionMetrics;
|
|
86
84
|
private handleExtendedNetworkErrorsSet;
|
|
87
|
-
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, measureNonSegmentRequests, measureFastSamples, preloadFirstSegment, maxQualityForFirstSegmentPreload
|
|
85
|
+
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, useUrlCacheMechanism, measureNonSegmentRequests, measureFastSamples, preloadFirstSegment, maxQualityForFirstSegmentPreload }: IParams);
|
|
88
86
|
private onHeadersReceived;
|
|
89
87
|
private setupPerformanceObserver;
|
|
90
88
|
private processPerformanceResourceTiming;
|
|
@@ -95,8 +93,6 @@ export declare class Fetcher {
|
|
|
95
93
|
fetchManifest: ReturnType<typeof abortable<[string], string | null>>;
|
|
96
94
|
fetch: ReturnType<typeof abortable<[string, FetchParams], ArrayBuffer | null>>;
|
|
97
95
|
fetchRepresentation(segmentReference: SegmentReference, parser: GenericContainerParser<unknown>, fetchParams: FetchParams): Promise<RepresentationFetchResult | null>;
|
|
98
|
-
/** Скипнутые сегменты не записаны в кэш — при следующем запросе региона докачаются как miss. */
|
|
99
|
-
private traceSkippedCacheSegments;
|
|
100
96
|
destroy(): void;
|
|
101
97
|
private fetchByteRangeRepresentation;
|
|
102
98
|
private fetchTemplateRepresentation;
|
|
@@ -40,7 +40,6 @@ export declare class Player {
|
|
|
40
40
|
private subscriptionRemovable;
|
|
41
41
|
private representationSubscription;
|
|
42
42
|
private fetcher;
|
|
43
|
-
private segmentCacheService;
|
|
44
43
|
state$: StateMachine<State>;
|
|
45
44
|
currentVideoRepresentation$: IValueSubject<Representation["id"] | undefined>;
|
|
46
45
|
currentVideoRepresentationInit$: IValueSubject<CommonInit | undefined>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type CacheManager = {
|
|
2
|
+
get: () => Promise<Response | null>;
|
|
3
|
+
set: (response: Response) => void;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Пытаемся добиться кэширования вызовов.
|
|
7
|
+
* Сейчас есть проблема, что expires и sig меняются, хотя контент не меняется, поэтому ходим мимо кэша.
|
|
8
|
+
* Из за этого обрабатываем кэш вручную.
|
|
9
|
+
*/
|
|
10
|
+
export declare const createCacheManager: (url: string) => Promise<CacheManager>;
|
|
11
|
+
export declare function canUseCacheApi(): boolean;
|
|
12
|
+
export declare function normalizeUrl(url: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Проверяет, не просрочен ли кэшированный ответ
|
|
15
|
+
*/
|
|
16
|
+
export declare function isResponseExpired(response: Response): boolean;
|
|
17
|
+
export declare function cloneResponse(response: Response, url: string): Response;
|
|
18
|
+
/**
|
|
19
|
+
* Извлекает expires из оригинального URL (параметр expires1)
|
|
20
|
+
* Предполагается, что expires1 — timestamp в секундах
|
|
21
|
+
*/
|
|
22
|
+
export declare function getExpiresFromUrl(url: string): number;
|
|
23
|
+
export declare const dropUrlsCache: () => Promise<void>;
|
|
@@ -3,7 +3,6 @@ import type { CommonInit, Manifest, Representation, Segment } from "../../../uti
|
|
|
3
3
|
import type { Fetcher } from "../fetcher";
|
|
4
4
|
import type { ITuningConfig } from "../../../../utils/tuningConfig";
|
|
5
5
|
import type { VideoSegmentLoadProgress } from "../../../utils/Abr/types";
|
|
6
|
-
import type { ISegmentCacheStorage } from "../../../utils/segmentCache";
|
|
7
6
|
export type TRepresentationSwitchMode = "lazy" | "force";
|
|
8
7
|
export declare enum SwithRepresentationMode {
|
|
9
8
|
Lazy = "lazy",
|
|
@@ -16,7 +15,6 @@ export interface Dependencies {
|
|
|
16
15
|
tuning: ITuningConfig;
|
|
17
16
|
compatibilityMode?: boolean;
|
|
18
17
|
manifest: Manifest | null;
|
|
19
|
-
segmentCacheService?: ISegmentCacheStorage;
|
|
20
18
|
getCurrentPosition(): Milliseconds | undefined;
|
|
21
19
|
getCurrentStallDuration(): Milliseconds;
|
|
22
20
|
isActiveLowLatency(): boolean;
|
|
@@ -2,7 +2,6 @@ import type { Fetcher, FetchParamsWithUrl, Priority, RepresentationFetchResult }
|
|
|
2
2
|
import type { CommonInit, ContainerParser, Representation, Segment } from "../../../../utils/parsers/types";
|
|
3
3
|
import { StreamKind } from "../../../../utils/parsers/types";
|
|
4
4
|
import type { ITuningConfig } from "../../../../../utils/tuningConfig";
|
|
5
|
-
import type { ISegmentCacheStorage } from "../../../../utils/segmentCache";
|
|
6
5
|
import type { Byte, IError, IRange, ISubject, ITracer, IValueSubject, Milliseconds, Seconds } from "@vkontakte/videoplayer-shared";
|
|
7
6
|
import { abortable, Subscription } from "@vkontakte/videoplayer-shared";
|
|
8
7
|
import type { NativeBufferManager } from "../nativeBufferManager";
|
|
@@ -20,7 +19,6 @@ export declare abstract class BaseVirtualBufferManager<T extends Segment> implem
|
|
|
20
19
|
protected readonly fetcher: Fetcher;
|
|
21
20
|
protected readonly tracer: ITracer;
|
|
22
21
|
protected readonly tuning: ITuningConfig;
|
|
23
|
-
protected readonly segmentCacheService: ISegmentCacheStorage | undefined;
|
|
24
22
|
protected representations: Map<Representation["id"], Representation>;
|
|
25
23
|
protected playingRepresentationId: Representation["id"] | undefined;
|
|
26
24
|
protected downloadingRepresentationId: Representation["id"] | undefined;
|
|
@@ -55,7 +53,7 @@ export declare abstract class BaseVirtualBufferManager<T extends Segment> implem
|
|
|
55
53
|
protected readonly getCurrentPosition: () => Milliseconds | undefined;
|
|
56
54
|
protected readonly getCurrentStallDuration: () => Milliseconds | undefined;
|
|
57
55
|
protected brokenSegmentAppendDetected: boolean;
|
|
58
|
-
protected constructor(kind: StreamKind, nativeBufferManager: NativeBufferManager, representations: Representation[], { fetcher, tracer, tuning, getCurrentPosition, getCurrentStallDuration, manifest
|
|
56
|
+
protected constructor(kind: StreamKind, nativeBufferManager: NativeBufferManager, representations: Representation[], { fetcher, tracer, tuning, getCurrentPosition, getCurrentStallDuration, manifest }: Dependencies);
|
|
59
57
|
protected abstract loadItems(itemsToLoad: IBufferPlaybackQueueItem<T>[], representation: Representation, priority?: Priority): Promise<void>;
|
|
60
58
|
protected abstract selectItemsToLoad(): IBufferPlaybackQueueItem<T>[];
|
|
61
59
|
protected abstract prepareFetchParams(items: IBufferPlaybackQueueItem<T>[], representation: Representation): FetchParamsWithUrl;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseVirtualBufferManager } from "./baseVirtualBufferManager
|
|
1
|
+
import { BaseVirtualBufferManager } from "./baseVirtualBufferManager";
|
|
2
2
|
import type { Dependencies, IBufferPlaybackQueueItem, ISomeDataLoadedCallbackParams, IVirtualBufferManager } from "../types";
|
|
3
3
|
import type { ByteRangeSegment, Representation, StreamKind } from "../../../../utils/parsers/types";
|
|
4
4
|
import type { NativeBufferManager } from "../nativeBufferManager";
|
|
@@ -8,7 +8,6 @@ export declare class ByteRangeVirtualBufferManager extends BaseVirtualBufferMana
|
|
|
8
8
|
protected override loadItems(itemsToLoad: IBufferPlaybackQueueItem<ByteRangeSegment>[], representation: Representation, priority?: Priority): Promise<void>;
|
|
9
9
|
protected override selectItemsToLoad(): IBufferPlaybackQueueItem<ByteRangeSegment>[];
|
|
10
10
|
protected override prepareFetchParams(items: IBufferPlaybackQueueItem<ByteRangeSegment>[], representation: Representation): FetchParamsWithUrl;
|
|
11
|
-
private buildCacheMetadata;
|
|
12
11
|
/**
|
|
13
12
|
* Закидываем в буфер сегменты атомарнее чем сегмент целиком. Например, по боксам в мпеге и по блокам в вебме.
|
|
14
13
|
* Таким образом не ждём его полной загрузки и готовы играть его намного быстрее
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TemplateVirtualBufferManager } from "./templateVirtualBufferManager
|
|
1
|
+
import { TemplateVirtualBufferManager } from "./templateVirtualBufferManager";
|
|
2
2
|
import type { Manifest, Representation, StreamKind, TemplateSegment, TemplateSegmentReference } from "../../../../utils/parsers/types";
|
|
3
3
|
import type { NativeBufferManager } from "../nativeBufferManager";
|
|
4
4
|
import type { Dependencies, IBufferPlaybackQueueItem, ISomeDataLoadedCallbackParams } from "../types";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseVirtualBufferManager } from "./baseVirtualBufferManager
|
|
1
|
+
import { BaseVirtualBufferManager } from "./baseVirtualBufferManager";
|
|
2
2
|
import type { Dependencies, IBufferPlaybackQueueItem, ISomeDataLoadedCallbackParams, IVirtualBufferManager } from "../types";
|
|
3
3
|
import type { TemplateSegment, Representation, StreamKind } from "../../../../utils/parsers/types";
|
|
4
4
|
import type { NativeBufferManager } from "../nativeBufferManager";
|
|
@@ -4,7 +4,6 @@ import type { Byte, IError, IRange, ISubject, ITracer, IValueSubject, Millisecon
|
|
|
4
4
|
import { abortable } from "@vkontakte/videoplayer-shared";
|
|
5
5
|
import type { ExactVideoQuality } from "@vkontakte/videoplayer-shared";
|
|
6
6
|
import type { CommonInit, GenericContainerParser, Segment, SegmentReference, StreamKind } from "../../utils/parsers/types";
|
|
7
|
-
import type { ISegmentCacheStorage, CacheMetadata } from "../../utils/segmentCache";
|
|
8
7
|
declare global {
|
|
9
8
|
interface Navigator {
|
|
10
9
|
connection: {
|
|
@@ -25,11 +24,11 @@ export interface IParams {
|
|
|
25
24
|
tracer: ITracer;
|
|
26
25
|
useEnableSubtitlesParam?: boolean;
|
|
27
26
|
handleExtendedNetworkErrorsSet?: boolean;
|
|
27
|
+
useUrlCacheMechanism?: boolean;
|
|
28
28
|
measureNonSegmentRequests?: boolean;
|
|
29
29
|
measureFastSamples?: boolean;
|
|
30
30
|
preloadFirstSegment?: boolean;
|
|
31
31
|
maxQualityForFirstSegmentPreload?: ExactVideoQuality;
|
|
32
|
-
segmentCacheService?: ISegmentCacheStorage;
|
|
33
32
|
}
|
|
34
33
|
export type Priority = "high" | "low" | "auto";
|
|
35
34
|
export interface FetchParamsWithUrl extends FetchParams {
|
|
@@ -45,8 +44,8 @@ export interface FetchParams {
|
|
|
45
44
|
measureThroughput?: boolean;
|
|
46
45
|
isLowLatency?: boolean;
|
|
47
46
|
bufferOptimisation?: boolean;
|
|
47
|
+
urlCacheMechanismEnabled?: boolean;
|
|
48
48
|
kind: StreamKind;
|
|
49
|
-
cacheMetadata?: CacheMetadata;
|
|
50
49
|
}
|
|
51
50
|
export type RepresentationFetchResult<T extends Segment> = {
|
|
52
51
|
initMetadata: CommonInit | null;
|
|
@@ -73,17 +72,16 @@ export declare class Fetcher {
|
|
|
73
72
|
private subscription;
|
|
74
73
|
private compatibilityMode;
|
|
75
74
|
private useEnableSubtitlesParam;
|
|
75
|
+
private useUrlCacheMechanism;
|
|
76
76
|
private measureNonSegmentRequests;
|
|
77
77
|
private measureFastSamples;
|
|
78
78
|
private preloadFirstSegment;
|
|
79
79
|
private maxQualityForFirstSegmentPreload;
|
|
80
|
-
private segmentCacheService;
|
|
81
|
-
private segmentCache;
|
|
82
80
|
private startupPhase;
|
|
83
81
|
private performanceObserver;
|
|
84
82
|
private pendingConnectionMetrics;
|
|
85
83
|
private handleExtendedNetworkErrorsSet;
|
|
86
|
-
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, measureNonSegmentRequests, measureFastSamples, preloadFirstSegment, maxQualityForFirstSegmentPreload
|
|
84
|
+
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, useUrlCacheMechanism, measureNonSegmentRequests, measureFastSamples, preloadFirstSegment, maxQualityForFirstSegmentPreload }: IParams);
|
|
87
85
|
private onHeadersReceived;
|
|
88
86
|
private setupPerformanceObserver;
|
|
89
87
|
private processResourceTiming;
|
|
@@ -94,8 +92,6 @@ export declare class Fetcher {
|
|
|
94
92
|
fetchManifest: ReturnType<typeof abortable<[string], string | null>>;
|
|
95
93
|
fetch: ReturnType<typeof abortable<[string, FetchParams], ArrayBuffer | null>>;
|
|
96
94
|
fetchRepresentation<T extends Segment>(segmentReference: SegmentReference, parser: GenericContainerParser<unknown>, dowbloadAbortSignal: AbortSignal, priority?: Priority, representationHeight?: number, kind?: StreamKind): Promise<RepresentationFetchResult<T> | null | undefined>;
|
|
97
|
-
/** Скипнутые сегменты не записаны в кэш — при следующем запросе региона докачаются как miss. */
|
|
98
|
-
private traceSkippedCacheSegments;
|
|
99
95
|
destroy(): void;
|
|
100
96
|
private fetchByteRangeRepresentation;
|
|
101
97
|
private fetchTemplateRepresentation;
|
|
@@ -9,7 +9,6 @@ import type { IError, IRange, ISubject, ISubscription, ITracer, IValueSubject, M
|
|
|
9
9
|
import { abortable, Subject, Subscription, SubscriptionRemovable } from "@vkontakte/videoplayer-shared";
|
|
10
10
|
import type { VideoSegmentLoadProgress } from "../../../utils/Abr/types";
|
|
11
11
|
import { Fetcher } from "../fetcher";
|
|
12
|
-
import type { ISegmentCacheStorage } from "../../../utils/segmentCache";
|
|
13
12
|
import type { Dependencies, IVirtualBufferManager, SwithRepresentationMode } from "../buffer/types";
|
|
14
13
|
import type { Params } from "./types";
|
|
15
14
|
import { State } from "./types";
|
|
@@ -36,7 +35,6 @@ export declare abstract class BasePlayer {
|
|
|
36
35
|
protected subscriptionRemovable: SubscriptionRemovable;
|
|
37
36
|
protected representationSubscription: Subscription;
|
|
38
37
|
protected fetcher: Fetcher;
|
|
39
|
-
protected segmentCacheService: ISegmentCacheStorage | undefined;
|
|
40
38
|
protected forceEnded$: ISubject<void>;
|
|
41
39
|
protected stallWatchdogSubscription: ISubscription | undefined;
|
|
42
40
|
protected destroyController: AbortController;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type CacheManager = {
|
|
2
|
+
get: () => Promise<Response | null>;
|
|
3
|
+
set: (response: Response) => Promise<void>;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Пытаемся добиться кэширования вызовов.
|
|
7
|
+
* Сейчас есть проблема, что expires и sig меняются, хотя контент не меняется, поэтому ходим мимо кэша.
|
|
8
|
+
* Из за этого обрабатываем кэш вручную.
|
|
9
|
+
*/
|
|
10
|
+
export declare const createCacheManager: (url: string) => Promise<CacheManager>;
|
|
11
|
+
export declare function canUseCacheApi(): boolean;
|
|
12
|
+
export declare function normalizeUrl(url: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Проверяет, не просрочен ли кэшированный ответ
|
|
15
|
+
*/
|
|
16
|
+
export declare function isResponseExpired(response: Response): boolean;
|
|
17
|
+
export declare function cloneResponse(response: Response, url: string): Response;
|
|
18
|
+
/**
|
|
19
|
+
* Извлекает expires из оригинального URL (параметр expires1)
|
|
20
|
+
* Предполагается, что expires1 — timestamp в секундах
|
|
21
|
+
*/
|
|
22
|
+
export declare function getExpiresFromUrl(url: string): number;
|
|
@@ -12,6 +12,8 @@ export type ManifestUrl = {
|
|
|
12
12
|
bandwidth?: Kbps;
|
|
13
13
|
size?: IRectangle;
|
|
14
14
|
fps?: number;
|
|
15
|
+
/** HLS fMP4: идентификатор аудио-группы (EXT-X-MEDIA GROUP-ID), к которой привязан вариант через STREAM-INF AUDIO= */
|
|
16
|
+
audioGroupId?: string;
|
|
15
17
|
};
|
|
16
18
|
export type HLSManifestData = {
|
|
17
19
|
qualityManifests: ManifestUrl[];
|
|
@@ -37,7 +37,6 @@ export default class ProviderContainer implements IProviderContainer {
|
|
|
37
37
|
private currentProviderStarted;
|
|
38
38
|
private volumeMultiplierManager;
|
|
39
39
|
private dashMaxTvVideoQuality;
|
|
40
|
-
private segmentCacheCleared;
|
|
41
40
|
private mayday;
|
|
42
41
|
private maydayStatistics;
|
|
43
42
|
constructor(params: IParams);
|
|
@@ -51,8 +50,6 @@ export default class ProviderContainer implements IProviderContainer {
|
|
|
51
50
|
private destroyProvider;
|
|
52
51
|
private handleMaydayRecommendation;
|
|
53
52
|
private applyErrorSideEffects;
|
|
54
|
-
/** Битые данные в кэше могут вызывать повторные ошибки после реинита — очищаем кэш целиком. */
|
|
55
|
-
private clearSegmentCacheOnError;
|
|
56
53
|
private createProvider;
|
|
57
54
|
private createScreenProvider;
|
|
58
55
|
private createChromecastProvider;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ManifestUrl } from "../HlsProvider/manifestDataExtractor";
|
|
2
|
+
export declare const FMP4_QUALITY_QUERY_PARAMS: readonly ["mq", "lq"];
|
|
3
|
+
/**
|
|
4
|
+
* HLS fMP4: дочерний плейлист варианта не содержит EXT-X-MEDIA групп, поэтому нативный HLS
|
|
5
|
+
* не знает какую аудио-группу подцепить и продолжает держать предыдущую — звук пропадает при
|
|
6
|
+
* смене качества. Решение — грузить мастер-плейлист с зафиксированным качеством через
|
|
7
|
+
* mq=lq=<height>, тогда бэк сам отдаст нужный вариант с правильной аудио-группой.
|
|
8
|
+
*
|
|
9
|
+
* Возвращает undefined, если у варианта нельзя надёжно определить высоту — в этом случае
|
|
10
|
+
* лучше оставить дефолтное поведение провайдера, чем отправлять мусор в URL.
|
|
11
|
+
*/
|
|
12
|
+
export declare const buildFmp4MasterUrl: (masterUrl: string, qualityManifest: ManifestUrl) => URL | undefined;
|
|
@@ -4,6 +4,7 @@ export declare enum OffsetParameterType {
|
|
|
4
4
|
PLAYBACK_SHIFT = 1,
|
|
5
5
|
DASH_CMAF_OFFSET_P = 2
|
|
6
6
|
}
|
|
7
|
+
export declare const hasOffsetMarker: (url: string) => boolean;
|
|
7
8
|
declare const _default: (url: string, offset?: Milliseconds, type?: OffsetParameterType) => string;
|
|
8
9
|
export default _default;
|
|
9
10
|
export declare const getLiveUrlOffset: (url: string, type: OffsetParameterType) => number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CurrentClientDevice } from "../types/currentClientDevice";
|
|
2
2
|
import type { DisplayChecker } from "./DisplayChecker";
|
|
3
3
|
import type { Checker } from "../types/checker";
|
|
4
|
+
import type { HighEntropyValues } from "../types/userAgentData";
|
|
4
5
|
export interface OS {
|
|
5
6
|
name: string;
|
|
6
7
|
version: string;
|
|
@@ -10,6 +11,12 @@ export interface DeviceDetails {
|
|
|
10
11
|
vendor: string;
|
|
11
12
|
model: string;
|
|
12
13
|
}
|
|
14
|
+
export interface DeviceHardware {
|
|
15
|
+
cpuCores?: number;
|
|
16
|
+
memoryGb?: number;
|
|
17
|
+
gpuVendor?: string;
|
|
18
|
+
gpuArchitecture?: string;
|
|
19
|
+
}
|
|
13
20
|
export declare class DeviceChecker implements Checker {
|
|
14
21
|
private _displayChecker;
|
|
15
22
|
private _isMobile;
|
|
@@ -18,10 +25,14 @@ export declare class DeviceChecker implements Checker {
|
|
|
18
25
|
private _highEntropyValues;
|
|
19
26
|
private _os;
|
|
20
27
|
private _details;
|
|
28
|
+
private _hardware;
|
|
29
|
+
private _gpuDetection;
|
|
21
30
|
constructor(displayChecker: DisplayChecker);
|
|
22
31
|
get current(): CurrentClientDevice;
|
|
23
32
|
get os(): OS;
|
|
24
33
|
get details(): DeviceDetails;
|
|
34
|
+
get hardware(): DeviceHardware;
|
|
35
|
+
get highEntropyValues(): HighEntropyValues;
|
|
25
36
|
get isIOS(): boolean;
|
|
26
37
|
get isIPadOS(): boolean;
|
|
27
38
|
get isMac(): boolean;
|
|
@@ -33,6 +44,9 @@ export declare class DeviceChecker implements Checker {
|
|
|
33
44
|
get isMobile(): boolean;
|
|
34
45
|
get iOSVersion(): number | undefined;
|
|
35
46
|
detect(): void;
|
|
47
|
+
private detectHardware;
|
|
48
|
+
detectGpu(): Promise<void>;
|
|
49
|
+
private requestGpuInfo;
|
|
36
50
|
private detectHighEntropyValues;
|
|
37
51
|
private detectDevice;
|
|
38
52
|
private detectOS;
|
|
@@ -10,6 +10,7 @@ export declare class DisplayChecker implements Checker {
|
|
|
10
10
|
private _screenHeight;
|
|
11
11
|
private _screenWidth;
|
|
12
12
|
private _colorDepth;
|
|
13
|
+
private _colorGamut;
|
|
13
14
|
private _displayMode;
|
|
14
15
|
private _isStandalone;
|
|
15
16
|
get isTouch(): boolean;
|
|
@@ -21,8 +22,10 @@ export declare class DisplayChecker implements Checker {
|
|
|
21
22
|
get pixelRatio(): number;
|
|
22
23
|
get isHDR(): boolean;
|
|
23
24
|
get colorDepth(): number;
|
|
25
|
+
get colorGamut(): ColorGamut | undefined;
|
|
24
26
|
get displayMode(): DisplayMode;
|
|
25
27
|
get isStandalone(): boolean;
|
|
26
28
|
detect(): void;
|
|
29
|
+
private detectColorGamut;
|
|
27
30
|
private detectDisplayMode;
|
|
28
31
|
}
|
|
@@ -5,7 +5,6 @@ import { IOSPreferredFormat } from "../enums/IOSPreferredFormat";
|
|
|
5
5
|
import type { Byte, Kbps, Milliseconds, RecursivePartial, Seconds, TimerModule } from "@vkontakte/videoplayer-shared";
|
|
6
6
|
import { type ExactVideoQuality, VideoQuality } from "@vkontakte/videoplayer-shared";
|
|
7
7
|
import { AudioRuleName, VideoRuleName } from "../providers/utils/Abr/types";
|
|
8
|
-
import type { SegmentCacheConfig } from "../providers/utils/segmentCache/types";
|
|
9
8
|
export type ITuningConfig = {
|
|
10
9
|
/** @deprecated */
|
|
11
10
|
configName?: string[];
|
|
@@ -203,6 +202,7 @@ export type ITuningConfig = {
|
|
|
203
202
|
usePersistentGaps: boolean;
|
|
204
203
|
abrThrottle: number;
|
|
205
204
|
useVideoElementWaitingCurrentTimeReassign: boolean;
|
|
205
|
+
useVideoElementProgressCurrentTimeReassign: boolean;
|
|
206
206
|
stallWatchdogInterval: Milliseconds;
|
|
207
207
|
liveUpdateInterval: Milliseconds;
|
|
208
208
|
liveStallReinitInterval: Milliseconds;
|
|
@@ -252,20 +252,24 @@ export type ITuningConfig = {
|
|
|
252
252
|
maxQualityForFirstSegmentPreload: ExactVideoQuality;
|
|
253
253
|
/** Включает отправку телеметрии трейсера (resume) при превышении stall watchdog */
|
|
254
254
|
tracerResumeOnUnexpectedStall: boolean;
|
|
255
|
+
/** Включает отправку телеметрии трейсера (resume) при выборе ABR качества не выше lowQualityTelemetryLimit */
|
|
256
|
+
tracerResumeOnLowQuality: boolean;
|
|
255
257
|
/**
|
|
256
|
-
*
|
|
257
|
-
* `
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
258
|
+
* Эксперимент: при `true` отключает `await this.reinitDecoderIfNeeded(shouldForceSeek)`
|
|
259
|
+
* внутри `stallWatchdogIntervalCallback`. По умолчанию `false` — текущее поведение
|
|
260
|
+
* (force-seek раз в секунду при глубоком stall). Гипотеза: возможно, force-seek из
|
|
261
|
+
* watchdog'а сам по себе тормозит восстановление на длинных столлах (аналог B1,
|
|
262
|
+
* но через полное отключение reinit, а не троттлинг частоты).
|
|
263
|
+
*/
|
|
264
|
+
disableStallWatchdogReinitDecoder: boolean;
|
|
265
|
+
/**
|
|
266
|
+
* Эксперимент: при `destroy()` резолвить callback'и `currentTask` и всех задач в очереди,
|
|
267
|
+
* чтобы их промисы (`await this.queue.append(...)`, `await this.queue.remove(...)`) не висели
|
|
268
|
+
* вечно после разрушения очереди. По умолчанию `false` — поведение как до эксперимента:
|
|
269
|
+
* `queue = []; currentTask = null` без вызова callback'ов, промисы зависают (pre-existing behaviour).
|
|
270
|
+
* Включать поэтапно, начиная с процента трафика, для A/B по метрикам утечек и восстановления.
|
|
267
271
|
*/
|
|
268
|
-
|
|
272
|
+
resolveQueueOnDestroy: boolean;
|
|
269
273
|
};
|
|
270
274
|
dashCmafLive: {
|
|
271
275
|
externalStopControl: boolean;
|
|
@@ -313,6 +317,15 @@ export type ITuningConfig = {
|
|
|
313
317
|
*/
|
|
314
318
|
maxPausedTime: number;
|
|
315
319
|
catchupLiveForMutedInactiveTab: boolean;
|
|
320
|
+
/**
|
|
321
|
+
* UVP-2618. Отключать перемотку лайва, если ссылка пришла без маркера offset (`_offset_p` в пути
|
|
322
|
+
* или query-параметр `?offset_p=`). Применяется ко всем live-форматам: dash_live, dash_live_cmaf,
|
|
323
|
+
* hls_live, hls_live_cmaf. Когда манифест отдаёт DVR-окно (shiftDuration / liveSeekableDuration /
|
|
324
|
+
* X-Playback-Duration), но в URL нет маркера, `generateLiveUrl` не сможет подставить offset и плеер
|
|
325
|
+
* молча переинициализируется на live edge. Включение делает DVR-окно нулевым и скрывает таймлайн.
|
|
326
|
+
* По умолчанию false (прежнее поведение), включается для эксперимента.
|
|
327
|
+
*/
|
|
328
|
+
disableLiveSeekWithoutOffsetMarker: boolean;
|
|
316
329
|
};
|
|
317
330
|
enableWakeLock: boolean;
|
|
318
331
|
enableTelemetryAtStart: boolean;
|
|
@@ -353,6 +366,7 @@ export type ITuningConfig = {
|
|
|
353
366
|
* include-threshold - записываем столлы длинее stallIgnoreThreshold
|
|
354
367
|
*/
|
|
355
368
|
stallHandlingStrategy: "verbose" | "exclude-threshold" | "include-threshold";
|
|
369
|
+
stallIgnoreOnPause: boolean;
|
|
356
370
|
gapWatchdogInterval: Milliseconds;
|
|
357
371
|
requestQuick: boolean;
|
|
358
372
|
/** @deprecated HLS.js удалён, флаг ничего не делает */
|
|
@@ -440,6 +454,15 @@ export type ITuningConfig = {
|
|
|
440
454
|
*/
|
|
441
455
|
handleExtendedNetworkErrorsSet?: boolean;
|
|
442
456
|
/**
|
|
457
|
+
* Кэшируем ответы от сервера руками, так как из за динамичесокй природы некоторых параметров в урле
|
|
458
|
+
* браузер это не может сделать.
|
|
459
|
+
*/
|
|
460
|
+
useUrlCacheMechanism?: boolean;
|
|
461
|
+
/**
|
|
462
|
+
* Очищаем кэш урлов при падение провайдера.
|
|
463
|
+
*/
|
|
464
|
+
dropUrlCacheWhenProviderCrashed?: boolean;
|
|
465
|
+
/**
|
|
443
466
|
* При смене/реините провайдера игнорируем результат того, смогло видео заиграть или нет.
|
|
444
467
|
*/
|
|
445
468
|
ignoreForcePlayResultWhenProviderChanged?: boolean;
|
|
@@ -467,7 +490,6 @@ export type ITuningConfig = {
|
|
|
467
490
|
* провайдер по-прежнему ждёт canplay, чтобы play() не вызывался до появления данных.
|
|
468
491
|
*/
|
|
469
492
|
readyOnLoadedMetadata: boolean;
|
|
470
|
-
segmentCache: SegmentCacheConfig;
|
|
471
493
|
};
|
|
472
494
|
export type IOptionalTuningConfig = RecursivePartial<ITuningConfig>;
|
|
473
495
|
export declare const fillDefault: (partial: IOptionalTuningConfig) => ITuningConfig;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { InitSegmentParams, ISegmentCacheStorage, SegmentCacheConfig, SetSegmentParams } from "./types";
|
|
2
|
-
export declare class IndexedDbSegmentCacheStorage implements ISegmentCacheStorage {
|
|
3
|
-
private config;
|
|
4
|
-
private dbPromise;
|
|
5
|
-
private destroyed;
|
|
6
|
-
private evictionTimerId;
|
|
7
|
-
private globalTotalBytes;
|
|
8
|
-
private maxTotalStoredBytes;
|
|
9
|
-
private quotaExceeded;
|
|
10
|
-
private cacheEventsChannel;
|
|
11
|
-
constructor(config: SegmentCacheConfig);
|
|
12
|
-
private getDb;
|
|
13
|
-
private isFresh;
|
|
14
|
-
/**
|
|
15
|
-
* Читает записи по массиву ключей в одной транзакции.
|
|
16
|
-
* Свежие по TTL — возвращает данные и обновляет lastAccessAt (не чаще чем раз в TOUCH_INTERVAL_MS,
|
|
17
|
-
* чтобы избежать write amplification: каждый cache hit не должен делать store.put с полным ArrayBuffer).
|
|
18
|
-
* Протухшие — удаляет, декрементирует globalTotalBytes.
|
|
19
|
-
*/
|
|
20
|
-
private readFreshRecord;
|
|
21
|
-
/**
|
|
22
|
-
* При открытии БД пересчитывает globalTotalBytes: проходит по всем записям,
|
|
23
|
-
* суммирует размер живых (не протухших по TTL) и удаляет протухшие.
|
|
24
|
-
* TTL различается: media — ttlMs, init/index — initTtlMs.
|
|
25
|
-
*/
|
|
26
|
-
private handleDbOpened;
|
|
27
|
-
/** Возвращает TTL в зависимости от типа записи по первичному ключу. */
|
|
28
|
-
private ttlForEntry;
|
|
29
|
-
getSegments(normalizedUrl: string, indices: number[]): Promise<Map<number, ArrayBuffer>>;
|
|
30
|
-
/** Удаляет записи по индексам сегментов в одной транзакции, декрементируя globalTotalBytes. */
|
|
31
|
-
deleteSegments(normalizedUrl: string, indices: number[]): Promise<void>;
|
|
32
|
-
setSegment(params: SetSegmentParams): Promise<void>;
|
|
33
|
-
getInitSegment({ normalizedUrl, rangeType, range }: InitSegmentParams): Promise<ArrayBuffer | null>;
|
|
34
|
-
/** Универсальная запись с подсчётом delta, QuotaExceededError-обработкой и eviction. */
|
|
35
|
-
private putRecord;
|
|
36
|
-
private handleQuotaExceededError;
|
|
37
|
-
/** Полная очистка кэша с рассылкой события остальным инстансам (вкладки, другие плееры). */
|
|
38
|
-
clear(): Promise<void>;
|
|
39
|
-
destroy(): void;
|
|
40
|
-
private scheduleEviction;
|
|
41
|
-
/**
|
|
42
|
-
* LRU-eviction: запускается по дебаунсу после каждой записи.
|
|
43
|
-
* Без квоты — триггерит при достижении maxTotalStoredBytes.
|
|
44
|
-
* После QuotaExceededError — раньше, на maxTotalStoredBytes * evictionThreshold,
|
|
45
|
-
* чтобы не упереться в квоту повторно.
|
|
46
|
-
* Очищает с запасом — до maxTotalStoredBytes * evictionTargetPercent.
|
|
47
|
-
*/
|
|
48
|
-
private runEviction;
|
|
49
|
-
/**
|
|
50
|
-
* Удаляет самые старые по lastAccessAt записи, пока не освободит хотя бы bytesToFree.
|
|
51
|
-
* maxBytesPerBatch ограничивает длительность одной транзакции; без лимита — при QuotaExceededError.
|
|
52
|
-
*/
|
|
53
|
-
private evictOldest;
|
|
54
|
-
}
|