@vkontakte/videoplayer-core 2.0.176-beta.0 → 2.0.176-dev.477f4c39b.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 +16 -16
- package/es2015.esm.js +16 -16
- package/esnext.cjs +8 -8
- package/esnext.esm.js +8 -8
- package/evergreen.esm.js +15 -15
- package/package.json +2 -2
- package/types/index.d.ts +9 -3
- package/types/player/types.d.ts +6 -0
- package/types/providers/DashProvider/baseDashProvider.d.ts +2 -0
- package/types/providers/DashProvider/lib/fetcher.d.ts +22 -1
- package/types/providers/DashProvider/lib/player.d.ts +3 -0
- package/types/providers/DashProviderVirtual/baseDashProvider.d.ts +2 -0
- package/types/providers/DashProviderVirtual/lib/fetcher.d.ts +22 -1
- package/types/providers/DashProviderVirtual/lib/player/types.d.ts +4 -0
- package/types/providers/ProviderContainer/index.d.ts +2 -0
- package/types/providers/ProviderContainer/utils/selectFormats.d.ts +10 -0
- package/types/providers/utils/initialByteRange.d.ts +22 -0
- package/types/utils/ThroughputEstimator.d.ts +6 -1
- package/types/utils/prepareMedia.d.ts +40 -0
- package/types/utils/prepareSources.d.ts +55 -0
- package/types/utils/tuningConfig.d.ts +37 -0
- package/types/utils/warmUpSources.d.ts +21 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vkontakte/videoplayer-core",
|
|
3
|
-
"version": "2.0.176-
|
|
3
|
+
"version": "2.0.176-dev.477f4c39b.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.105-
|
|
45
|
+
"@vkontakte/videoplayer-shared": "1.0.105-dev.477f4c39b.0"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -3,7 +3,12 @@ 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
|
|
6
|
+
import warmUpSources from "./utils/warmUpSources";
|
|
7
|
+
import type { IWarmUp, IWarmUpTargets } from "./utils/warmUpSources";
|
|
8
|
+
import prepareSources from "./utils/prepareSources";
|
|
9
|
+
import type { IPreparedSources, IPrepareSourcesOptions } from "./utils/prepareSources";
|
|
10
|
+
import type { IPreparedMedia } from "./utils/prepareMedia";
|
|
11
|
+
import type { IPlayer, IPlayerInfo, IPlayerEvents, IConfig, ISources, ICueSettings, IExternalTextTrack, ITextTrack, PlaybackRate, IVideoStream, IAudioStream, StartEnd, HttpConnectionMetrics, HttpDownloadMetrics } from "./player/types";
|
|
7
12
|
import { PlaybackState, ChromecastState, HttpConnectionType } from "./player/types";
|
|
8
13
|
import type { IOptionalTuningConfig } from "./utils/tuningConfig";
|
|
9
14
|
export { clientChecker, isMobile } from "./utils/ClientChecker";
|
|
@@ -15,5 +20,6 @@ import { Subscription, Observable, Subject, ValueSubject, VideoQuality } from "@
|
|
|
15
20
|
* @deprecated
|
|
16
21
|
*/
|
|
17
22
|
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 };
|
|
19
|
-
export {
|
|
23
|
+
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 };
|
|
24
|
+
export type { IWarmUp, IWarmUpTargets, IPreparedSources, IPrepareSourcesOptions, IPreparedMedia };
|
|
25
|
+
export { Player, warmUpSources, prepareSources, PlaybackState, ChromecastState, HttpConnectionType, Surface, Subscription, VideoFormat, VideoQuality, Observable, Subject, ValueSubject, VERSION, SDK_VERSION, PredefinedQualityLimits, VideoCodec, VideoCodecName };
|
package/types/player/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IPreparedSources } from "../utils/prepareSources";
|
|
1
2
|
import type { DebugData, IError, ILogEntry, IObservable, IRectangle, IValueObservable, IValueSubject, Kbps, Milliseconds, QualityLimits, Seconds, Subject, ValueSubject, VideoQuality } from "@vkontakte/videoplayer-shared";
|
|
2
3
|
import type { dump } from "../utils/playbackTelemetry";
|
|
3
4
|
export interface StartEnd<Unit extends number> {
|
|
@@ -558,6 +559,11 @@ export interface IConfig {
|
|
|
558
559
|
* Нужно ли recoverableError обрабатывать как ошибку провайдера или будет снаружи обрабатываться.
|
|
559
560
|
*/
|
|
560
561
|
handleNetworkRecoverableErrorAsProviderError?: boolean;
|
|
562
|
+
/**
|
|
563
|
+
* UVP-11502: манифест, запрошенный потребителем заранее — см. prepareSources.
|
|
564
|
+
* Не передан — плеер запрашивает манифест сам, как и раньше.
|
|
565
|
+
*/
|
|
566
|
+
preparedSources?: IPreparedSources;
|
|
561
567
|
}
|
|
562
568
|
export interface ISources {
|
|
563
569
|
[VideoFormat.MPEG]?: IMpegSource;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IPreparedSources } from "../../utils/prepareSources";
|
|
1
2
|
import type { IAudioTrack, IDashURLSource, IHLSSource, IInternalTextTrack, IVideoTrack, VideoCodec } from "../../player/types";
|
|
2
3
|
import type { IProviderSubscriptionInfo } from "./lib/types";
|
|
3
4
|
import { ProviderState } from "./lib/types";
|
|
@@ -13,6 +14,7 @@ import StallsManager from "../utils/StallsManager";
|
|
|
13
14
|
import { AbrManager } from "../utils/Abr/abrManager";
|
|
14
15
|
import { ElementSizeManager } from "../utils/HTMLVideoElement/ElementSizeManager";
|
|
15
16
|
type IParams = IProviderParams<IDashURLSource> & {
|
|
17
|
+
preparedSources?: IPreparedSources;
|
|
16
18
|
sourceHls?: IHLSSource;
|
|
17
19
|
forceVideoCodec?: VideoCodec;
|
|
18
20
|
isOnDemand?: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { HttpConnectionType, HttpConnectionMetrics, HttpDownloadMetrics } from "../../../player/types";
|
|
2
|
+
import type { IPreparedSources } from "../../../utils/prepareSources";
|
|
2
3
|
import type ThroughputEstimator from "../../../utils/ThroughputEstimator";
|
|
3
4
|
import type { Byte, IValueSubject, ISubject, Milliseconds, IRange, ITracer, IError } from "@vkontakte/videoplayer-shared";
|
|
4
5
|
import { abortable } from "@vkontakte/videoplayer-shared";
|
|
@@ -30,6 +31,8 @@ export interface IParams {
|
|
|
30
31
|
cacheHitTtfbMaxMs?: Milliseconds;
|
|
31
32
|
preloadFirstSegment?: boolean;
|
|
32
33
|
maxQualityForFirstSegmentPreload?: ExactVideoQuality;
|
|
34
|
+
preparedSources?: IPreparedSources;
|
|
35
|
+
preparedSourcesTimeout?: Milliseconds;
|
|
33
36
|
}
|
|
34
37
|
export type Priority = "high" | "low" | "auto";
|
|
35
38
|
export interface FetchParamsWithUrl extends FetchParams {
|
|
@@ -78,13 +81,17 @@ export declare class Fetcher {
|
|
|
78
81
|
private measureNonSegmentRequests;
|
|
79
82
|
private measureFastSamples;
|
|
80
83
|
private cacheHitTtfbMaxMs;
|
|
84
|
+
private preparedSources?;
|
|
85
|
+
private preparedMedia?;
|
|
86
|
+
private preparedMediaResolved?;
|
|
87
|
+
private preparedSourcesTimeout;
|
|
81
88
|
private preloadFirstSegment;
|
|
82
89
|
private maxQualityForFirstSegmentPreload;
|
|
83
90
|
private startupPhase;
|
|
84
91
|
private performanceObserver;
|
|
85
92
|
private pendingConnectionMetrics;
|
|
86
93
|
private handleExtendedNetworkErrorsSet;
|
|
87
|
-
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, useUrlCacheMechanism, measureNonSegmentRequests, measureFastSamples, cacheHitTtfbMaxMs, preloadFirstSegment, maxQualityForFirstSegmentPreload }: IParams);
|
|
94
|
+
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, useUrlCacheMechanism, measureNonSegmentRequests, measureFastSamples, cacheHitTtfbMaxMs, preloadFirstSegment, maxQualityForFirstSegmentPreload, preparedSources, preparedSourcesTimeout }: IParams);
|
|
88
95
|
private onHeadersReceived;
|
|
89
96
|
private setupPerformanceObserver;
|
|
90
97
|
private processPerformanceResourceTiming;
|
|
@@ -99,6 +106,20 @@ export declare class Fetcher {
|
|
|
99
106
|
private fetchByteRangeRepresentation;
|
|
100
107
|
private fetchTemplateRepresentation;
|
|
101
108
|
private isLikelyCacheHitByTtfb;
|
|
109
|
+
/**
|
|
110
|
+
* Ответ на манифест, запрошенный до создания плеера. Отдаётся один раз и только на тот же URL:
|
|
111
|
+
* разойдётся адрес — значит подготовка выбрала другой формат, и запрос идёт обычным путём.
|
|
112
|
+
*/
|
|
113
|
+
private takePrepared;
|
|
114
|
+
/**
|
|
115
|
+
* Байты, скачанные до создания плеера. Отдаются по тому же URL и только на вложенный диапазон:
|
|
116
|
+
* подготовка тянет файл с нуля, поэтому смещения запроса совпадают с индексами в её буфере.
|
|
117
|
+
*/
|
|
118
|
+
private takePreparedMedia;
|
|
119
|
+
/**
|
|
120
|
+
* Плеер выбрал другую репрезентацию: держать чужую загрузку дальше значит отнимать у него полосу.
|
|
121
|
+
*/
|
|
122
|
+
private releasePreparedMedia;
|
|
102
123
|
private doFetch;
|
|
103
124
|
private unsubscribeAbortSubscription;
|
|
104
125
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IPreparedSources } from "../../../utils/prepareSources";
|
|
1
2
|
import type { IHLSSource, HttpConnectionType, HttpConnectionMetrics, HttpDownloadMetrics, VideoCodec } from "../../../player/types";
|
|
2
3
|
import { LiveStreamStatus } from "./types";
|
|
3
4
|
import type { CommonInit, Manifest, Representation, Segment, TextRepresentation } from "../../utils/parsers/types";
|
|
@@ -18,6 +19,8 @@ export interface Params {
|
|
|
18
19
|
throughputEstimator: ThroughputEstimator;
|
|
19
20
|
tuning: ITuningConfig;
|
|
20
21
|
compatibilityMode?: boolean;
|
|
22
|
+
preparedSources?: IPreparedSources;
|
|
23
|
+
preparedSourcesTimeout?: Milliseconds;
|
|
21
24
|
forceVideoCodec?: VideoCodec;
|
|
22
25
|
tracer: ITracer;
|
|
23
26
|
isOnDemand: boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IPreparedSources } from "../../utils/prepareSources";
|
|
1
2
|
import type { IAudioTrack, IDashURLSource, IHLSSource, IInternalTextTrack, IVideoTrack, VideoCodec } from "../../player/types";
|
|
2
3
|
import type { IProviderSubscriptionInfo } from "./lib/types";
|
|
3
4
|
import { ProviderState } from "./lib/types";
|
|
@@ -13,6 +14,7 @@ import { ElementSizeManager } from "../utils/HTMLVideoElement/ElementSizeManager
|
|
|
13
14
|
import type { BasePlayer } from "./lib/player/basePlayer";
|
|
14
15
|
import { AbrManager } from "../utils/Abr/abrManager";
|
|
15
16
|
type IParams = IProviderParams<IDashURLSource> & {
|
|
17
|
+
preparedSources?: IPreparedSources;
|
|
16
18
|
sourceHls?: IHLSSource;
|
|
17
19
|
forceVideoCodec?: VideoCodec;
|
|
18
20
|
isOnDemand?: boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IPreparedSources } from "../../../utils/prepareSources";
|
|
1
2
|
import type { HttpConnectionType, HttpConnectionMetrics, HttpDownloadMetrics } from "../../../player/types";
|
|
2
3
|
import type ThroughputEstimator from "../../../utils/ThroughputEstimator";
|
|
3
4
|
import type { Byte, IError, IRange, ISubject, ITracer, IValueSubject, Milliseconds } from "@vkontakte/videoplayer-shared";
|
|
@@ -21,6 +22,8 @@ export interface IParams {
|
|
|
21
22
|
throughputEstimator?: ThroughputEstimator;
|
|
22
23
|
requestQuic: boolean;
|
|
23
24
|
compatibilityMode?: boolean;
|
|
25
|
+
preparedSources?: IPreparedSources;
|
|
26
|
+
preparedSourcesTimeout?: Milliseconds;
|
|
24
27
|
tracer: ITracer;
|
|
25
28
|
useEnableSubtitlesParam?: boolean;
|
|
26
29
|
handleExtendedNetworkErrorsSet?: boolean;
|
|
@@ -77,13 +80,17 @@ export declare class Fetcher {
|
|
|
77
80
|
private measureNonSegmentRequests;
|
|
78
81
|
private measureFastSamples;
|
|
79
82
|
private cacheHitTtfbMaxMs;
|
|
83
|
+
private preparedSources?;
|
|
84
|
+
private preparedMedia?;
|
|
85
|
+
private preparedMediaResolved?;
|
|
86
|
+
private preparedSourcesTimeout;
|
|
80
87
|
private preloadFirstSegment;
|
|
81
88
|
private maxQualityForFirstSegmentPreload;
|
|
82
89
|
private startupPhase;
|
|
83
90
|
private performanceObserver;
|
|
84
91
|
private pendingConnectionMetrics;
|
|
85
92
|
private handleExtendedNetworkErrorsSet;
|
|
86
|
-
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, useUrlCacheMechanism, measureNonSegmentRequests, measureFastSamples, cacheHitTtfbMaxMs, preloadFirstSegment, maxQualityForFirstSegmentPreload }: IParams);
|
|
93
|
+
constructor({ throughputEstimator, requestQuic, tracer, compatibilityMode, useEnableSubtitlesParam, handleExtendedNetworkErrorsSet, useUrlCacheMechanism, measureNonSegmentRequests, measureFastSamples, cacheHitTtfbMaxMs, preparedSources, preparedSourcesTimeout, preloadFirstSegment, maxQualityForFirstSegmentPreload }: IParams);
|
|
87
94
|
private onHeadersReceived;
|
|
88
95
|
private setupPerformanceObserver;
|
|
89
96
|
private processResourceTiming;
|
|
@@ -98,5 +105,19 @@ export declare class Fetcher {
|
|
|
98
105
|
private fetchByteRangeRepresentation;
|
|
99
106
|
private fetchTemplateRepresentation;
|
|
100
107
|
private isLikelyCacheHitByTtfb;
|
|
108
|
+
/**
|
|
109
|
+
* Ответ на манифест, запрошенный до создания плеера. Отдаётся один раз и только на тот же URL:
|
|
110
|
+
* разойдётся адрес — значит подготовка выбрала другой формат, и запрос идёт обычным путём.
|
|
111
|
+
*/
|
|
112
|
+
private takePrepared;
|
|
113
|
+
/**
|
|
114
|
+
* Байты, скачанные до создания плеера. Отдаются по тому же URL и только на вложенный диапазон:
|
|
115
|
+
* подготовка тянет файл с нуля, поэтому смещения запроса совпадают с индексами в её буфере.
|
|
116
|
+
*/
|
|
117
|
+
private takePreparedMedia;
|
|
118
|
+
/**
|
|
119
|
+
* Плеер выбрал другую репрезентацию: держать чужую загрузку дальше значит отнимать у него полосу.
|
|
120
|
+
*/
|
|
121
|
+
private releasePreparedMedia;
|
|
101
122
|
private doFetch;
|
|
102
123
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Milliseconds } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { IPreparedSources } from "../../../../utils/prepareSources";
|
|
1
3
|
import type ThroughputEstimator from "../../../../utils/ThroughputEstimator";
|
|
2
4
|
import type { ITuningConfig } from "../../../../utils/tuningConfig";
|
|
3
5
|
import type { VideoCodec } from "../../../../player/types";
|
|
@@ -12,6 +14,8 @@ export interface Params {
|
|
|
12
14
|
throughputEstimator: ThroughputEstimator;
|
|
13
15
|
tuning: ITuningConfig;
|
|
14
16
|
compatibilityMode?: boolean;
|
|
17
|
+
preparedSources?: IPreparedSources;
|
|
18
|
+
preparedSourcesTimeout?: Milliseconds;
|
|
15
19
|
forceVideoCodec?: VideoCodec;
|
|
16
20
|
tracer: ITracer;
|
|
17
21
|
isOnDemand?: boolean;
|
|
@@ -5,6 +5,7 @@ import type { IError, ISubject, IValueSubject, IRectangle } from "@vkontakte/vid
|
|
|
5
5
|
import { ValueSubject } from "@vkontakte/videoplayer-shared";
|
|
6
6
|
import type { IDesiredState, IProviderDependencies, IProviderOutput } from "../types";
|
|
7
7
|
import type { IProviderContainer, IProviderEntry } from "./types";
|
|
8
|
+
import type { IPreparedSources } from "../../utils/prepareSources";
|
|
8
9
|
interface IParams extends IProviderDependencies {
|
|
9
10
|
container: HTMLElement;
|
|
10
11
|
sources: ISources;
|
|
@@ -16,6 +17,7 @@ interface IParams extends IProviderDependencies {
|
|
|
16
17
|
panelSize?: IRectangle;
|
|
17
18
|
skipVideoElVolumeSync$: ValueSubject<boolean>;
|
|
18
19
|
handleNetworkRecoverableErrorAsProviderError?: boolean;
|
|
20
|
+
preparedSources?: IPreparedSources;
|
|
19
21
|
}
|
|
20
22
|
export default class ProviderContainer implements IProviderContainer {
|
|
21
23
|
current$: IValueSubject<IProviderEntry>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ISources, VideoFormat } from "../../../player/types";
|
|
2
|
+
import type { ITuningConfig } from "../../../utils/tuningConfig";
|
|
3
|
+
/**
|
|
4
|
+
* Порядок форматов для экрана: платформенный приоритет, пересечённый с тем, что реально отдал API,
|
|
5
|
+
* с учётом принудительного формата и списка нежелательных.
|
|
6
|
+
*
|
|
7
|
+
* Вынесено из ProviderContainer, потому что тот же порядок нужен подготовке источников снаружи
|
|
8
|
+
* плеера: она обязана выбрать тот же формат, иначе прогретый запрос уйдёт не за тем манифестом.
|
|
9
|
+
*/
|
|
10
|
+
export declare const selectScreenFormats: (sources: ISources, tuning: ITuningConfig) => VideoFormat[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Byte, IRange } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { ByteRangeSegmentReference } from "./parsers/types";
|
|
3
|
+
export interface IInitialByteRange {
|
|
4
|
+
range: IRange<Byte>;
|
|
5
|
+
/** Index попал в тот же запрос — значит второй round-trip за ним не нужен. */
|
|
6
|
+
indexLoadedWithInit: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface IOptions {
|
|
9
|
+
/** Тянуть ли следом первый сегмент (UVP-10107): длина известна из манифеста. */
|
|
10
|
+
withFirstSegment: boolean;
|
|
11
|
+
/** Нижняя граница хвоста: подготовка снаружи добирает диапазон до своего потолка. */
|
|
12
|
+
minBytes?: Byte;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Диапазон первого запроса к медиа: init, при удачной раскладке index следом за ним, и — если
|
|
16
|
+
* просили — первый сегмент.
|
|
17
|
+
*
|
|
18
|
+
* Вынесено из фетчеров, потому что тот же диапазон считает подготовка источников снаружи плеера:
|
|
19
|
+
* разойдись эти расчёты на байт, и подготовленный ответ не подойдёт под запрос плеера.
|
|
20
|
+
*/
|
|
21
|
+
export declare const initialByteRange: ({ initRange, indexRange, firstSegmentLength }: Pick<ByteRangeSegmentReference, "initRange" | "indexRange" | "firstSegmentLength">, { withFirstSegment, minBytes }: IOptions) => IInitialByteRange;
|
|
22
|
+
export {};
|
|
@@ -23,8 +23,13 @@ declare class ThroughputEstimator {
|
|
|
23
23
|
addRawRtt(time: Milliseconds): void;
|
|
24
24
|
private sanityCheck;
|
|
25
25
|
get throughputVariance$(): IValueSubject<number>;
|
|
26
|
-
|
|
26
|
+
static loadStored(key: string, legacyKey: string, tuning: ITuningConfig["throughputEstimator"]): number | undefined;
|
|
27
27
|
private static writeStored;
|
|
28
28
|
private static validateStored;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Стартовая оценка сети без создания оценщика: подготовка источников выбирает качество до того,
|
|
32
|
+
* как появится плеер, и обязана взять ровно то значение, с которого он стартует.
|
|
33
|
+
*/
|
|
34
|
+
export declare const initialThroughputEstimation: (tuning: ITuningConfig["throughputEstimator"]) => Kbps;
|
|
30
35
|
export default ThroughputEstimator;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Byte, IRange, IRectangle, Milliseconds } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { ExactVideoQuality } from "@vkontakte/videoplayer-shared";
|
|
3
|
+
import type { ITuningConfig } from "./tuningConfig";
|
|
4
|
+
/** Замер подготовительной загрузки: плеер стартует не с дефолтной гипотезы, а со свежего сэмпла. */
|
|
5
|
+
export interface IPreparedMediaMetrics {
|
|
6
|
+
bytes: Byte;
|
|
7
|
+
duration: Milliseconds;
|
|
8
|
+
rtt: Milliseconds;
|
|
9
|
+
}
|
|
10
|
+
export interface IPreparedMedia {
|
|
11
|
+
/** URL репрезентации без диапазона: плеер запросит его же, диапазон он приложит свой. */
|
|
12
|
+
readonly url: string;
|
|
13
|
+
/** Срез уже доехавших байт. `undefined` — диапазон не наш, не дождались или подготовку порвали. */
|
|
14
|
+
take: (range: IRange<Byte>, timeout: Milliseconds) => Promise<ArrayBuffer | undefined>;
|
|
15
|
+
/** Отдаётся один раз: второй вызов вернёт `undefined`, чтобы сэмпл не учли дважды. */
|
|
16
|
+
takeMetrics: () => IPreparedMediaMetrics | undefined;
|
|
17
|
+
/** Рвёт поток и освобождает буфер. Идемпотентно. */
|
|
18
|
+
destroy: () => void;
|
|
19
|
+
}
|
|
20
|
+
export interface IPrepareMediaOptions {
|
|
21
|
+
manifestText: string;
|
|
22
|
+
manifestUrl: string;
|
|
23
|
+
tuning: ITuningConfig;
|
|
24
|
+
/** В режиме совместимости диапазон уходит заголовком, а не параметром URL. */
|
|
25
|
+
compatibilityMode?: boolean;
|
|
26
|
+
/** Куда встанет плеер. Нет подсказки — качество ограничивается потолком предзагрузки. */
|
|
27
|
+
container?: IRectangle;
|
|
28
|
+
/** Качество, выбранное пользователем: тогда гадать не нужно вовсе. */
|
|
29
|
+
quality?: ExactVideoQuality;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Догружает начало медиа выбранной репрезентации: init, index и столько сегментов, сколько влезает
|
|
33
|
+
* в потолок предзагрузки, — одним байтовым диапазоном от нуля файла.
|
|
34
|
+
*
|
|
35
|
+
* Репрезентация выбирается тем же `selectTrackByRules`, что и в плеере, на той же сохранённой
|
|
36
|
+
* оценке сети; диапазон считает та же `initialByteRange`, что и фетчер. Разойдись любое из двух —
|
|
37
|
+
* плеер запросит не тот адрес, и подготовка пропадёт впустую.
|
|
38
|
+
*/
|
|
39
|
+
declare const _default: (options: IPrepareMediaOptions, signal: AbortSignal) => Promise<IPreparedMedia | undefined>;
|
|
40
|
+
export default _default;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ISources } from "../player/types";
|
|
2
|
+
import { VideoFormat } from "../player/types";
|
|
3
|
+
import type { IPreparedMedia } from "./prepareMedia";
|
|
4
|
+
import type { IOptionalTuningConfig } from "./tuningConfig";
|
|
5
|
+
import type { ExactVideoQuality, IRectangle } from "@vkontakte/videoplayer-shared";
|
|
6
|
+
export interface IPreparedSources {
|
|
7
|
+
/** URL, ради которого всё затевалось: плеер возьмёт ответ, только если запросит ровно его. */
|
|
8
|
+
readonly url: string;
|
|
9
|
+
readonly format: VideoFormat;
|
|
10
|
+
/** Ответ на запрос манифеста. Тело не вычитано — его прочитает плеер. */
|
|
11
|
+
readonly response: Promise<Response | undefined>;
|
|
12
|
+
/**
|
|
13
|
+
* Начало медиа выбранной репрезентации. Появляется только под `usePreparedFirstSegments` и только
|
|
14
|
+
* после разбора манифеста, поэтому это второй промис, а не поле готового объекта.
|
|
15
|
+
*/
|
|
16
|
+
readonly media?: Promise<IPreparedMedia | undefined>;
|
|
17
|
+
/**
|
|
18
|
+
* Владение перешло плееру: снимает самоотмену по TTL. Дальше хэндл живёт столько, сколько живёт
|
|
19
|
+
* фетчер, и умирает вместе с ним.
|
|
20
|
+
*/
|
|
21
|
+
take: () => void;
|
|
22
|
+
/** Рвёт обе стадии и освобождает буфер. Идемпотентно. */
|
|
23
|
+
destroy: () => void;
|
|
24
|
+
}
|
|
25
|
+
export interface IPrepareSourcesOptions {
|
|
26
|
+
/** Конфиг плеера потребителя: недостающее добирается дефолтами, как это сделает сам плеер. */
|
|
27
|
+
tuning?: IOptionalTuningConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Хэндл прошлой подготовки того же видео. Потребитель зовёт подготовку и до загрузки конфига
|
|
30
|
+
* плеера, и после: сошёлся URL — отдаём прежний запрос, разошёлся — прежний отменяем и идём
|
|
31
|
+
* заново. Иначе конфиг, меняющий URL или формат, тихо обесценил бы подготовку.
|
|
32
|
+
*/
|
|
33
|
+
previous?: IPreparedSources;
|
|
34
|
+
/**
|
|
35
|
+
* Размер места, куда встанет плеер. Без него выбор качества опирается на одну оценку сети,
|
|
36
|
+
* поэтому ограничивается потолком предзагрузки.
|
|
37
|
+
*/
|
|
38
|
+
container?: IRectangle;
|
|
39
|
+
/** Качество, выбранное пользователем ранее: с ним подготовка не гадает вовсе. */
|
|
40
|
+
quality?: ExactVideoQuality;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Запрашивает манифест до создания плеера — как только потребителю стали известны источники.
|
|
44
|
+
*
|
|
45
|
+
* Смысл в запасе: между ответом API со ссылками и первым запросом плеера проходят сотни
|
|
46
|
+
* миллисекунд, и в них укладывается DNS, TCP, TLS и сама загрузка манифеста. Выбор формата
|
|
47
|
+
* и достройка URL повторяют логику плеера, поэтому подготовленный ответ подходит ему как есть;
|
|
48
|
+
* разойдутся — плеер сходит за манифестом сам.
|
|
49
|
+
*
|
|
50
|
+
* Под `usePreparedFirstSegments` следом догружается начало медиа. У этой стадии, в отличие от
|
|
51
|
+
* манифеста, висит открытый поток и растущий буфер, поэтому у хэндла есть и самоотмена по TTL:
|
|
52
|
+
* потребитель обязан звать `destroy` на всех выходах, но выход бывает и молчаливым.
|
|
53
|
+
*/
|
|
54
|
+
declare const _default: (sources: ISources, options?: IPrepareSourcesOptions) => IPreparedSources | undefined;
|
|
55
|
+
export default _default;
|
|
@@ -475,6 +475,43 @@ export type ITuningConfig = {
|
|
|
475
475
|
*/
|
|
476
476
|
useUrlCacheMechanism?: boolean;
|
|
477
477
|
/**
|
|
478
|
+
* Прогревать ли соединение к хостам раздачи. **Сам SDK этот флаг не читает** — прогрев живёт
|
|
479
|
+
* в `warmUpSources`, а зовёт её потребитель: внутри SDK запаса времени до первого запроса нет.
|
|
480
|
+
* Флаг лежит здесь, чтобы раскаткой управлял тот же ключ конфига плеера, что и остальными
|
|
481
|
+
* экспериментами, а не отдельная ручка на каждом потребителе.
|
|
482
|
+
*/
|
|
483
|
+
usePreconnectSources?: boolean;
|
|
484
|
+
/**
|
|
485
|
+
* Запрашивать ли манифест до создания плеера. **Сам SDK этот флаг не читает** — подготовку
|
|
486
|
+
* зовёт потребитель через `prepareSources`, потому что запас времени есть только у него.
|
|
487
|
+
* Флаг лежит здесь, чтобы раскаткой управлял ключ конфига плеера, а не ручка на потребителе.
|
|
488
|
+
*/
|
|
489
|
+
usePreparedSources?: boolean;
|
|
490
|
+
/**
|
|
491
|
+
* Сколько ждать манифест, запрошенный потребителем заранее (`prepareSources`), прежде чем
|
|
492
|
+
* идти за ним самому. Ноль ожидания не отменяет подготовку — он делает её бесполезной,
|
|
493
|
+
* поэтому предел нужен только как страховка от зависшего запроса снаружи.
|
|
494
|
+
*/
|
|
495
|
+
preparedSourcesTimeout: Milliseconds;
|
|
496
|
+
/**
|
|
497
|
+
* Догружать ли вслед за манифестом начало медиа выбранной репрезентации — init, index и первые
|
|
498
|
+
* сегменты одним байтовым диапазоном. Качество выбирается тем же `selectTrackByRules`, что и в
|
|
499
|
+
* плеере, на той же сохранённой оценке сети. Читает флаг не SDK, а потребитель: подготовку зовёт
|
|
500
|
+
* он, и только у него есть запас времени до создания плеера.
|
|
501
|
+
*/
|
|
502
|
+
usePreparedFirstSegments?: boolean;
|
|
503
|
+
/**
|
|
504
|
+
* Потолок предзагрузки медиа в байтах. Ограничивает и трафик несостоявшегося просмотра, и память:
|
|
505
|
+
* скачанное держится в буфере, пока его не заберёт плеер.
|
|
506
|
+
*/
|
|
507
|
+
preparedFirstSegmentsMaxBytes: Byte;
|
|
508
|
+
/**
|
|
509
|
+
* Сколько подготовка живёт, если её никто не забрал. Потребитель обязан звать `destroy` на всех
|
|
510
|
+
* выходах, но выход бывает и молчаливым — вкладку закрыли, плеер так и не создали. Без предела
|
|
511
|
+
* открытый поток и накопленный буфер пережили бы сам просмотр.
|
|
512
|
+
*/
|
|
513
|
+
preparedSourcesTtl: Milliseconds;
|
|
514
|
+
/**
|
|
478
515
|
* Очищаем кэш урлов при падение провайдера.
|
|
479
516
|
*/
|
|
480
517
|
dropUrlCacheWhenProviderCrashed?: boolean;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ISources } from "../player/types";
|
|
2
|
+
export interface IWarmUpTargets {
|
|
3
|
+
preconnect: string[];
|
|
4
|
+
dnsPrefetch: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface IWarmUp {
|
|
7
|
+
applied: IWarmUpTargets;
|
|
8
|
+
destroy: () => void;
|
|
9
|
+
}
|
|
10
|
+
interface IOptions {
|
|
11
|
+
failoverHosts?: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Прогрев соединения к хостам раздачи по готовым `sources` — до того, как создан плеер.
|
|
15
|
+
*
|
|
16
|
+
* Экономия равна запасу времени до первого запроса, поэтому звать имеет смысл там, где `sources`
|
|
17
|
+
* появились сильно раньше плеера: сразу после ответа API у потребителя. Сам SDK прогрев не вызывает,
|
|
18
|
+
* а флаг `tuning.usePreconnectSources` нужен потребителю, чтобы раскаткой управлял конфиг плеера.
|
|
19
|
+
*/
|
|
20
|
+
declare const _default: (sources: ISources, { failoverHosts }?: IOptions) => IWarmUp;
|
|
21
|
+
export default _default;
|