@vkontakte/videoplayer-core 2.0.171 → 2.0.172-beta.1

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 (64) hide show
  1. package/es2015.cjs +19 -241
  2. package/es2015.esm.js +19 -241
  3. package/esnext.cjs +19 -241
  4. package/esnext.esm.js +19 -241
  5. package/evergreen.esm.js +19 -241
  6. package/package.json +2 -2
  7. package/types/player/Player.d.ts +5 -1
  8. package/types/player/types.d.ts +25 -5
  9. package/types/providers/DashLiveProvider/utils/LiveDashPlayer.d.ts +3 -0
  10. package/types/providers/DashProvider/baseDashProvider.d.ts +3 -9
  11. package/types/providers/DashProvider/lib/buffer.d.ts +6 -2
  12. package/types/providers/DashProvider/lib/player.d.ts +1 -0
  13. package/types/providers/DashProvider/lib/sourceBufferTaskQueue.d.ts +1 -2
  14. package/types/providers/DashProvider/lib/types.d.ts +2 -2
  15. package/types/providers/DashProviderVirtual/baseDashProvider.d.ts +4 -9
  16. package/types/providers/DashProviderVirtual/lib/buffer/nativeBufferManager.d.ts +4 -2
  17. package/types/providers/DashProviderVirtual/lib/buffer/sourceBufferTaskQueue.d.ts +3 -2
  18. package/types/providers/DashProviderVirtual/lib/buffer/virtualBuffer/baseVirtualBufferManager.versionA.d.ts +3 -1
  19. package/types/providers/DashProviderVirtual/lib/player/basePlayer.d.ts +3 -1
  20. package/types/providers/DashProviderVirtual/lib/types.d.ts +2 -2
  21. package/types/providers/ProviderContainer/Mayday/GraceTimeout.d.ts +17 -0
  22. package/types/providers/ProviderContainer/Mayday/heuristics/SegmentAppendHeuristic.d.ts +10 -0
  23. package/types/providers/ProviderContainer/Mayday/heuristics/StartupHangupHeuristic.d.ts +46 -0
  24. package/types/providers/ProviderContainer/Mayday/heuristics/TvFetcherErrorHeuristic.d.ts +10 -0
  25. package/types/providers/ProviderContainer/Mayday/index.d.ts +2 -1
  26. package/types/providers/ProviderContainer/Mayday/types.d.ts +2 -1
  27. package/types/providers/ProviderContainer/index.d.ts +0 -1
  28. package/types/providers/ProviderContainer/utils/formatsSupport.d.ts +0 -1
  29. package/types/providers/ProviderContainer/utils/playbackHangup.d.ts +6 -2
  30. package/types/providers/types.d.ts +4 -2
  31. package/types/providers/utils/Abr/abrController.d.ts +4 -1
  32. package/types/providers/utils/Abr/abrManager.d.ts +3 -0
  33. package/types/providers/utils/Abr/controllers/stallsController.d.ts +10 -3
  34. package/types/providers/utils/Abr/rules/audio/audioThroughputRule.d.ts +2 -2
  35. package/types/providers/utils/Abr/rules/audio/minAudioForVideoRule.d.ts +2 -2
  36. package/types/providers/utils/Abr/rules/baseRule.d.ts +2 -2
  37. package/types/providers/utils/Abr/rules/video/abandonRequestRule.d.ts +2 -2
  38. package/types/providers/utils/Abr/rules/video/bolaRule.d.ts +2 -2
  39. package/types/providers/utils/Abr/rules/video/bufferRule.d.ts +2 -2
  40. package/types/providers/utils/Abr/rules/video/fitsContainerRule.d.ts +2 -2
  41. package/types/providers/utils/Abr/rules/video/insufficientBufferRule.d.ts +2 -2
  42. package/types/providers/utils/Abr/rules/video/lowerLimitRule.d.ts +2 -2
  43. package/types/providers/utils/Abr/rules/video/stallsRule.d.ts +6 -2
  44. package/types/providers/utils/Abr/rules/video/throughputRule.d.ts +2 -2
  45. package/types/providers/utils/Abr/rules/video/tvDisabledVideoTrackRule.d.ts +2 -2
  46. package/types/providers/utils/Abr/rules/video/upperLimitRule.d.ts +2 -2
  47. package/types/providers/utils/Abr/selectTrackByRules.d.ts +23 -0
  48. package/types/providers/utils/Abr/types.d.ts +8 -10
  49. package/types/providers/utils/Abr/utils.d.ts +3 -2
  50. package/types/providers/utils/HTMLVideoElement/ElementSizeManager.d.ts +2 -2
  51. package/types/providers/utils/HTMLVideoElement/destroy.d.ts +1 -1
  52. package/types/providers/utils/HTMLVideoElement/observable.d.ts +2 -2
  53. package/types/providers/utils/HTMLVideoElement/pool.d.ts +2 -3
  54. package/types/providers/utils/restorePlaybackRateInSafari.d.ts +2 -2
  55. package/types/utils/ThroughputEstimator.d.ts +2 -0
  56. package/types/utils/buffer/isBrokenSegmentAppend.d.ts +3 -0
  57. package/types/utils/buffer/timeRangesToIntervals.d.ts +3 -0
  58. package/types/utils/timers.d.ts +2 -0
  59. package/types/utils/tuningConfig.d.ts +58 -37
  60. package/types/providers/ProviderContainer/Mayday/heuristics/HangupHeuristic.d.ts +0 -23
  61. package/types/providers/utils/Abr/rules/video/downloadTimeRule.d.ts +0 -15
  62. package/types/providers/utils/Abr/rules/video/failedVideoTrackRule.d.ts +0 -14
  63. package/types/utils/autoSelectTrack.d.ts +0 -37
  64. package/types/utils/buffer/dynamicBufferTarget.d.ts +0 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vkontakte/videoplayer-core",
