@vkontakte/videoplayer-core 2.0.171-dev.ed76c949d.0 → 2.0.172-beta.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 -127
- package/es2015.esm.js +17 -127
- package/esnext.cjs +16 -126
- package/esnext.esm.js +16 -126
- package/evergreen.esm.js +16 -126
- package/package.json +2 -2
- package/types/player/Player.d.ts +4 -1
- package/types/player/types.d.ts +21 -5
- package/types/providers/DashLiveProvider/utils/LiveDashPlayer.d.ts +9 -0
- package/types/providers/DashProvider/baseDashProvider.d.ts +0 -3
- package/types/providers/DashProvider/lib/buffer.d.ts +6 -2
- package/types/providers/DashProvider/lib/player.d.ts +1 -0
- package/types/providers/DashProviderVirtual/baseDashProvider.d.ts +1 -4
- package/types/providers/DashProviderVirtual/lib/buffer/nativeBufferManager.d.ts +3 -1
- package/types/providers/DashProviderVirtual/lib/buffer/sourceBufferTaskQueue.d.ts +3 -1
- package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/baseVirtualBufferManager.versionA.d.ts +3 -1
- package/types/providers/DashProviderVirtual/lib/player/basePlayer.d.ts +3 -1
- package/types/providers/ProviderContainer/Mayday/heuristics/SegmentAppendHeuristic.d.ts +10 -0
- package/types/providers/ProviderContainer/Mayday/types.d.ts +1 -1
- package/types/providers/types.d.ts +4 -2
- package/types/providers/utils/Abr/abrManager.d.ts +2 -0
- package/types/providers/utils/Abr/selectTrackByRules.d.ts +23 -0
- package/types/providers/utils/Abr/utils.d.ts +4 -1
- package/types/providers/utils/HTMLVideoElement/observable.d.ts +1 -1
- package/types/providers/utils/HTMLVideoElement/pool.d.ts +1 -1
- package/types/utils/ThroughputEstimator.d.ts +2 -0
- package/types/utils/buffer/isBrokenSegmentAppend.d.ts +3 -0
- package/types/utils/buffer/timeRangesToIntervals.d.ts +3 -0
- package/types/utils/tuningConfig.d.ts +34 -4
- package/types/utils/autoSelectTrack.d.ts +0 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vkontakte/videoplayer-core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.172-beta.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.101-beta.1"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/types/player/Player.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IOptionalTuningConfig } from "../utils/tuningConfig";
|
|
2
|
-
import type { ILogEntry, ITracer, QualityLimits, Seconds, VideoQuality } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { ILogEntry, ITracer, QualityLimits, Seconds, VideoQuality, DebugData } from "@vkontakte/videoplayer-shared";
|
|
3
3
|
import { type IAudioStream, type IConfig, type ICueSettings, type IExternalTextTrack, type IPlayer, type ITextTrack, type IVideoStream, type PlaybackRate, type PlayerEventsImpl, type PlayerExperimentalImpl, type PlayerInfoImpl, PredefinedQualityLimits } from "./types";
|
|
4
4
|
import type { IPlayerOptions } from "../utils/playerOptions";
|
|
5
5
|
export default class Player implements IPlayer {
|
|
@@ -78,7 +78,10 @@ export default class Player implements IPlayer {
|
|
|
78
78
|
getExactTime(): Seconds;
|
|
79
79
|
getExactLiveTime(): Seconds;
|
|
80
80
|
getAllLogs(): ILogEntry[];
|
|
81
|
+
getDebugData(): DebugData;
|
|
82
|
+
private buildDebugData;
|
|
81
83
|
private setIntrinsicVideoSize;
|
|
84
|
+
private initDebugDataSubscriptions;
|
|
82
85
|
private initDesiredStateSubscriptions;
|
|
83
86
|
private initProviderContainerSubscription;
|
|
84
87
|
private initChromecastSubscription;
|
package/types/player/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IError, ILogEntry, IObservable, IRectangle, IValueObservable, IValueSubject, Kbps, Milliseconds, QualityLimits, Seconds, Subject, ValueSubject, VideoQuality } from "@vkontakte/videoplayer-shared";
|
|
1
|
+
import type { DebugData, IError, ILogEntry, IObservable, IRectangle, IValueObservable, IValueSubject, Kbps, Milliseconds, QualityLimits, Seconds, Subject, ValueSubject, VideoQuality } from "@vkontakte/videoplayer-shared";
|
|
2
2
|
import type { dump } from "../utils/playbackTelemetry";
|
|
3
3
|
export interface StartEnd<Unit extends number> {
|
|
4
4
|
start: Unit;
|
|
@@ -311,17 +311,29 @@ export interface PlayerInfoValues {
|
|
|
311
311
|
*/
|
|
312
312
|
currentPlaybackRate$: PlaybackRate;
|
|
313
313
|
/**
|
|
314
|
-
* Текущий
|
|
314
|
+
* Текущий видео буффер-плеера (тот; который содержит текущую позицию воспроизведения)
|
|
315
315
|
*
|
|
316
316
|
* default value: `undefined`
|
|
317
317
|
*/
|
|
318
|
-
|
|
318
|
+
currentVideoBuffer$: StartEnd<Seconds> | undefined;
|
|
319
319
|
/**
|
|
320
|
-
* Текущий
|
|
320
|
+
* Текущий аудио-буффер плеера (тот; который содержит текущую позицию воспроизведения)
|
|
321
321
|
*
|
|
322
322
|
* default value: `undefined`
|
|
323
323
|
*/
|
|
324
|
-
|
|
324
|
+
currentAudioBuffer$: StartEnd<Seconds> | undefined;
|
|
325
|
+
/**
|
|
326
|
+
* Текущий браузерный видео-буффер (тот; который содержит текущую позицию воспроизведения)
|
|
327
|
+
*
|
|
328
|
+
* default value: `undefined`
|
|
329
|
+
*/
|
|
330
|
+
currentNativeVideoBuffer$: StartEnd<Seconds> | undefined;
|
|
331
|
+
/**
|
|
332
|
+
* Текущий браузерный аудио-буффер (тот; который содержит текущую позицию воспроизведения)
|
|
333
|
+
*
|
|
334
|
+
* default value: `undefined`
|
|
335
|
+
*/
|
|
336
|
+
currentNativeAudioBuffer$: StartEnd<Seconds> | undefined;
|
|
325
337
|
/** Суммарная длительность всех буферизованных диапазонов в миллисекундах */
|
|
326
338
|
totalBufferDuration$: Milliseconds | undefined;
|
|
327
339
|
/**
|
|
@@ -456,6 +468,10 @@ export interface PlayerInfoValues {
|
|
|
456
468
|
* Длина аудио сегмента
|
|
457
469
|
*/
|
|
458
470
|
currentAudioSegmentLength$: number;
|
|
471
|
+
/**
|
|
472
|
+
* Отладочная информация
|
|
473
|
+
*/
|
|
474
|
+
debugData$: DebugData;
|
|
459
475
|
}
|
|
460
476
|
export type IPlayerInfo = { [K in keyof PlayerInfoValues]: IValueObservable<PlayerInfoValues[K]> };
|
|
461
477
|
export type PlayerInfoImpl = { [K in keyof PlayerInfoValues]: ValueSubject<PlayerInfoValues[K]> };
|
|
@@ -60,6 +60,7 @@ export default class LiveDashPlayer {
|
|
|
60
60
|
*/
|
|
61
61
|
private waitingForFirstBufferAfterSrcChange;
|
|
62
62
|
private params;
|
|
63
|
+
private playbackStateSubscription;
|
|
63
64
|
soundProhibitedEvent$: Subject<void>;
|
|
64
65
|
constructor(params: IParams);
|
|
65
66
|
attachSource(manifestUrl: string): void;
|
|
@@ -101,6 +102,14 @@ export default class LiveDashPlayer {
|
|
|
101
102
|
* send buffering notification to player
|
|
102
103
|
*/
|
|
103
104
|
private _notifyBuffering;
|
|
105
|
+
private _notifyLoadStart;
|
|
106
|
+
/**
|
|
107
|
+
* Лоадер для случая, когда play запрошен до завершения подготовки видео:
|
|
108
|
+
* syncPlayback при этом умирает на раннем выходе по активному videoState-переходу и не вызывает play().
|
|
109
|
+
* Смотрим только переходы подготовки (MANIFEST_READY/READY): переход PAUSED→PLAYING создаётся
|
|
110
|
+
* syncPlayback позже (debounce(0)), поэтому обычный resume сюда не попадает.
|
|
111
|
+
*/
|
|
112
|
+
private _syncBufferingWithDesiredPlayback;
|
|
104
113
|
/**
|
|
105
114
|
* initialize video tag, add necessary event listeners
|
|
106
115
|
* @private
|
|
@@ -4,7 +4,6 @@ import { ProviderState } from "./lib/types";
|
|
|
4
4
|
import type { Representation, Stream } from "../utils/parsers/types";
|
|
5
5
|
import type { IProvider, IProviderAllocationResolution, IProviderParams } from "../types";
|
|
6
6
|
import type { IObservableVideo } from "../utils/HTMLVideoElement/observable";
|
|
7
|
-
import { TrackHistory } from "../../utils/autoSelectTrack";
|
|
8
7
|
import type { IStateMachine } from "../../utils/StateMachine/types";
|
|
9
8
|
import type { ExactVideoQuality, ISubscription, ITracer, Milliseconds, Nullable } from "@vkontakte/videoplayer-shared";
|
|
10
9
|
import { Player } from "./lib/player";
|
|
@@ -47,8 +46,6 @@ export default abstract class BaseDashProvider implements IProvider {
|
|
|
47
46
|
}>;
|
|
48
47
|
protected videoStreamsMap: Map<Stream, IVideoTrack[]>;
|
|
49
48
|
protected audioStreamsMap: Map<Stream, IAudioTrack[]>;
|
|
50
|
-
protected videoTrackSwitchHistory: TrackHistory<IVideoTrack>;
|
|
51
|
-
protected audioTrackSwitchHistory: TrackHistory<IAudioTrack>;
|
|
52
49
|
constructor(params: IParams);
|
|
53
50
|
protected abstract seek(position: Milliseconds, forcePrecise: boolean): void;
|
|
54
51
|
protected getProviderSubscriptionInfo(): IProviderSubscriptionInfo;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ITuningConfig } from "../../../utils/tuningConfig";
|
|
2
|
-
import type { IError, IRange, ISubject, IValueSubject, Milliseconds } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { IError, IRange, ISubject, ITracer, IValueSubject, Milliseconds } from "@vkontakte/videoplayer-shared";
|
|
3
3
|
import { abortable } from "@vkontakte/videoplayer-shared";
|
|
4
4
|
import type { Fetcher } from "./fetcher";
|
|
5
5
|
import type { CommonInit, Manifest, Representation, Segment, Stream, StreamKind } from "../../utils/parsers/types";
|
|
@@ -11,6 +11,7 @@ export interface Dependencies {
|
|
|
11
11
|
isActiveLowLatency: () => boolean;
|
|
12
12
|
compatibilityMode?: boolean;
|
|
13
13
|
manifest: Manifest | null;
|
|
14
|
+
tracer: ITracer;
|
|
14
15
|
}
|
|
15
16
|
export interface Gap extends IRange<Milliseconds> {
|
|
16
17
|
representation: Representation["id"];
|
|
@@ -67,6 +68,7 @@ export declare class BufferManager {
|
|
|
67
68
|
private baseUrlsIndex;
|
|
68
69
|
private compatibilityMode;
|
|
69
70
|
private preloadOnly;
|
|
71
|
+
private tracer;
|
|
70
72
|
private isLive;
|
|
71
73
|
private liveUpdateSegmentIndex;
|
|
72
74
|
private liveInitialAdditionalOffset;
|
|
@@ -75,7 +77,8 @@ export declare class BufferManager {
|
|
|
75
77
|
private lastDataObtainedTimestampMs;
|
|
76
78
|
private loadByteRangeSegmentsTimeoutId;
|
|
77
79
|
private preDownloadedFirstSegment;
|
|
78
|
-
|
|
80
|
+
private brokenSegmentAppendDetected;
|
|
81
|
+
constructor(kind: StreamKind, mediaSource: MediaSource, representations: Representation[], { fetcher, tuning, getCurrentPosition, isActiveLowLatency, compatibilityMode, manifest, tracer }: Dependencies);
|
|
79
82
|
startWith: ReturnType<typeof abortable<[Representation["id"]]>>;
|
|
80
83
|
switchToWithPreviousAbort(newRepresentationId: Representation["id"], dropBuffer?: boolean): Promise<void | undefined>;
|
|
81
84
|
switchTo: ReturnType<typeof abortable<[Representation["id"], boolean | undefined], void>>;
|
|
@@ -119,6 +122,7 @@ export declare class BufferManager {
|
|
|
119
122
|
*/
|
|
120
123
|
private onSomeByteRangesDataLoaded;
|
|
121
124
|
private onSegmentFullyAppended;
|
|
125
|
+
private detectBrokenSegmentAppend;
|
|
122
126
|
private abortSegment;
|
|
123
127
|
private loadNextInit;
|
|
124
128
|
private loadInit;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { IAudioTrack,
|
|
1
|
+
import type { IAudioTrack, IDashURLSource, IHLSSource, IInternalTextTrack, IVideoTrack, VideoCodec } from "../../player/types";
|
|
2
2
|
import type { IProviderSubscriptionInfo } from "./lib/types";
|
|
3
3
|
import { ProviderState } from "./lib/types";
|
|
4
4
|
import type { Representation, Stream } from "../utils/parsers/types";
|
|
5
5
|
import type { IProvider, IProviderAllocationResolution, IProviderParams } from "../types";
|
|
6
6
|
import type { IObservableVideo } from "../utils/HTMLVideoElement/observable";
|
|
7
|
-
import { TrackHistory } from "../../utils/autoSelectTrack";
|
|
8
7
|
import type { IStateMachine } from "../../utils/StateMachine/types";
|
|
9
8
|
import type { ExactVideoQuality, ISubscription, ITracer, Milliseconds, Nullable } from "@vkontakte/videoplayer-shared";
|
|
10
9
|
import DroppedFramesManager from "../utils/HTMLVideoElement/DroppedFramesManager";
|
|
@@ -47,8 +46,6 @@ export default abstract class BaseDashProvider implements IProvider {
|
|
|
47
46
|
}>;
|
|
48
47
|
protected videoStreamsMap: Map<Stream, IVideoTrack[]>;
|
|
49
48
|
protected audioStreamsMap: Map<Stream, IAudioTrack[]>;
|
|
50
|
-
protected videoTrackSwitchHistory: TrackHistory<IVideoTrack>;
|
|
51
|
-
protected audioTrackSwitchHistory: TrackHistory<IBaseTrack>;
|
|
52
49
|
constructor(params: IParams);
|
|
53
50
|
protected abstract seek(position: Milliseconds, forcePrecise: boolean): void;
|
|
54
51
|
protected abstract getPlayer(): BasePlayer;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { IError, IRange, ISubject, IValueSubject, Milliseconds } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { ITuningConfig } from "../../../../utils/tuningConfig";
|
|
2
3
|
export declare class NativeBufferManager {
|
|
3
4
|
error$: ISubject<IError>;
|
|
4
5
|
updateEnd$: IValueSubject<void>;
|
|
5
6
|
private mediaSource;
|
|
6
7
|
private sourceBuffer;
|
|
7
8
|
private sourceBufferTaskQueue;
|
|
9
|
+
private readonly tuning;
|
|
8
10
|
private subscription;
|
|
9
|
-
constructor(mediaSource: MediaSource);
|
|
11
|
+
constructor(mediaSource: MediaSource, tuning: ITuningConfig);
|
|
10
12
|
init(mime: string, codecs: string): void;
|
|
11
13
|
addInitSegment(initView: BufferSource, signal?: AbortSignal): Promise<boolean>;
|
|
12
14
|
append(segmentView: BufferSource, signal?: AbortSignal): Promise<boolean>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Byte, IError, ISubject, Milliseconds } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { ITuningConfig } from "../../../../utils/tuningConfig";
|
|
2
3
|
declare class SourceBufferTaskQueue {
|
|
3
4
|
bufferFull$: ISubject<Byte>;
|
|
4
5
|
error$: ISubject<IError>;
|
|
@@ -7,7 +8,8 @@ declare class SourceBufferTaskQueue {
|
|
|
7
8
|
private currentTask;
|
|
8
9
|
private destroyed;
|
|
9
10
|
private abortRequested;
|
|
10
|
-
|
|
11
|
+
private readonly tuning;
|
|
12
|
+
constructor(buffer: SourceBuffer, tuning: ITuningConfig);
|
|
11
13
|
append(data: BufferSource, signal?: AbortSignal): Promise<boolean>;
|
|
12
14
|
remove(from: Milliseconds, to: Milliseconds, signal?: AbortSignal): Promise<boolean>;
|
|
13
15
|
abort(init?: BufferSource): Promise<boolean>;
|
|
@@ -52,6 +52,7 @@ export declare abstract class BaseVirtualBufferManager<T extends Segment> implem
|
|
|
52
52
|
protected subscription: Subscription;
|
|
53
53
|
protected readonly getCurrentPosition: () => Milliseconds | undefined;
|
|
54
54
|
protected readonly getCurrentStallDuration: () => Milliseconds | undefined;
|
|
55
|
+
protected brokenSegmentAppendDetected: boolean;
|
|
55
56
|
protected constructor(kind: StreamKind, nativeBufferManager: NativeBufferManager, representations: Representation[], { fetcher, tracer, tuning, getCurrentPosition, getCurrentStallDuration, manifest }: Dependencies);
|
|
56
57
|
protected abstract loadItems(itemsToLoad: IBufferPlaybackQueueItem<T>[], representation: Representation, priority?: Priority): Promise<void>;
|
|
57
58
|
protected abstract selectItemsToLoad(): IBufferPlaybackQueueItem<T>[];
|
|
@@ -96,7 +97,7 @@ export declare abstract class BaseVirtualBufferManager<T extends Segment> implem
|
|
|
96
97
|
*/
|
|
97
98
|
protected sanitizeBufferPlaybackQueue(): boolean;
|
|
98
99
|
protected forceSwitchCondition(oldRepresentation: Representation, newRepresentation: Representation): boolean;
|
|
99
|
-
protected clearBuffer(): Promise<void>;
|
|
100
|
+
protected clearBuffer(signal?: AbortSignal): Promise<void>;
|
|
100
101
|
private resetBuffer;
|
|
101
102
|
protected abortDownload(): void;
|
|
102
103
|
protected abortDownloadingItems(): void;
|
|
@@ -120,6 +121,7 @@ export declare abstract class BaseVirtualBufferManager<T extends Segment> implem
|
|
|
120
121
|
protected parseFeedableSegmentChunk(chunk: DataView): DataView | null;
|
|
121
122
|
protected onItemFullyDownloaded(downloadedItem: IBufferPlaybackQueueItem<T>): void;
|
|
122
123
|
protected onItemFullyAppended(appendedItem: IBufferPlaybackQueueItem<T>): void;
|
|
124
|
+
private detectBrokenSegmentAppend;
|
|
123
125
|
protected removeSegment(nextRemoveItem: IBufferPlaybackQueueItem<T>, signal: AbortSignal): Promise<void>;
|
|
124
126
|
protected onDownloadItem(downloadedItem: IBufferPlaybackQueueItem<T>): void;
|
|
125
127
|
protected pruneVirtualBuffer(currentPosition: Milliseconds): void;
|
|
@@ -63,9 +63,11 @@ export declare abstract class BasePlayer {
|
|
|
63
63
|
liveSeekableDuration$: IValueSubject<Milliseconds>;
|
|
64
64
|
liveAvailabilityStartTime$: IValueSubject<Milliseconds>;
|
|
65
65
|
liveStreamStatus$: IValueSubject<LiveStreamStatus | undefined>;
|
|
66
|
-
|
|
66
|
+
currentVideoBuffer$: IValueSubject<IRange<Seconds>>;
|
|
67
|
+
currentAudioBuffer$: IValueSubject<IRange<Seconds>>;
|
|
67
68
|
bufferLength$: IValueSubject<Milliseconds>;
|
|
68
69
|
nativeBufferLength$: IValueSubject<Milliseconds>;
|
|
70
|
+
nativeAudioBufferLength$: IValueSubject<IRange<Seconds>>;
|
|
69
71
|
liveLatency$: IValueSubject<Milliseconds | undefined>;
|
|
70
72
|
liveLoadBufferLength$: IValueSubject<Milliseconds>;
|
|
71
73
|
livePositionFromPlayer$: IValueSubject<number>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IError } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { IHeuristicDeps } from "../types";
|
|
3
|
+
import type { ISyncHeuristic, HeuristicResult } from "./IHeuristic";
|
|
4
|
+
export declare class SegmentAppendHeuristic implements ISyncHeuristic {
|
|
5
|
+
private deps;
|
|
6
|
+
static readonly heuristicName = "SegmentAppendHeuristic";
|
|
7
|
+
readonly type = "sync";
|
|
8
|
+
constructor(deps: IHeuristicDeps);
|
|
9
|
+
analyze(error: IError): HeuristicResult;
|
|
10
|
+
}
|
|
@@ -14,7 +14,7 @@ export interface IMaydayProviderOutput {
|
|
|
14
14
|
position$: IValueSubject<number>;
|
|
15
15
|
currentVideoTrack$: IValueSubject<IVideoTrack | undefined>;
|
|
16
16
|
totalBufferDuration$: IValueSubject<Milliseconds | undefined>;
|
|
17
|
-
|
|
17
|
+
currentNativeVideoBuffer$: IValueSubject<IRange<Seconds> | undefined>;
|
|
18
18
|
bufferRangeCount$: IValueSubject<number | undefined>;
|
|
19
19
|
availableVideoStreams$: IValueSubject<IVideoStream[]>;
|
|
20
20
|
currentAudioStream$: IValueSubject<IAudioStream | undefined>;
|
|
@@ -81,8 +81,10 @@ export interface IProviderOutput {
|
|
|
81
81
|
autoVideoTrackLimits$: IValueSubject<QualityLimits | undefined>;
|
|
82
82
|
autoVideoTrackLimitingAvailable$: IValueSubject<boolean>;
|
|
83
83
|
canChangePlaybackSpeed$: IValueSubject<boolean | undefined>;
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
currentVideoBuffer$: IValueSubject<IRange<Seconds> | undefined>;
|
|
85
|
+
currentAudioBuffer$: IValueSubject<IRange<Seconds> | undefined>;
|
|
86
|
+
currentNativeVideoBuffer$: IValueSubject<IRange<Seconds> | undefined>;
|
|
87
|
+
currentNativeAudioBuffer$: IValueSubject<IRange<Seconds> | undefined>;
|
|
86
88
|
totalBufferDuration$: IValueSubject<Milliseconds | undefined>;
|
|
87
89
|
bufferRangeCount$: IValueSubject<number | undefined>;
|
|
88
90
|
videoLastDataObtainedTimestamp$: IValueSubject<Milliseconds | undefined>;
|
|
@@ -7,12 +7,14 @@ export declare class AbrManager {
|
|
|
7
7
|
private audioAbrController;
|
|
8
8
|
private subscription;
|
|
9
9
|
private lastVideoTrackSelected$;
|
|
10
|
+
private lastAudioTrackSelected$;
|
|
10
11
|
private context;
|
|
11
12
|
private phaseController;
|
|
12
13
|
private allVideoRules;
|
|
13
14
|
private tracer;
|
|
14
15
|
init(context: IInitAbrManagerContext): void;
|
|
15
16
|
updateContext(updateContext: IUpdatableAbrManagerContext): void;
|
|
17
|
+
private getAudioReserve;
|
|
16
18
|
autoSelectTrack<T extends IVideoTrack | IAudioTrack>(kind: Exclude<StreamKind, StreamKind.TEXT>): T;
|
|
17
19
|
destroy(): void;
|
|
18
20
|
private initVideoElementAbrContext;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IComponentLogger, IRectangle, ITracer, Kbps, Milliseconds, Nullable, QualityLimits } from "@vkontakte/videoplayer-shared";
|
|
2
|
+
import type { IVideoTrack } from "../../../player/types";
|
|
3
|
+
import type { ITuningConfig } from "../../../utils/tuningConfig";
|
|
4
|
+
export interface ISelectTrackByRulesContext {
|
|
5
|
+
videoTracks: IVideoTrack[];
|
|
6
|
+
tuning: ITuningConfig;
|
|
7
|
+
abrLogger: IComponentLogger;
|
|
8
|
+
tracer: ITracer;
|
|
9
|
+
estimatedThroughput: Kbps;
|
|
10
|
+
container?: Nullable<IRectangle>;
|
|
11
|
+
panelSize?: Nullable<IRectangle>;
|
|
12
|
+
limits?: QualityLimits;
|
|
13
|
+
playbackRate?: number;
|
|
14
|
+
forwardBufferHealth?: number;
|
|
15
|
+
forwardBufferDuration?: Milliseconds;
|
|
16
|
+
visible?: boolean;
|
|
17
|
+
currentVideoTrack?: Nullable<IVideoTrack>;
|
|
18
|
+
reserve?: Kbps;
|
|
19
|
+
isLive?: boolean;
|
|
20
|
+
element?: HTMLMediaElement;
|
|
21
|
+
}
|
|
22
|
+
export declare const defaultEmptyArrayErrorMessage = "Assertion \"ABR Tracks is empty array\" failed";
|
|
23
|
+
export declare function selectTrackByRules(context: ISelectTrackByRulesContext): IVideoTrack;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Milliseconds, Nullable } from "@vkontakte/videoplayer-shared";
|
|
1
|
+
import type { Kbps, Milliseconds, Nullable } from "@vkontakte/videoplayer-shared";
|
|
2
2
|
import type { IAudioTrack, IBaseTrack, IVideoTrack } from "../../../player/types";
|
|
3
|
+
import type { Representation, Segment } from "../parsers/types";
|
|
3
4
|
export declare const bufferToPlaybackMs: (contentMs: Milliseconds | undefined, playbackRate: number) => Milliseconds;
|
|
4
5
|
export declare enum CompareTrack {
|
|
5
6
|
Descending = -1,
|
|
@@ -13,3 +14,5 @@ export declare const isLowerTrack: <T extends IBaseTrack>(track1: T, track2: T)
|
|
|
13
14
|
export declare const logBase: (base: number, x: number) => number;
|
|
14
15
|
export declare const bitrateFactorFromBufferLevel: (forwardBufferHealth: number, emptyFactor: number, fullFactor: number) => number;
|
|
15
16
|
export declare const getMinPossibleAudioForVideo: (videoTrack: Nullable<IVideoTrack>, sortedVideoTracksAsc: IVideoTrack[], sortedAudioTracksAsc: IAudioTrack[], minVideoAudioRatio: number) => IAudioTrack | undefined;
|
|
17
|
+
export declare const getForwardBitrateKbps: (forwardBufferRepresentations: Nullable<Map<Representation["id"], Segment[]>>, videoTrack: Nullable<IVideoTrack>) => Kbps | undefined;
|
|
18
|
+
export declare const isVideoTail: (remainingDurationMs: Nullable<Milliseconds>, mpdSegmentDurationMs: Nullable<Milliseconds>) => boolean;
|
|
@@ -17,7 +17,7 @@ export interface IObservableVideo {
|
|
|
17
17
|
loadedMetadata$: IObservable<undefined>;
|
|
18
18
|
loadedData$: IObservable<undefined>;
|
|
19
19
|
isBuffering$: IObservable<boolean>;
|
|
20
|
-
|
|
20
|
+
currentVideoBuffer$: IObservable<IRange<Seconds>>;
|
|
21
21
|
totalBufferDuration$: IObservable<Milliseconds>;
|
|
22
22
|
bufferRangeCount$: IObservable<number>;
|
|
23
23
|
volumeState$: IObservable<IVolumeState>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ITuningConfig } from "../../../utils/tuningConfig";
|
|
2
|
-
type DisposeConstraints = Pick<ITuningConfig, "reuseOwnVideoElement">;
|
|
2
|
+
type DisposeConstraints = Pick<ITuningConfig, "reuseOwnVideoElement" | "clearAudioElementOnDispose">;
|
|
3
3
|
export declare const allocate: (container: HTMLElement, { audioVideoSyncRate, disableYandexPiP, reuseOwnVideoElement }: ITuningConfig) => HTMLVideoElement;
|
|
4
4
|
export declare const initializeAudio: (element: HTMLAudioElement) => HTMLAudioElement;
|
|
5
5
|
export declare const dispose: (element: HTMLMediaElement, constraints: DisposeConstraints) => void;
|
|
@@ -14,6 +14,8 @@ declare class ThroughputEstimator {
|
|
|
14
14
|
trackXHR(xhr: XMLHttpRequest): void;
|
|
15
15
|
trackStream(stream: ReadableStream, isLowLatency?: boolean): void;
|
|
16
16
|
addRawSpeed(size: Byte, time: Milliseconds, concurrency?: number, isLowLatency?: boolean): void;
|
|
17
|
+
private countActiveDownloads;
|
|
18
|
+
private isFastSample;
|
|
17
19
|
/**
|
|
18
20
|
* Стоит использовать только когда другие методы совсем не получается
|
|
19
21
|
*/
|
|
@@ -56,8 +56,19 @@ export type ITuningConfig = {
|
|
|
56
56
|
* - fromCache — попадание в Cache API (doFetch дёргает onCacheHit);
|
|
57
57
|
* - TTFB — headersReceivedAt - requestStartedAt < max(rtt*0.5, 2мс) (кэш ~0, реал ≥ RTT).
|
|
58
58
|
* 2. sanityCheck отключает порог time ≤ cacheThresholdSize → реальные быстрые сэмплы проходят.
|
|
59
|
+
* 3. Прошедший быстрый сэмпл применяется только если поднимает оценку: по объекту, который
|
|
60
|
+
* укладывается в одно окно, наблюдаемое время — латентность, а не size/полоса, поэтому
|
|
61
|
+
* он задаёт нижнюю границу и не может доказать, что сеть стала медленнее.
|
|
62
|
+
* 4. Финальный замер стрима делит полосу на параллельные загрузки, как промежуточные:
|
|
63
|
+
* мелкий сегмент качается параллельно с аудио и другого замера не получает.
|
|
64
|
+
* Параллельной считается загрузка, отдававшая байты внутри окна замера: открытая,
|
|
65
|
+
* но молчащая (подвисла либо уже выкачала своё и ждёт done) полосу не занимает.
|
|
59
66
|
* Честный кэш (мгновенная отдача → rate > 1 Гбит/с) по-прежнему режется проверкой rate выше.
|
|
60
67
|
*
|
|
68
|
+
* Пункты 3 и 4 добавлены после эксперимента 37621: без них включённые быстрые сэмплы
|
|
69
|
+
* систематически занижали оценку, ABR держал низкое качество и сегменты оставались
|
|
70
|
+
* мелкими — петля с положительной обратной связью, вердикт NO-GO.
|
|
71
|
+
*
|
|
61
72
|
* По умолчанию false — поведение не меняется.
|
|
62
73
|
*/
|
|
63
74
|
measureFastSamples: boolean;
|
|
@@ -179,7 +190,8 @@ export type ITuningConfig = {
|
|
|
179
190
|
useNewRepresentationSwitch: boolean;
|
|
180
191
|
useDelayedRepresentationSwitch: boolean;
|
|
181
192
|
useSmartRepresentationSwitch: boolean;
|
|
182
|
-
|
|
193
|
+
brokenSegmentAppendDetection: boolean;
|
|
194
|
+
brokenSegmentAppendTolerance: Milliseconds;
|
|
183
195
|
useFetchPriorityHints: boolean;
|
|
184
196
|
enableBaseUrlSupport: boolean;
|
|
185
197
|
maxSegmentRetryCount: number;
|
|
@@ -200,11 +212,9 @@ export type ITuningConfig = {
|
|
|
200
212
|
tickMaintainInterval: Milliseconds;
|
|
201
213
|
minSafeBufferToPlay: Milliseconds;
|
|
202
214
|
useBufferHoldingOnlyOnStall: boolean;
|
|
203
|
-
useNewAbr: boolean;
|
|
204
215
|
useAbrPhases: boolean;
|
|
205
216
|
abrVideoRules: VideoRuleName[];
|
|
206
217
|
abrAudioRules: AudioRuleName[];
|
|
207
|
-
useDynamicBirtateRule: boolean;
|
|
208
218
|
useFailoverHostsOnAllProviderCrash: boolean;
|
|
209
219
|
saveData3gQualityLimit: ExactVideoQuality;
|
|
210
220
|
saveData2gQualityLimit: ExactVideoQuality;
|
|
@@ -241,6 +251,20 @@ export type ITuningConfig = {
|
|
|
241
251
|
maxQualityForFirstSegmentPreload: ExactVideoQuality;
|
|
242
252
|
/** Включает отправку телеметрии трейсера (resume) при превышении stall watchdog */
|
|
243
253
|
tracerResumeOnUnexpectedStall: boolean;
|
|
254
|
+
/**
|
|
255
|
+
* При отмене signal текущей задачи sourceBufferTaskQueue (например, через
|
|
256
|
+
* `maintainAbortController.abort()` в `prepareSeek`) прерывать зависшую MSE-операцию
|
|
257
|
+
* через `buffer.abort()`. Без этого `completeTask` не вызовется при залипшем
|
|
258
|
+
* SourceBuffer и промис `append`/`remove` зависнет навечно — `prepareSeek`
|
|
259
|
+
* застрянет на `await maintainMutexPromise` (V3 deadlock), stall растёт до
|
|
260
|
+
* `crashOnStallTimeout=25с`.
|
|
261
|
+
*
|
|
262
|
+
* По умолчанию false (opt-in). Дешёвый фикс, но поведенческое изменение:
|
|
263
|
+
* единственный побочный эффект — лишний `buffer.abort()` при штатной отмене
|
|
264
|
+
* maintain (например, при обычном seek), но MSE `abort()` без активной операции
|
|
265
|
+
* — no-op по спеке. Включать поэтапно, начиная с процента.
|
|
266
|
+
*/
|
|
267
|
+
abortSourceBufferOnSignal: boolean;
|
|
244
268
|
};
|
|
245
269
|
dashCmafLive: {
|
|
246
270
|
externalStopControl: boolean;
|
|
@@ -338,7 +362,8 @@ export type ITuningConfig = {
|
|
|
338
362
|
alwaysAbortPreviousSwitch: boolean;
|
|
339
363
|
useDashProviderVirtual: boolean;
|
|
340
364
|
useDashProviderVirtualMobile: boolean;
|
|
341
|
-
|
|
365
|
+
useDashLiveProviderVirtual: boolean;
|
|
366
|
+
useDashLiveProviderVirtualMobile: boolean;
|
|
342
367
|
useSafariEndlessRequestBugfix: boolean;
|
|
343
368
|
/**
|
|
344
369
|
* Ручка для фикса сброса playbackRate при перемотке live-трансляции на Safari.
|
|
@@ -438,6 +463,11 @@ export type ITuningConfig = {
|
|
|
438
463
|
/** включен режим проигрывания только аудио (без видео) */
|
|
439
464
|
audioOnly: boolean;
|
|
440
465
|
/**
|
|
466
|
+
* В audio-режиме при dispose провайдера очищает внешний <audio> (снятие src + load())
|
|
467
|
+
* вместо destroy(), который удаляет элемент из DOM.
|
|
468
|
+
*/
|
|
469
|
+
clearAudioElementOnDispose: boolean;
|
|
470
|
+
/**
|
|
441
471
|
* Переводить провайдер в READY по loadedmetadata вместо canplay.
|
|
442
472
|
* canplay означает, что видео уже может играться, что избыточно для READY —
|
|
443
473
|
* достаточно получить манифест (loadedmetadata).
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { ITuningConfig } from "./tuningConfig";
|
|
2
|
-
import type { Kbps, Milliseconds, IRectangle, QualityLimits, IComponentLogger } from "@vkontakte/videoplayer-shared";
|
|
3
|
-
import { type ExactVideoQuality } from "@vkontakte/videoplayer-shared";
|
|
4
|
-
import type { IAudioTrack, IBaseTrack, IVideoTrack } from "../player/types";
|
|
5
|
-
interface IConstraints<T extends IBaseTrack> {
|
|
6
|
-
container?: IRectangle;
|
|
7
|
-
estimatedThroughput?: Kbps;
|
|
8
|
-
tuning: ITuningConfig["autoTrackSelection"];
|
|
9
|
-
limits?: QualityLimits;
|
|
10
|
-
reserve?: Kbps;
|
|
11
|
-
playbackRate?: number;
|
|
12
|
-
forwardBufferHealth?: number;
|
|
13
|
-
current?: T;
|
|
14
|
-
visible?: boolean;
|
|
15
|
-
history?: TrackHistory<T>;
|
|
16
|
-
droppedVideoMaxQualityLimit?: ExactVideoQuality;
|
|
17
|
-
stallsVideoMaxQualityLimit?: ExactVideoQuality;
|
|
18
|
-
stallsPredictedThroughput?: Kbps;
|
|
19
|
-
abrLogger: IComponentLogger;
|
|
20
|
-
panelSize?: IRectangle;
|
|
21
|
-
}
|
|
22
|
-
export declare class TrackHistory<T extends IBaseTrack> {
|
|
23
|
-
last: T | undefined;
|
|
24
|
-
history: Record<IBaseTrack["id"], Milliseconds>;
|
|
25
|
-
recordSelection(track: T): void;
|
|
26
|
-
recordSwitch(track: T | undefined): void;
|
|
27
|
-
clear(): void;
|
|
28
|
-
}
|
|
29
|
-
export declare const defaultEmptyArrayErrorMessage = "Assertion \"ABR Tracks is empty array\" failed";
|
|
30
|
-
export declare const getMinPossibleAudioForVideoOld: (videoTrack: IVideoTrack, videoTracks: IVideoTrack[], audioTracks: IAudioTrack[], minVideoAudioRatio: number) => IAudioTrack | undefined;
|
|
31
|
-
export declare const getMinPossibleAudioForVideoNew: (videoTrack: IVideoTrack, videoTracks: IVideoTrack[], audioTracks: IAudioTrack[], minVideoAudioRatio: number) => IAudioTrack | undefined;
|
|
32
|
-
export declare const autoSelectVideoTrackNew: (videoTracks: IVideoTrack[], { container, estimatedThroughput, tuning, limits, reserve, forwardBufferHealth, playbackRate, current, history, visible, droppedVideoMaxQualityLimit, stallsVideoMaxQualityLimit, stallsPredictedThroughput, abrLogger, panelSize }: IConstraints<IVideoTrack>) => IVideoTrack;
|
|
33
|
-
export declare const autoSelectVideoTrackOld: (videoTracks: IVideoTrack[], { container, estimatedThroughput, tuning, limits, reserve, forwardBufferHealth, playbackRate, current, history, visible, droppedVideoMaxQualityLimit, stallsVideoMaxQualityLimit, stallsPredictedThroughput, abrLogger, panelSize }: IConstraints<IVideoTrack>) => IVideoTrack;
|
|
34
|
-
export declare const autoSelectAudioTrackForVideoOld: (selectedVideoTrack: IVideoTrack, videoTracks: IVideoTrack[], audioTracks: IAudioTrack[], { estimatedThroughput, tuning, playbackRate, forwardBufferHealth, history, abrLogger, stallsPredictedThroughput }: IConstraints<IAudioTrack>) => IAudioTrack | undefined;
|
|
35
|
-
export declare const autoSelectAudioTrackForVideoNew: (selectedVideoTrack: IVideoTrack, videoTracks: IVideoTrack[], audioTracks: IAudioTrack[], { estimatedThroughput, tuning, playbackRate, forwardBufferHealth, history, abrLogger, stallsPredictedThroughput }: IConstraints<IAudioTrack>) => IAudioTrack | undefined;
|
|
36
|
-
export {};
|