import { ITuningConfig } from '../../../utils/tuningConfig';
import { IError, IRange, ISubject, IValueSubject, Milliseconds } from '@vkontakte/videoplayer-shared';
import type { Fetcher } from './fetcher';
import { CommonInit, Manifest, Representation, Stream, StreamKind } from '../../../providers/utils/parsers/types';
export interface Dependencies {
    fetcher: Fetcher;
    tuning: ITuningConfig;
    getCurrentPosition: () => Milliseconds | undefined;
    isActiveLowLatency: () => boolean;
    compatibilityMode?: boolean;
    manifest: Manifest | null;
}
export interface Gap extends IRange<Milliseconds> {
    representation: Representation['id'];
    /**
     * дырки, которые не нужно удалять при парсинге буфера (те `detectGapsWhenIdle`).
     * те, например, которые были обнаружены при парсинге сегментов из манифеста.
     *
     * в функции `detectGapsWhenIdle` мы сравниваем ранее найденные дырки с данными буфера,
     * проблема в том, что не смотря на то, что буфер может показать, что как будто дырки нет,
     * по факту, найденная в манифесте дырка, скорее всего, никуда не делась и это приведет к зависанию видео.
     */
    persistent: boolean;
}
export declare class BufferManager {
    currentLiveSegmentServerLatency$: IValueSubject<number>;
    currentLowLatencySegmentLength$: IValueSubject<number>;
    currentSegmentLength$: IValueSubject<number>;
    onLastSegment$: IValueSubject<boolean>;
    fullyBuffered$: IValueSubject<boolean>;
    playingRepresentation$: IValueSubject<Representation['id'] | undefined>;
    playingRepresentationInit$: IValueSubject<CommonInit | undefined>;
    error$: ISubject<IError>;
    gaps: Gap[];
    private subscription;
    private kind;
    private initData;
    private parsedInitData;
    private representations;
    private segments;
    private allInitsLoaded;
    private activeSegments;
    private mediaSource;
    private playingRepresentationId;
    private downloadingRepresentationId;
    private switchingToRepresentationId;
    private sourceBuffer;
    private downloadAbortController;
    private switchAbortController;
    private destroyAbortController;
    private useSmartRepresentationSwitch;
    private readonly getCurrentPosition;
    private readonly isActiveLowLatency;
    private tuning;
    private forwardBufferTarget;
    private fetcher;
    private bufferLimit;
    private sourceBufferTaskQueue;
    private gapDetectionIdleCallback;
    private initLoadIdleCallback;
    private failedDownloads;
    private baseUrls;
    private baseUrlsIndex;
    private compatibilityMode;
    private preloadOnly;
    private isLive;
    private liveUpdateSegmentIndex;
    private liveInitialAdditionalOffset;
    private isSeekingLive;
    private index;
    private lastDataObtainedTimestampMs;
    private loadByteRangeSegmentsTimeoutId;
    constructor(kind: StreamKind, mediaSource: MediaSource, representations: Representation[], { fetcher, tuning, getCurrentPosition, isActiveLowLatency, compatibilityMode, manifest }: Dependencies);
    startWith: (param_0: string) => Promise<void | undefined>;
    switchToWithPreviousAbort(newRepresentationId: Representation['id'], dropBuffer?: boolean): void;
    switchTo: (param_0: string, param_1: boolean | undefined) => Promise<void | undefined>;
    switchToOld: (param_0: string, param_1: boolean | undefined) => Promise<void | undefined>;
    warmUpMediaSource(): void;
    abort(): Promise<boolean>;
    maintain(currentPosition?: Milliseconds | undefined): void;
    get lastDataObtainedTimestamp(): number;
    private searchGaps;
    private getActualLiveStartingSegments;
    getLiveSegmentsToLoadState(manifest: Manifest | null): IRange<Milliseconds> | undefined;
    seekLive: (param_0: Stream[]) => Promise<void | undefined>;
    updateLive(manifest: Manifest | null): void;
    proceedLowLatencyLive(): void;
    calculateDurationFromSegments(): number;
    setSmartRepresentationSwitch(state: boolean): void;
    private updateLowLatencyLiveIfNeeded;
    findSegmentStartTime(position: Milliseconds): Milliseconds | undefined;
    setTarget(time: Milliseconds): void;
    setPreloadOnly(preloadOnly: boolean): void;
    destroy(): void;
    private selectForwardBufferSegments;
    private selectForwardBufferSegmentsLive;
    private selectForwardBufferSegmentsRecord;
    private loadSegments;
    private loadTemplateSegment;
    private updateRepresentationsBaseUrlIfNeeded;
    private loadByteRangeSegments;
    private prepareByteRangeFetchSegmentParams;
    private prepareTemplateFetchSegmentParams;
    private abortActiveSegments;
    private onSomeTemplateDataLoaded;
    /**
     * Закидываем в буфер сегменты атомарнее чем сегмент целиком. Например, по боксам в мпеге и по блокам в вебме.
     * Таким образом не ждём его полной загрузки и готовы играть его намного быстрее
     * @param dataView – данные, размер буфера – весь запрос
     * @param globalFrom – Отступ dataView от начала файла, совпадает с отсупами сегментов
     * @param loaded – Объём загруженных в dataView данных (всё что больше – пока нули)
     * @private
     */
    private onSomeByteRangesDataLoaded;
    private onSegmentFullyAppended;
    private abortSegment;
    private loadNextInit;
    private loadInit;
    private dropBuffer;
    private pruneBuffer;
    private abortBuffer;
    getDebugBufferState(): IRange<Milliseconds> | undefined;
    getForwardBufferDuration(currentPosition?: Milliseconds | undefined): Milliseconds;
    private detectGaps;
    private detectGapsWhenIdle;
    private checkEjectedSegments;
    private handleAsyncError;
}
