import { IObservable, IValueObservable, IValueSubject, ILogEntry, Kbps, Milliseconds, Seconds, IRectangle, IError, QualityLimits, VideoQuality } from '@vkontakte/videoplayer-shared';
import { Pixel } from '../utils/3d/types';
export interface StartEnd<Unit extends number> {
    start: Unit;
    end: Unit;
}
export interface IPlayer {
    info: IPlayerInfo;
    events: IPlayerEvents;
    /**
     * Инициализация видео
     */
    initVideo(config: IConfig): IPlayer;
    /**
     *  Полная деинициализация плеера
     */
    destroy(): void;
    prepare(): IPlayer;
    play(): IPlayer;
    pause(): IPlayer;
    stop(): IPlayer;
    /**
     * @param time
     * @param forcePrecise Для длинных видео перемотка по-умолчанию может быть не точной (т.к. точная выполняется долго). С этим флагом перемотка будет гарантировано точной (но возможно медленной)
     */
    seekTime(time: Seconds, forcePrecise?: boolean): IPlayer;
    /**
     * @param percent: number [0; 1]
     */
    seekPercent(percent: number): IPlayer;
    /**
     * @param percent: number [0; 1]
     */
    setVolume(percent: number, muted?: boolean): IPlayer;
    /**
     * @param muted Флаг, отражающий нужно ли сделать мьют.
     * @param forced Флаг, который игнорирует внутренние механики простановки mute значения
     * и ставит то значение, которое передали в функцию.
     */
    setMuted(muted: boolean, forced?: boolean): IPlayer;
    setAudioStream(stream: IVideoStream): IPlayer;
    setVideoStream(stream: IVideoStream): IPlayer;
    setQuality(quality: VideoQuality): IPlayer;
    setAutoQuality(enable: boolean): IPlayer;
    setAutoQualityLimits(limit: QualityLimits): IPlayer;
    /**
     * Установить предопределенные настройки лимитов.
     */
    setPredefinedQualityLimits(type: PredefinedQualityLimits): IPlayer;
    startCameraManualRotation(mx: number, my: number): IPlayer;
    stopCameraManualRotation(immediate: boolean): IPlayer;
    moveCameraFocusPX(mx: Pixel, my: Pixel, dt: number): IPlayer;
    holdCamera(): IPlayer;
    releaseCamera(): IPlayer;
    setPlaybackRate(playbackRate: PlaybackRate): IPlayer;
    setLooped(isLooped: boolean): IPlayer;
    setExternalTextTracks(tracks: Omit<IExternalTextTrack, 'type'>[]): IPlayer;
    selectTextTrack(id: ITextTrack['id'] | undefined): IPlayer;
    setTextTrackCueSettings(settings: ICueSettings): IPlayer;
    setLiveLowLatency(isLowLatency: boolean): IPlayer;
    /**
     * Включает или отключает Chromecast
     */
    toggleChromecast(): void;
    /**
     * Возвращает наиболее точное время воспроизведения.
     * Может быть точнее, чем `info.position$` в промежутках между timeupdate
     */
    getExactTime(): number;
    /**
     * Возвращает все логи с момента инициализации плеера
     */
    getAllLogs(): ILogEntry[];
    experimental: {
        /**
         * Элемент, который сейчас вставлен в container.
         * Может быть видеоэлементом, iframe и вообще чем угодно в общем случае.
         */
        element$: IValueObservable<HTMLVideoElement | undefined>;
        tuningConfigName$: IValueSubject<string[]>;
        enableDebugTelemetry$: IValueSubject<boolean>;
        dumpTelemetry: (receiver: (value: Record<string, any>) => void) => void;
        /** функция вычисления текущей позиции проигрывания из под провадера (если расчет нестандартный) */
        getCurrentTime$: IValueSubject<(() => number) | null>;
    };
}
/**
 * События плеера.
 * События, начинающиеся с `will...` случаются в начале совершения действия,
 * остальные - в момент окончания действия.
 */