3
- "version": "2.0.171",
3
+ "version": "2.0.172-beta.1",
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.100"
45
+ "@vkontakte/videoplayer-shared": "1.0.101-beta.3"
46
46
  }
47
47
  }
@@ -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 {
@@ -30,6 +30,7 @@ export default class Player implements IPlayer {
30
30
  experimental: PlayerExperimentalImpl;
31
31
  private devNullLog;
32
32
  private collectDecodingInfoDestroyCb;
33
+ private hasReleasedTimers;
33
34
  constructor(tuning?: IOptionalTuningConfig, tracer?: ITracer, playerOptions?: IPlayerOptions);
34
35
  private readonly doInit;
35
36
  /**
@@ -77,7 +78,10 @@ export default class Player implements IPlayer {
77
78
  getExactTime(): Seconds;
78
79
  getExactLiveTime(): Seconds;
79
80
  getAllLogs(): ILogEntry[];
81
+ getDebugData(): DebugData;
82
+ private buildDebugData;
80
83
  private setIntrinsicVideoSize;
84
+ private initDebugDataSubscriptions;
81
85
  private initDesiredStateSubscriptions;
82
86
  private initProviderContainerSubscription;
83
87
  private initChromecastSubscription;
@@ -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,33 @@ export interface PlayerInfoValues {
311
311
  */
312
312
  currentPlaybackRate$: PlaybackRate;
313
313
  /**
314
- * Текущий буффер плеера (тот; который содержит текущую позицию воспроизведения)
314
+ * Текущий видео буффер-плеера (тот; который содержит текущую позицию воспроизведения)
315
315
  *
316
316
  * default value: `undefined`
317
317
  */
318
- currentBuffer$: StartEnd<Seconds> | undefined;
318
+ currentVideoBuffer$: StartEnd<Seconds> | undefined;
319
319
  /**
320
- * Текущий браузерный буффер (тот; который содержит текущую позицию воспроизведения)
320
+ * Текущий аудио-буффер плеера (тот; который содержит текущую позицию воспроизведения)
321
321
  *
322
322
  * default value: `undefined`
323
323
  */
324
- currentNativeBuffer$: StartEnd<Seconds> | undefined;
324
+ currentAudioBuffer$: StartEnd<Seconds> | undefined;
325
+ /**
326
+ * Текущий браузерный видео-буффер (тот; который содержит текущую позицию воспроизведения)
327
+ *
328
+ * default value: `undefined`
329
+ */
330
+ currentNativeVideoBuffer$: StartEnd<Seconds> | undefined;
331
+ /**
332
+ * Текущий браузерный аудио-буффер (тот; который содержит текущую позицию воспроизведения)
333
+ *
334
+ * Семантика: для большинства провайдеров источник один — HTMLMediaElement, у которого `buffered` общий на audio- и video-данные
335
+ * (по спеке HTML audio data = mix всех enabled audio tracks, video data = currently selected video track — https://html.spec.whatwg.org/multipage/media.html#media-resource).
336
+ * В таких случаях значение совпадает с `currentNativeVideoBuffer$`.
337
+ *
338
+ * default value: `undefined`
339
+ */
340
+ currentNativeAudioBuffer$: StartEnd<Seconds> | undefined;
325
341
  /** Суммарная длительность всех буферизованных диапазонов в миллисекундах */
326
342
  totalBufferDuration$: Milliseconds | undefined;
327
343
  /**
@@ -456,6 +472,10 @@ export interface PlayerInfoValues {
456
472
  * Длина аудио сегмента
457
473
  */
458
474
  currentAudioSegmentLength$: number;
475
+ /**
476
+ * Отладочная информация
477
+ */
478
+ debugData$: DebugData;
459
479
  }
460
480
  export type IPlayerInfo = { [K in keyof PlayerInfoValues]: IValueObservable<PlayerInfoValues[K]> };
461
481
  export type PlayerInfoImpl = { [K in keyof PlayerInfoValues]: ValueSubject<PlayerInfoValues[K]> };
@@ -49,6 +49,9 @@ export default class LiveDashPlayer {
49
49
  private bufferStates;
50
50
  private downloadRate?;
51
51
  private sourceJitter;
52
+ private srcToken;
53
+ private videoListeners;
54
+ private objectUrl;
52
55
  private chunkRateEstimator;
53
56
  private manifestUrl;
54
57
  private urlResolver;
@@ -3,8 +3,7 @@ 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
- import type { IObservableVideo } from "../utils/HTMLVideoElement/observable";
7
- import { TrackHistory } from "../../utils/autoSelectTrack";
6
+ import type { IObservableMediaElement } from "../utils/HTMLVideoElement/observable";
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";
@@ -16,7 +15,6 @@ import { ElementSizeManager } from "../utils/HTMLVideoElement/ElementSizeManager
16
15
  type IParams = IProviderParams<IDashURLSource> & {
17
16
  sourceHls?: IHLSSource;
18
17
  forceVideoCodec?: VideoCodec;
19
- failedVideoTrack?: Nullable<IVideoTrack>;
20
18
  isOnDemand?: boolean;
21
19
  dashMaxTvVideoQuality?: Nullable<ExactVideoQuality>;
22
20
  };
@@ -25,7 +23,7 @@ export default abstract class BaseDashProvider implements IProvider {
25
23
  protected volumeSubscription: ISubscription;
26
24
  protected videoState: IStateMachine<ProviderState>;
27
25
  protected readonly allocation: IProviderAllocationResolution;
28
- protected observableVideo: IObservableVideo | null;
26
+ protected observableVideo: IObservableMediaElement | null;
29
27
  protected player: Player;
30
28
  protected params: IParams;
31
29
  protected tracer: ITracer;
@@ -34,7 +32,6 @@ export default abstract class BaseDashProvider implements IProvider {
34
32
  protected stallsManager: StallsManager;
35
33
  protected elementSizeManager: ElementSizeManager;
36
34
  protected abrManager: AbrManager;
37
- protected failedVideoTrack: Nullable<IVideoTrack>;
38
35
  protected videoTracksMap: Map<IVideoTrack, {
39
36
  stream: Stream;
40
37
  representation: Representation;
@@ -49,16 +46,13 @@ export default abstract class BaseDashProvider implements IProvider {
49
46
  }>;
50
47
  protected videoStreamsMap: Map<Stream, IVideoTrack[]>;
51
48
  protected audioStreamsMap: Map<Stream, IAudioTrack[]>;
52
- protected videoTrackSwitchHistory: TrackHistory<IVideoTrack>;
53
- protected audioTrackSwitchHistory: TrackHistory<IAudioTrack>;
54
49
  constructor(params: IParams);
55
50
  protected abstract seek(position: Milliseconds, forcePrecise: boolean): void;
56
51
  protected getProviderSubscriptionInfo(): IProviderSubscriptionInfo;
57
52
  protected subscribe(): void;
58
53
  private syncBufferTarget;
59
- private resolveAudioBufferTargetMs;
60
54
  private resolveBufferTargetMs;
61
- private getCurrentVideoBitrateKbps;
55
+ private resolveAudioBufferTargetMs;
62
56
  protected selectVideoAudioRepresentations(): [Representation, Representation | undefined] | undefined;
63
57
  protected prepare(manifestOffset?: number): void;
64
58
  protected syncPlayback: () => void;
@@ -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
- constructor(kind: StreamKind, mediaSource: MediaSource, representations: Representation[], { fetcher, tuning, getCurrentPosition, isActiveLowLatency, compatibilityMode, manifest }: Dependencies);
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;
@@ -83,6 +83,7 @@ export declare class Player {
83
83
  private gapWatchdogActive;
84
84
  private gapWatchdogSubscription;
85
85
  private stallWatchdogSubscription;
86
+ private stallTracer;
86
87
  private livePauseWatchdogSubscription;
87
88
  private liveWasInterrupted;
88
89
  private isOnDemand;
@@ -7,8 +7,7 @@ declare class SourceBufferTaskQueue {
7
7
  private currentTask;
8
8
  private destroyed;
9
9
  private abortRequested;
10
- private isAbortFixEnabled;
11
- constructor(buffer: SourceBuffer, isAbortFixEnabled?: boolean);
10
+ constructor(buffer: SourceBuffer);
12
11
  append(data: BufferSource, signal?: AbortSignal): Promise<boolean>;
13
12
  remove(from: Milliseconds, to: Milliseconds, signal?: AbortSignal): Promise<boolean>;
14
13
  abort(init?: BufferSource): Promise<boolean>;
@@ -1,6 +1,6 @@
1
1
  import type { IObservable, ISubject, IValueSubject } from "@vkontakte/videoplayer-shared";
2
2
  import type { IDesiredState, IProviderOutput, IProviderParams } from "../../types";
3
- import type { IObservableVideo } from "../../utils/HTMLVideoElement/observable";
3
+ import type { IObservableMediaElement } from "../../utils/HTMLVideoElement/observable";
4
4
  import type { IDashURLSource } from "../../../player/types";
5
5
  export declare enum LiveStatus {
6
6
  ActiveLowLatency = "active_low_latency",
@@ -16,7 +16,7 @@ export declare enum LiveStreamStatus {
16
16
  export interface IProviderSubscriptionInfo {
17
17
  output: IProviderOutput;
18
18
  desiredState: IDesiredState;
19
- observableVideo: IObservableVideo;
19
+ observableVideo: IObservableMediaElement;
20
20
  genericErrorListener: (error: Error | unknown) => void;
21
21
  connect: <Value>(from: IObservable<Value>, to: ISubject<Value> | IValueSubject<Value> | ((v: Value) => void)) => void;
22
22
  }
@@ -1,10 +1,9 @@
1
- import type { IAudioTrack, IBaseTrack, IDashURLSource, IHLSSource, IInternalTextTrack, IVideoTrack, VideoCodec } from "../../player/types";
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
- import type { IObservableVideo } from "../utils/HTMLVideoElement/observable";
7
- import { TrackHistory } from "../../utils/autoSelectTrack";
6
+ import type { IObservableMediaElement } from "../utils/HTMLVideoElement/observable";
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";
@@ -16,7 +15,6 @@ import { AbrManager } from "../utils/Abr/abrManager";
16
15
  type IParams = IProviderParams<IDashURLSource> & {
17
16
  sourceHls?: IHLSSource;
18
17
  forceVideoCodec?: VideoCodec;
19
- failedVideoTrack?: Nullable<IVideoTrack>;
20
18
  isOnDemand?: boolean;
21
19
  dashMaxTvVideoQuality?: Nullable<ExactVideoQuality>;
22
20
  };
@@ -25,7 +23,7 @@ export default abstract class BaseDashProvider implements IProvider {
25
23
  protected volumeSubscription: ISubscription;
26
24
  protected videoState: IStateMachine<ProviderState>;
27
25
  protected readonly allocation: IProviderAllocationResolution;
28
- protected observableVideo: IObservableVideo | null;
26
+ protected observableVideo: IObservableMediaElement | null;
29
27
  protected player: BasePlayer;
30
28
  protected params: IParams;
31
29
  protected tracer: ITracer;
@@ -48,17 +46,14 @@ export default abstract class BaseDashProvider implements IProvider {
48
46
  }>;
49
47
  protected videoStreamsMap: Map<Stream, IVideoTrack[]>;
50
48
  protected audioStreamsMap: Map<Stream, IAudioTrack[]>;
51
- protected videoTrackSwitchHistory: TrackHistory<IVideoTrack>;
52
- protected audioTrackSwitchHistory: TrackHistory<IBaseTrack>;
53
49
  constructor(params: IParams);
54
50
  protected abstract seek(position: Milliseconds, forcePrecise: boolean): void;
55
51
  protected abstract getPlayer(): BasePlayer;
56
52
  protected getProviderSubscriptionInfo(): IProviderSubscriptionInfo;
57
53
  protected subscribe(): void;
58
54
  private syncBufferTarget;
59
- private resolveAudioBufferTargetMs;
60
55
  private resolveBufferTargetMs;
61
- private getCurrentVideoBitrateKbps;
56
+ private resolveAudioBufferTargetMs;
62
57
  protected selectVideoAudioRepresentations(): [Representation, Representation | undefined] | undefined;
63
58
  protected prepare(manifestOffset?: number): void;
64
59
  protected syncPlayback: () => void;
@@ -1,13 +1,15 @@
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);
10
- init(mime: string, codecs: string, useAbortMSEFix?: boolean): void;
11
+ constructor(mediaSource: MediaSource, tuning: ITuningConfig);
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>;
13
15
  remove(from: Milliseconds, to: Milliseconds, 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,8 +8,8 @@ declare class SourceBufferTaskQueue {
7
8
  private currentTask;
8
9
  private destroyed;
9
10
  private abortRequested;
10
- private isAbortFixEnabled;
11
- constructor(buffer: SourceBuffer, isAbortFixEnabled?: boolean);
11
+ private readonly tuning;
12
+ constructor(buffer: SourceBuffer, tuning: ITuningConfig);
12
13
  append(data: BufferSource, signal?: AbortSignal): Promise<boolean>;
13
14
  remove(from: Milliseconds, to: Milliseconds, signal?: AbortSignal): Promise<boolean>;
14
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
- currentBuffer$: IValueSubject<IRange<Seconds>>;
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>;
@@ -1,6 +1,6 @@
1
1
  import type { IObservable, ISubject, IValueSubject } from "@vkontakte/videoplayer-shared";
2
2
  import type { IDesiredState, IProviderOutput, IProviderParams } from "../../types";
3
- import type { IObservableVideo } from "../../utils/HTMLVideoElement/observable";
3
+ import type { IObservableMediaElement } from "../../utils/HTMLVideoElement/observable";
4
4
  import type { IDashURLSource } from "../../../player/types";
5
5
  export declare enum LiveStatus {
6
6
  ActiveLowLatency = "active_low_latency",
@@ -16,7 +16,7 @@ export declare enum LiveStreamStatus {
16
16
  export interface IProviderSubscriptionInfo {
17
17
  output: IProviderOutput;
18
18
  desiredState: IDesiredState;
19
- observableVideo: IObservableVideo;
19
+ observableVideo: IObservableMediaElement;
20
20
  genericErrorListener: (error: Error | unknown) => void;
21
21
  connect: <Value>(from: IObservable<Value>, to: ISubject<Value> | IValueSubject<Value> | ((v: Value) => void)) => void;
22
22
  }
@@ -0,0 +1,17 @@
1
+ import type { Milliseconds } from "@vkontakte/videoplayer-shared";
2
+ /**
3
+ * Декрементный grace-таймаут: каждый вызов `decay()` уменьшает оставшееся время.
4
+ *
5
+ * После создания `current` возвращает начальное значение.
6
+ * Каждый вызов `decay()` умножает `remaining` на `decayFactor`, но не меньше `minTimeout`.
7
+ * Когда `remaining` достигает `minTimeout` — следующий `decay()` возвращает 0 (expire).
8
+ */
9
+ export declare class GraceTimeout {
10
+ private remaining;
11
+ private readonly decayFactor;
12
+ private readonly minTimeout;
13
+ constructor(initialTimeout: Milliseconds, decayFactor: number, minTimeout: Milliseconds);
14
+ get current(): Milliseconds;
15
+ decay(): Milliseconds;
16
+ reset(initialTimeout: Milliseconds): void;
17
+ }
@@ -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
+ }
@@ -0,0 +1,46 @@
1
+ import { Subject } from "@vkontakte/videoplayer-shared";
2
+ import type { IError } from "@vkontakte/videoplayer-shared";
3
+ import type { IHeuristicDeps, IMaydayEvent } from "../types";
4
+ import type { IAsyncHeuristic, HeuristicResult } from "./IHeuristic";
5
+ /**
6
+ * Эвристика зависания перехода stopped-*.
7
+ *
8
+ * В зависимости от видимости вкладки и наличия звука выбирает стратегию
9
+ * и эмитит одну из рекомендаций:
10
+ *
11
+ * Visible-вкладка: grace-таймаут с уменьшением таймаута на поступление данных.
12
+ * — данные поступают → таймер продлевается.
13
+ * — grace истёк без прогресса → emit switch_codec (или switch_provider).
14
+ *
15
+ * Hidden-вкладка (audible): та же grace-модель с таймаутом (таймеры в воркере не тротлятся).
16
+ * — данные поступают → таймер продлевается.
17
+ * — grace истёк без прогресса → emit switch_codec.
18
+ *
19
+ * Hidden-вкладка (muted/deferred): молча ждём возврата на visible, desired state не трогаем.
20
+ * — вкладка стала visible → emit reinit (полный реинит сам восстановит воспроизведение).
21
+ * — переход всё-таки завершился в фоне (видео заиграло) → отмена, reinit не нужен.
22
+ */
23
+ export declare class StartupHangupHeuristic implements IAsyncHeuristic {
24
+ private deps;
25
+ static readonly heuristicName = "StartupHangupHeuristic";
26
+ readonly type = "async";
27
+ readonly recommendation$: Subject<IMaydayEvent>;
28
+ private timerId;
29
+ private subscription;
30
+ private error;
31
+ private grace;
32
+ private hangupStartedAt;
33
+ private dataArrivals;
34
+ private hiddenWaitActive;
35
+ constructor(deps: IHeuristicDeps);
36
+ analyze(error: IError): HeuristicResult;
37
+ private startMonitoring;
38
+ private waitForVisible;
39
+ private restartTimer;
40
+ private recommendSwitch;
41
+ private isTabHidden;
42
+ private logOutcome;
43
+ private cancel;
44
+ reset(): void;
45
+ destroy(): void;
46
+ }
@@ -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 TvFetcherErrorHeuristic implements ISyncHeuristic {
5
+ private _deps;
6
+ static readonly heuristicName = "TvFetcherErrorHeuristic";
7
+ readonly type = "sync";
8
+ constructor(_deps: IHeuristicDeps);
9
+ analyze(error: IError): HeuristicResult;
10
+ }
@@ -3,5 +3,6 @@ export type { IMaydayDeps, IFallbackContext, IRecommendation, RecoveryAction, IM
3
3
  export type { ISyncHeuristic, IAsyncHeuristic, HeuristicResult } from "./heuristics/IHeuristic";
4
4
  export { MediaErrorHeuristic } from "./heuristics/MediaErrorHeuristic";
5
5
  export { FetcherErrorHeuristic } from "./heuristics/FetcherErrorHeuristic";
6
- export { HangupHeuristic } from "./heuristics/HangupHeuristic";
6
+ export { TvFetcherErrorHeuristic } from "./heuristics/TvFetcherErrorHeuristic";
7
+ export { StartupHangupHeuristic } from "./heuristics/StartupHangupHeuristic";
7
8
  export { MaydayStatistics } from "./MaydayStatistics";
@@ -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
- currentNativeBuffer$: IValueSubject<IRange<Seconds> | undefined>;
17
+ currentNativeVideoBuffer$: IValueSubject<IRange<Seconds> | undefined>;
18
18
  bufferRangeCount$: IValueSubject<number | undefined>;
19
19
  availableVideoStreams$: IValueSubject<IVideoStream[]>;
20
20
  currentAudioStream$: IValueSubject<IAudioStream | undefined>;
@@ -54,6 +54,7 @@ export interface IHeuristicDeps {
54
54
  getVisibilityState: () => DocumentVisibilityState | undefined;
55
55
  getReadyState: () => number | undefined;
56
56
  getVideoPaused: () => boolean | undefined;
57
+ getIsMuted: () => boolean;
57
58
  currentNativeBuffer$: IValueSubject<IRange<Seconds> | undefined>;
58
59
  videoLastDataObtainedTimestamp$: IValueSubject<Milliseconds | undefined>;
59
60
  desiredPlaybackState$: IStateMachine<PlaybackState>;
@@ -35,7 +35,6 @@ export default class ProviderContainer implements IProviderContainer {
35
35
  private tracer;
36
36
  private params;
37
37
  private currentProviderStarted;
38
- private currentFailedVideoTrack;
39
38
  private volumeMultiplierManager;
40
39
  private dashMaxTvVideoQuality;
41
40
  private mayday;
@@ -15,7 +15,6 @@ type LiveFormat = VideoFormat.WEB_RTC_LIVE | VideoFormat.HLS_LIVE | VideoFormat.
15
15
  type AllLiveFormats = [LiveFormat, LiveFormat, LiveFormat, LiveFormat, LiveFormat];
16
16
  export declare const getLiveFormatsPriority: ({ androidPreferredFormat, preferCMAF, preferWebRTC }: Constraints) => AllLiveFormats;
17
17
  export declare const getChromeCastFormatsPriority: (live: boolean) => VideoFormat[];
18
- export declare const selectCodec: (codecs: Set<string>) => string | undefined;
19
18
  type CodecStream = {
20
19
  codecs: string;
21
20
  hdr?: boolean;
@@ -1,6 +1,5 @@
1
1
  import type { IProviderEntry } from "../types";
2
2
  import type { IObservable, Milliseconds } from "@vkontakte/videoplayer-shared";
3
- import { Observable } from "@vkontakte/videoplayer-shared";
4
3
  import type { IStateMachine } from "../../../utils/StateMachine/types";
5
4
  import { PlaybackState } from "../../../player/types";
6
5
  interface IParams {
@@ -12,5 +11,10 @@ interface IParams {
12
11
  playbackHangupNoDataThreshold: Milliseconds;
13
12
  useDelayedPlaybackHangupWithData: boolean;
14
13
  }
15
- declare const _default: (params: IParams) => Observable<string>;
14
+ export interface IPlaybackHangupInfo {
15
+ from: PlaybackState;
16
+ to: PlaybackState;
17
+ label: string;
18
+ }
19
+ declare const _default: (params: IParams) => IObservable<IPlaybackHangupInfo>;
16
20
  export default _default;
@@ -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
- currentBuffer$: IValueSubject<IRange<Seconds> | undefined>;
85
- currentNativeBuffer$: IValueSubject<IRange<Seconds> | undefined>;
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>;
@@ -1,5 +1,6 @@
1
- import type { IAbrController, IAbrRule, IBaseAbrControllerContext, IRuleInitContext } from "./types";
1
+ import type { IAbrController, IAbrRule, IBaseAbrControllerContext, IRuleInitContext, RuleLogData } from "./types";
2
2
  import type { IBaseTrack } from "../../../player/types";
3
+ export declare const formatRuleLog: ({ name, ...logData }: RuleLogData) => string;
3
4
  export default class AbrController<
4
5
  T extends IBaseTrack,
5
6
  C extends IBaseAbrControllerContext
@@ -12,6 +13,8 @@ export default class AbrController<
12
13
  destroy(): void;
13
14
  updateContext(context: C): void;
14
15
  autoSelectTrack(rules?: IAbrRule<T, C>[]): T;
16
+ private traceQualitySwitch;
17
+ private isLowQuality;
15
18
  private selectTrackBasedOnHistory;
16
19
  /** при переключении аудио стрима очищаем историю для предотвращения залипания в `onCooldown` */
17
20
  historyReset(): void;
@@ -7,11 +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;
14
+ private tracer;
13
15
  init(context: IInitAbrManagerContext): void;
14
16
  updateContext(updateContext: IUpdatableAbrManagerContext): void;
17
+ private getAudioReserve;
15
18
  autoSelectTrack<T extends IVideoTrack | IAudioTrack>(kind: Exclude<StreamKind, StreamKind.TEXT>): T;
16
19
  destroy(): void;
17
20
  private initVideoElementAbrContext;
@@ -1,15 +1,16 @@
1
- import type { IObservable, IValueSubject, Milliseconds } from "@vkontakte/videoplayer-shared";
1
+ import type { IObservable, ITracer, IValueSubject, Milliseconds } from "@vkontakte/videoplayer-shared";
2
2
  import type { ITuningConfig } from "../../../../utils/tuningConfig";
3
3
  import type { IVideoTrack } from "../../../../player/types";
4
- import type { IObservableVideo } from "../../HTMLVideoElement/observable";
4
+ import type { IObservableMediaElement } from "../../HTMLVideoElement/observable";
5
5
  interface IConnectData {
6
6
  videoLastDataObtainedTimestamp$: IValueSubject<Milliseconds>;
7
7
  lastVideoTrackSelected$: IValueSubject<IVideoTrack | undefined>;
8
8
  rtt$: IValueSubject<Milliseconds>;
9
9
  isSeeked$: IObservable<boolean>;
10
- observableVideo: IObservableVideo;
10
+ observableVideo: IObservableMediaElement;
11
11
  currentStallDuration$: IValueSubject<Milliseconds>;
12
12
  tuning: ITuningConfig["stallsManager"];
13
+ tracer: ITracer;
13
14
  }
14
15
  export declare class StallsController {
15
16
  private currentStallDuration$;
@@ -20,6 +21,9 @@ export declare class StallsController {
20
21
  private lastUniqueVideoTrackSelectedTimestamp;
21
22
  private lastUniqueVideoTrackSelected;
22
23
  private providerStartWatchingTimestamp;
24
+ private tracer;
25
+ private severeStallTracer;
26
+ private severeStallStartedAt;
23
27
  private subscription;
24
28
  severeStallOccurred$: IValueSubject<boolean>;
25
29
  totalStallsCount$: IValueSubject<number>;
@@ -28,6 +32,9 @@ export declare class StallsController {
28
32
  lastStallDuration$: IValueSubject<Milliseconds>;
29
33
  init(data: IConnectData): void;
30
34
  destroy(): void;
35
+ private startSevereStallTracer;
36
+ private endSevereStallTracer;
37
+ private traceUpdateStallData;
31
38
  private updateStallData;
32
39
  }
33
40
  export {};