@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.
Files changed (36) hide show
  1. package/es2015.cjs +17 -17
  2. package/es2015.esm.js +17 -17
  3. package/esnext.cjs +16 -16
  4. package/esnext.esm.js +16 -16
  5. package/evergreen.esm.js +16 -16
  6. package/package.json +2 -2
  7. package/types/index.d.ts +2 -2
  8. package/types/providers/DashLiveProvider/DashLiveProvider.d.ts +1 -0
  9. package/types/providers/DashProvider/dashCmafLiveProvider.d.ts +1 -0
  10. package/types/providers/DashProvider/lib/buffer.d.ts +0 -2
  11. package/types/providers/DashProvider/lib/fetcher.d.ts +4 -8
  12. package/types/providers/DashProvider/lib/player.d.ts +0 -1
  13. package/types/providers/DashProvider/lib/urlsCache.d.ts +23 -0
  14. package/types/providers/DashProviderVirtual/lib/buffer/types.d.ts +0 -2
  15. package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/{baseVirtualBufferManager.versionA.d.ts → baseVirtualBufferManager.d.ts} +1 -3
  16. package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/{byteRangeVirtualBufferManager.versionA.d.ts → byteRangeVirtualBufferManager.d.ts} +1 -2
  17. package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/liveVirtualBuffer.d.ts +1 -1
  18. package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/{templateVirtualBufferManager.versionA.d.ts → templateVirtualBufferManager.d.ts} +1 -1
  19. package/types/providers/DashProviderVirtual/lib/fetcher.d.ts +4 -8
  20. package/types/providers/DashProviderVirtual/lib/player/basePlayer.d.ts +0 -2
  21. package/types/providers/DashProviderVirtual/lib/urlsCache.d.ts +22 -0
  22. package/types/providers/HlsLiveProvider/index.d.ts +1 -0
  23. package/types/providers/HlsProvider/manifestDataExtractor.d.ts +2 -0
  24. package/types/providers/ProviderContainer/index.d.ts +0 -3
  25. package/types/providers/utils/buildFmp4MasterUrl.d.ts +12 -0
  26. package/types/providers/utils/generateLiveUrl.d.ts +1 -0
  27. package/types/utils/ClientChecker/services/DeviceChecker.d.ts +14 -0
  28. package/types/utils/ClientChecker/services/DisplayChecker.d.ts +3 -0
  29. package/types/utils/tuningConfig.d.ts +36 -14
  30. package/types/providers/utils/segmentCache/IndexedDbSegmentCacheStorage.d.ts +0 -54
  31. package/types/providers/utils/segmentCache/SegmentCache.d.ts +0 -59
  32. package/types/providers/utils/segmentCache/constants.d.ts +0 -20
  33. package/types/providers/utils/segmentCache/index.d.ts +0 -8
  34. package/types/providers/utils/segmentCache/segmentCacheDb.d.ts +0 -25
  35. package/types/providers/utils/segmentCache/segmentCacheUtils.d.ts +0 -25
  36. 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.173-dev.ebda080eb.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.102-dev.ebda080eb.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 };
@@ -34,4 +34,5 @@ export default class DashLiveProvider implements IProvider {
34
34
  private seek;
35
35
  private _dashCb;
36
36
  private syncPlayback;
37
+ private isSeekOffsetSupported;
37
38
  }
@@ -5,4 +5,5 @@ export default class DashCmafLiveProvider extends BaseDashProvider {
5
5
  constructor(params: IParams);
6
6
  protected override subscribe(): void;
7
7
  protected override seek(position: Milliseconds): void;
8
+ private isSeekOffsetSupported;
8
9
  }
@@ -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, segmentCacheService }: IParams);
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, segmentCacheService }: Dependencies);
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.versionA";
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.versionA";
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.versionA";
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, segmentCacheService }: IParams);
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;
@@ -30,4 +30,5 @@ export default class HlsLiveProvider implements IProvider {
30
30
  private seek;
31
31
  private syncPlayback;
32
32
  private generateLiveUrl;
33
+ private isSeekOffsetSupported;
33
34
  }
@@ -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
- * При отмене signal текущей задачи sourceBufferTaskQueue (например, через
257
- * `maintainAbortController.abort()` в `prepareSeek`) прерывать зависшую MSE-операцию
258
- * через `buffer.abort()`. Без этого `completeTask` не вызовется при залипшем
259
- * SourceBuffer и промис `append`/`remove` зависнет навечно `prepareSeek`
260
- * застрянет на `await maintainMutexPromise` (V3 deadlock), stall растёт до
261
- * `crashOnStallTimeout=25с`.
262
- *
263
- * По умолчанию false (opt-in). Дешёвый фикс, но поведенческое изменение:
264
- * единственный побочный эффект лишний `buffer.abort()` при штатной отмене
265
- * maintain (например, при обычном seek), но MSE `abort()` без активной операции
266
- * no-op по спеке. Включать поэтапно, начиная с процента.
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
- abortSourceBufferOnSignal: boolean;
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
- }