export interface IPlayerEvents {
    /**
     * Плеер получил ссылку и начал полезную работу
     */
    inited$: IObservable<void>;
    /**
     * Предзагрузка окончена и плеер готов стартовать немедленно. Если предзагрузка не инициировалась, события не будет
     */
    ready$: IObservable<void>;
    /**
     * Видео начало воспроизведение в первый раз
     * Соответствует первому для видео внешнему запуску воспроизведения
     */
    started$: IObservable<void>;
    /**
     * Любое начало воспроизведения. Первои и после паузы
     */
    playing$: IObservable<void>;
    /**
     * Видео на паузе
     */
    paused$: IObservable<void>;
    /**
     * Плеер остановлен
     */
    stopped$: IObservable<void>;
    /**
     * Запрошена предзагрузка видео
     */
    willReady$: IObservable<void>;
    /**
     * Запрошена пауза
     */
    willPause$: IObservable<void>;
    /**
     * Запрошено первый старт воспроизведения
     */
    willStart$: IObservable<void>;
    /**
     * Запрошено возобновление воспроизведения после паузы
     */
    willResume$: IObservable<void>;
    /**
     * Плеер будет остановлен
     */
    willStop$: IObservable<void>;
    /**
     * Плеер будет уничтожен, в момент события можно синхронно запросить последние данные о его состоянии.
     */
    willDestruct$: IObservable<void>;
    /**
     * @deprecated
     */
    watchCoverageRecord$: IObservable<StartEnd<Seconds>>;
    /**
     * @deprecated
     */
    watchCoverageLive$: IObservable<StartEnd<Milliseconds>>;
    /**
     * Ошибка в работе после которой воспроизведение было восстановлено
     */
    managedError$: IObservable<IError>;
    /**
     * Критическая ошибка, воспроизведение более не возможно
     */
    fatalError$: IObservable<IError>;
    /**
     * Проигрывание видео завершено
     */
    ended$: IObservable<void>;
    /**
     * Видео доиграло до конца, перемоталось в начало и заиграло снова, в параметре время в которое произошло переключение
     */
    looped$: IObservable<Seconds>;
    /**
     * Совершена перемотка
     */
    seeked$: IObservable<void>;
    /**
     * Запрошена перемотка
     */
    willSeek$: IObservable<ISeekRequest>;
    /**
     * Браузер не разрешил стартовать со звуком
     */
    autoplaySoundProhibited$: IObservable<void>;
    /**
     * Был отправлен запрос за манифестом
     * Событик поддерживается не во всех провайдерах
     */
    manifestRequested$: IObservable<void>;
    /**
     * Запрос за манифестом был успешно получен
     * Событик поддерживается не во всех провайдерах
     */
    manifestReceived$: IObservable<void>;
    /**
     * Был отправлен запрос за первыми медиа данными
     * Событик поддерживается не во всех провайдерах
     */
    firstBytesRequested$: IObservable<void>;
    /**
     * Запрос за первыми медиа данными был успешно получен
     * Событик поддерживается не во всех провайдерах
     */
    firstBytesReceived$: IObservable<void>;
    /**
     * Получен первый кусок контента от сервера раздачи видео
     * Событие поддерживается не во всех провайдерах (т.к. не все способы проигрывания видео поддерживают такой интерфейс)
     *
     * Содержит время в миллисекундах: сколько прошло с момента инициализации
     */
    firstBytes$: IObservable<Milliseconds>;
    /**
     * Загружена метадата в видео элементе
     */
    loadedMetadata$: IObservable<void>;
    /**
     * Показан первый кадр
     *
     * Содержит время в миллисекундах: сколько прошло времени с инициализации
     */
    firstFrame$: IObservable<Milliseconds>;
    /**
     * Плеер готов начать воспроизведение
     *
     * Содержит время в миллисекундах: сколько прошло времени с инициализации
     */
    canplay$: IObservable<Milliseconds>;
    /**
     * Логи для отладки
     */
    log$: IObservable<ILogEntry>;
    /**
     * Ошибки запроса данных, которые должны полечится перезапуском плеера
     */
    fetcherRecoverableError$: IObservable<IError>;
    /**
     * Произошел серьезный/долгий стол.
     */
    severeStallOccured$: IObservable<boolean>;
}
export interface IPlayerInfo {
    /**
     * Оптимистичный статут плеера. Так например, значение будет равно Playing сразу после вызова play().
     * Фактическое состояние лучше отслеживать по событиям (например, playing$)
     */
    playbackState$: IValueObservable<PlaybackState | undefined>;
    /**
     * Текущая позиция.
     *
     * default value: `0`
     */
    position$: IValueObservable<Seconds>;
    /**
     * Длительность видео.
     *
     * default value: `Infinity`
     */
    duration$: IValueObservable<Seconds>;
    /**
     * default value: `false`
     */
    muted$: IValueObservable<boolean>;
    /**
     * default value: `1`
     */
    volume$: IValueObservable<number>;
    currentVideoStream$: IValueObservable<IVideoStream | undefined>;
    availableVideoStreams$: IValueObservable<IVideoStream[]>;
    currentAudioStream$: IValueObservable<IAudioStream | undefined>;
    availableAudioStreams$: IValueObservable<IAudioStream[]>;
    /**
     * Список доступных качеств. Отсортированы по возрастанию.
     *
     * default value: `[]`
     */
    availableQualities$: IValueObservable<VideoQuality[]>;
    /**
     * Список фпс для доступных качеств
     *
     * default value: `{}`
     */
    availableQualitiesFps$: IValueObservable<FpsByQuality>;
    /**
     * Список доступных аудиодорожек
     *
     * default value: `[]`
     */
    availableAudioTracks$: IValueSubject<IAudioTrack[]>;
    /**
     * Доступна ли аудио дорожка
     *
     * default value: true
     */
    isAudioAvailable$: IValueSubject<boolean>;
    /**
     * Реальное качество, в котором сейчас воспроизводится видео.
     *
     * default value: `undefined`
     */
    currentQuality$: IValueObservable<VideoQuality | undefined>;
    /**
     * Будет ли плеер адаптивно переключать качество в зависимости от канала пользователя
     */
    isAutoQualityEnabled$: IValueObservable<boolean>;
    /**
     * Доступна ли установка лимитов авто качества
     */
    autoQualityLimitingAvailable$: IValueObservable<boolean>;
    /**
     * Текущие лимиты авто-качества
     */
    autoQualityLimits$: IValueObservable<QualityLimits>;
    /**
     * Отображает тип лимитов по качеству.
     */
    predefinedQualityLimitType$: IValueObservable<PredefinedQualityLimits>;
    /**
     * Текущая скорость воспроизведения
     */
    currentPlaybackRate$: IValueObservable<PlaybackRate>;
    /**
     * Текущий буффер (тот, который содержит текущую позицию воспроизведения)
     *
     * default value: `undefined`
     */
    currentBuffer$: IValueObservable<StartEnd<Seconds> | undefined>;
    /**
     * Статус буферизации видео. true если буфер пустой и воспроизведение прервано
     * В отличии от isStalled показывает и буферизации на старте и после перемотки
     */
    isBuffering$: IValueObservable<boolean>;
    /**
     * Статус только нежелательной буферизации, возникает при опустошении буфера в процессе воспроизведения
     * и не возникает при начальном наполнении буфера или после перемотки
     */
    isStalled$: IValueObservable<boolean>;
    /**
     * Закончилось ли видео
     */
    isEnded$: IValueObservable<boolean>;
    /**
     * Зациклено ли видео
     */
    isLooped$: IValueObservable<boolean>;
    /**
     * Бесконечный ли стрим
     */
    isLive$: IValueObservable<boolean | undefined>;
    /**
     * Был ли завершен бесконечный стрим
     */
    isLiveEnded$: IValueObservable<boolean | null>;
    /**
     * Доступно ли ускоренное воспроизведении в лайв трансляции
     */
    canChangePlaybackSpeed$: IValueObservable<boolean | undefined>;
    /**
     * Играем ли мы сейчас самый актуальный кадр лайва
     */
    atLiveEdge$: IValueObservable<boolean | undefined>;
    /**
     * Может ли плеер доиграть буффер законченной трансляции при перемотке
     */
    canPlayLiveTailBuffer$: IValueObservable<boolean>;
    /**
     * Играем ли мы сейчас самый старый кадр лайва
     */
    atLiveDurationEdge$: IValueObservable<boolean | undefined>;
    /**
     * Серверное время текущего кадра
     */
    liveTime$: IValueObservable<Milliseconds | undefined>;
    /**
     * Буферное время текущего кадра
     */
    liveBufferTime$: IValueObservable<Milliseconds | undefined>;
    /**
     * Задержка лайв стрима
     */
    liveLatency$: IValueObservable<Milliseconds | undefined>;
    /**
     * Формат, в котором сейчас воспроизводится видео
     */
    currentFormat$: IValueObservable<VideoFormat | undefined>;
    /**
     * Список всех доступных субтитров
     */
    availableTextTracks$: IValueObservable<ITextTrack[]>;
    /**
     * Выбранная и отображаемая дорожка субтитров
     */
    currentTextTrack$: IValueObservable<ITextTrack['id'] | undefined>;
    /**
     * Рассчитанная ширина канала пользователя
     */
    throughputEstimation$: IValueObservable<Kbps | undefined>;
    /**
     * Round-Trip-Time, время от отправки запроса до получения ответа. Весьма неточное.
     */
    rttEstimation$: IValueObservable<Milliseconds | undefined>;
    /**
     * Битрейт текущей видео-дорожки
     */
    videoBitrate$: IValueObservable<Kbps | undefined>;
    /**
     * Хост с которого воспроизводится видео
     */
    hostname$: IValueObservable<string | undefined>;
    /**
     * Тип HTTP соединения последнего запроса
     */
    httpConnectionType$: IValueObservable<HttpConnectionType | undefined>;
    /**
     * Было ли переиспользовано последнее HTTP соединение
     */
    httpConnectionReused$: IValueObservable<boolean | undefined>;
    /**
     * Состояние подключения Chromecast
     */
    chromecastState$: IValueObservable<ChromecastState>;
    /**
     * Имя устройства, куда выводится видео через Chromecast.
     * `undefined`, если видео не играет на Chromecast устройстве
     */
    chromecastDeviceName$: IValueObservable<string | undefined>;
    /**
     * Фактический размер видео
     */
    intrinsicVideoSize$: IValueObservable<{
        width: number;
        height: number;
    } | undefined>;
    /**
     * Признак того, что сейчас проигрывается 3D-видео
     */
    is3DVideo$: IValueObservable<boolean>;
    /**
     * Где сейчас рисуется картинка
     */
    surface$: IValueObservable<Surface | undefined>;
    /**
     * Список всех доступных источников
     */
    availableSources$: IValueObservable<ISources | undefined>;
    /**
     * Длина видео сегмента
     */
    currentVideoSegmentLength$: IValueSubject<number>;
    /**
     * Длина аудио сегмента
     */
    currentAudioSegmentLength$: IValueSubject<number>;
}
export declare enum PlaybackState {
    STOPPED = "stopped",
    READY = "ready",
    PLAYING = "playing",
    PAUSED = "paused"
}
export interface IVolumeState {
    /**
     * range: [0;1]
     */
    volume: number;
    muted: boolean;
}
export interface IConfig {
    container: string | HTMLElement;
    sources: ISources;
    meta?: IMetadata;
    failoverHosts?: string[];
    volumeMultiplier?: number;
    panelSize?: IRectangle;
}
export interface ISources {
    [VideoFormat.MPEG]?: IMpegSource;
    [VideoFormat.DASH]?: IDashURLSource;
    [VideoFormat.DASH_SEP]?: IDashURLSource;
    [VideoFormat.DASH_WEBM]?: IDashURLSource;
    [VideoFormat.DASH_WEBM_AV1]?: IDashURLSource;
    [VideoFormat.DASH_STREAMS]?: IDashURLSource;
    [VideoFormat.DASH_ONDEMAND]?: IDashURLSource;
    [VideoFormat.DASH_LIVE]?: IDashURLSource;
    [VideoFormat.DASH_LIVE_CMAF]?: IDashURLSource;
    [VideoFormat.DASH_LIVE_WEBM]?: IDashURLSource;
    [VideoFormat.HLS]?: IHLSSource;
    [VideoFormat.HLS_ONDEMAND]?: IHLSSource;
    [VideoFormat.HLS_FMP4]?: IHLSSource;
    [VideoFormat.HLS_LIVE]?: IHLSLiveSource;
    [VideoFormat.HLS_LIVE_CMAF]?: IHLSLiveSource;
    [VideoFormat.WEB_RTC_LIVE]?: URLSource;
}
export interface IMetadata {
    title?: string;
    subtitle?: string;
    videoId?: string;
}
export type QualitySetSource = Partial<Record<VideoQuality, string>>;
export type URLSource = {
    type: 'url';
    url: string;
};
export type RawSource = {
    type: 'raw';
    raw: string;
};
export type URLSourceWithSeek = URLSource & Partial<{
    maxSeekBackTime: Milliseconds;
}>;
export type IMpegSource = QualitySetSource;
export type IDashURLSource = URLSource & {
    compatibilityMode?: boolean;
};
export type IDashSource = URLSource | RawSource;
export type IHLSSource = URLSource;
export type IHLSLiveSource = URLSourceWithSeek;
export declare enum VideoFormat {
    MPEG = "MPEG",
    /** @deprecated Больше не транскодируется */
    DASH = "DASH",// "Старый" h264 даш, слитный: Аудиодорожка слита с видео
    DASH_SEP = "DASH_SEP",// h264, но аудиодорожка отделена
    /** @deprecated Используйте DASH_SEP */ DASH_SEP_VK = "DASH_SEP",
    DASH_WEBM = "DASH_WEBM",// Видео закодировано в VP9, аудио в opus, контейнер webm
    DASH_WEBM_AV1 = "DASH_WEBM_AV1",// Видео закодировано в AV1, остальное как _WEBM
    DASH_STREAMS = "DASH_STREAMS",// AdaptationSet может быть несколько. На текущий момент различаются только языки аудио. Возможно позже и кодеки будут. Пока H.264/AAC
    /** @deprecated Используйте DASH_WEBM */ DASH_WEBM_VK = "DASH_WEBM",
    DASH_ONDEMAND = "DASH_ONDEMAND",// На бэке сегменты транскодируются на лету. Кодек H.264. Формат манифеста отличается, SegmentTemplate вместо SegmentBase
    /** @deprecated Используйте DASH_ONDEMAND */ DASH_ONDEMAND_VK = "DASH_ONDEMAND",
    DASH_LIVE = "DASH_LIVE",
    DASH_LIVE_CMAF = "DASH_LIVE_CMAF",
    /** @deprecated */
    DASH_LIVE_WEBM = "DASH_LIVE_WEBM",
    HLS = "HLS",
    HLS_ONDEMAND = "HLS_ONDEMAND",
    /** @deprecated Используйте HLS */ HLS_JS = "HLS",
    HLS_FMP4 = "HLS_FMP4",
    HLS_LIVE = "HLS_LIVE",
    HLS_LIVE_CMAF = "HLS_LIVE_CMAF",
    WEB_RTC_LIVE = "WEB_RTC_LIVE"
}
export declare enum VideoCodec {
    AV1 = "av1",
    VP9 = "vp9",
    AVC1 = "avc1",// H264, AVC
    HEV1 = "hev1"
}
export declare enum AudioCodec {
    OPUS = "opus",
    MP4A = "mp4a"
}
export interface IVideoStream {
    id: string;
    language?: string;
    hdr?: boolean;
    codec?: string;
    label?: string;
}
export interface IBaseTrack {
    id: string;
    bitrate?: Kbps;
}
export interface IVideoTrack extends IBaseTrack {
    quality: VideoQuality;
    size?: IRectangle;
    fps?: number;
    streamId?: IVideoStream['id'];
}
export interface IAudioStream {
    id: string;
    language?: string;
    label?: string;
    codec?: string;
    isDefault?: boolean;
}
export type IAudioTrack = IBaseTrack;
interface ITextTrackBase {
    type: 'external' | 'internal';
    id: string;
    language?: string;
    label?: string;
    url?: string;
    isAuto?: boolean;
}
export interface IExternalTextTrack extends ITextTrackBase {
    type: 'external';
    url: string;
}
export interface IInternalTextTrack extends ITextTrackBase {
    type: 'internal';
    url: string;
}
export type ITextTrack = IExternalTextTrack | IInternalTextTrack;
export interface ICueSettings {
    align?: 'left' | 'center' | 'right';
    position?: number | 'auto';
    size?: number;
    line?: number | 'auto';
}
export declare enum VideoDestination {
    SCREEN = "SCREEN",
    CHROMECAST = "CHROMECAST"
}
export declare enum ChromecastState {
    NOT_AVAILABLE = "NOT_AVAILABLE",
    AVAILABLE = "AVAILABLE",
    CONNECTING = "CONNECTING",
    CONNECTED = "CONNECTED"
}
export interface ISeekRequest {
    from: Seconds;
    to: Seconds;
}
export declare enum HttpConnectionType {
    HTTP1 = "http1",
    HTTP2 = "http2",
    QUIC = "quic"
}
export declare enum SeekOperationState {
    None = "none",
    Requested = "requested",
    Applying = "applying"
}
type SeekStateNone = {
    state: SeekOperationState.None;
};
type SeekStateNotNone = {
    state: Exclude<SeekOperationState, SeekOperationState.None>;
    position: Milliseconds;
    forcePrecise: boolean;
};
export type SeekState = SeekStateNone | SeekStateNotNone;
export type FpsByQuality = Partial<Record<VideoQuality, number>>;
export type PlaybackRate = number;
export declare enum Surface {
    NONE = "none",
    INLINE = "inline",
    FULLSCREEN = "fullscreen",
    SECOND_SCREEN = "second_screen",
    PIP = "pip",
    INVISIBLE = "invisible"
}
export declare enum PredefinedQualityLimits {
    TRAFFIC_SAVING = "traffic_saving",
    HIGH_QUALITY = "high_quality",
    UNKNOWN = "unknown"
}
export {};
