@vkontakte/videoplayer-shared 1.0.99 → 1.0.100-dev.065b3da4a.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 +4 -4
- package/es2015.esm.js +4 -4
- package/esnext.cjs +4 -4
- package/esnext.esm.js +4 -4
- package/evergreen.esm.js +4 -4
- package/package.json +1 -1
- package/types/audio/AudioGraph.d.ts +37 -0
- package/types/audio/AudioPluginChain.d.ts +41 -0
- package/types/audio/AudioSourceConnection.d.ts +36 -0
- package/types/audio/global.d.d.ts +3 -0
- package/types/audio/index.d.ts +5 -0
- package/types/audio/plugins/EqualizerPlugin.d.ts +31 -0
- package/types/audio/plugins/NormalizerPlugin.d.ts +23 -0
- package/types/audio/plugins/VolumeFaderPlugin.d.ts +39 -0
- package/types/audio/types.d.ts +132 -0
- package/types/index.d.ts +1 -0
- package/types/utils/clearVideoElement.d.ts +1 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { IAudioGraph, IAudioGraphPlugin } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Конкретная реализация IAudioGraph.
|
|
4
|
+
*
|
|
5
|
+
* Архитектура:
|
|
6
|
+
*
|
|
7
|
+
* source₁ → [Chain₁] ─┐
|
|
8
|
+
* source₂ → [Chain₂] ─┼→ [masterGain] → ctx.destination
|
|
9
|
+
*
|
|
10
|
+
* Каждый источник получает собственную цепочку плагинов.
|
|
11
|
+
* Общий master GainNode управляет общей выходной громкостью.
|
|
12
|
+
*/
|
|
13
|
+
export declare class AudioGraph implements IAudioGraph {
|
|
14
|
+
private _ctx;
|
|
15
|
+
private _masterGain;
|
|
16
|
+
private readonly _connections;
|
|
17
|
+
private _contextEnabled;
|
|
18
|
+
private readonly _boundBeforeDisable;
|
|
19
|
+
/** Доступна ли Web Audio API в текущем окружении. */
|
|
20
|
+
static isSupported(): boolean;
|
|
21
|
+
get context(): AudioContext;
|
|
22
|
+
get contextState(): AudioContextState;
|
|
23
|
+
enableContext(): Promise<void>;
|
|
24
|
+
disableContext(): Promise<void>;
|
|
25
|
+
connectSource(element: HTMLMediaElement): Promise<void>;
|
|
26
|
+
disconnectSource(element: HTMLMediaElement): void;
|
|
27
|
+
isSourceConnected(element: HTMLMediaElement): boolean;
|
|
28
|
+
addPlugin(element: HTMLMediaElement, plugin: IAudioGraphPlugin): void;
|
|
29
|
+
removePlugin(element: HTMLMediaElement, pluginId: string): void;
|
|
30
|
+
getPlugins(element: HTMLMediaElement): readonly IAudioGraphPlugin[];
|
|
31
|
+
createAnalyser(element: HTMLMediaElement): AnalyserNode | null;
|
|
32
|
+
setMasterVolume(volume: number): void;
|
|
33
|
+
getMasterVolume(): number;
|
|
34
|
+
dispose(): void;
|
|
35
|
+
/** Лениво создаёт AudioContext и master gain. */
|
|
36
|
+
private ensureContext;
|
|
37
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { IAudioGraphPlugin } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Упорядоченная цепочка аудиоплагинов между источником и назначением.
|
|
4
|
+
*
|
|
5
|
+
* Цепочка имеет фиксированные input и output GainNodes. Плагины
|
|
6
|
+
* вставляются между ними. При добавлении или удалении плагинов
|
|
7
|
+
* пересобирается только внутреннее соединение
|
|
8
|
+
* input → плагины → output — источники, подключённые ко входу,
|
|
9
|
+
* не затрагиваются.
|
|
10
|
+
*
|
|
11
|
+
* source → [input] → plugin₁ → plugin₂ → … → [output] → destination
|
|
12
|
+
*/
|
|
13
|
+
export declare class AudioPluginChain {
|
|
14
|
+
private readonly _inputNode;
|
|
15
|
+
private readonly _outputNode;
|
|
16
|
+
private _plugins;
|
|
17
|
+
private _destination;
|
|
18
|
+
private readonly _taps;
|
|
19
|
+
constructor(ctx: AudioContext);
|
|
20
|
+
/** Узел, к которому подключаются источники. */
|
|
21
|
+
get input(): AudioNode;
|
|
22
|
+
/** Текущие плагины в порядке цепочки. */
|
|
23
|
+
get plugins(): readonly IAudioGraphPlugin[];
|
|
24
|
+
/** Подключает выход цепочки к узлу назначения. */
|
|
25
|
+
connectTo(destination: AudioNode): void;
|
|
26
|
+
/** Паразитное подключение к выходу цепочки (например, для AnalyserNode). Сохраняется при пересборке. */
|
|
27
|
+
addTap(node: AudioNode): void;
|
|
28
|
+
hasPlugin(id: string): boolean;
|
|
29
|
+
addPlugin(plugin: IAudioGraphPlugin): void;
|
|
30
|
+
removePlugin(id: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Разрушает и пересобирает внутреннее соединение:
|
|
33
|
+
* input → plugin₁ → … → pluginₙ → output → destination
|
|
34
|
+
*
|
|
35
|
+
* Отключает только outputNode каждого плагина (не inputNode), чтобы
|
|
36
|
+
* сохранить внутренние соединения внутри плагинов, имеющих несколько
|
|
37
|
+
* внутренних узлов (например, последовательность BiquadFilterNodes
|
|
38
|
+
* в EqualizerPlugin).
|
|
39
|
+
*/
|
|
40
|
+
private rebuild;
|
|
41
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IAudioGraphPlugin } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Управляет привязкой отдельного HTMLMediaElement к AudioContext.
|
|
4
|
+
*
|
|
5
|
+
* createMediaElementSource(element) необратим — после вызова аудио
|
|
6
|
+
* элемента навсегда направляется через Web Audio. Этот класс отслеживает
|
|
7
|
+
* это состояние: первый bind() создаёт узел-источник; unbind() лишь
|
|
8
|
+
* отключает его; последующий bind() переподключает без создания нового
|
|
9
|
+
* узла-источника.
|
|
10
|
+
*
|
|
11
|
+
* Каждое подключение имеет собственную AudioPluginChain, что позволяет
|
|
12
|
+
* применять эффекты индивидуально для каждого источника. Выход цепочки
|
|
13
|
+
* подаётся на общий destination (обычно master gain node).
|
|
14
|
+
*/
|
|
15
|
+
export declare class AudioSourceConnection {
|
|
16
|
+
private readonly _pluginChain;
|
|
17
|
+
private readonly _element;
|
|
18
|
+
private readonly _ctx;
|
|
19
|
+
private _sourceNode;
|
|
20
|
+
private _isBound;
|
|
21
|
+
constructor(element: HTMLMediaElement, ctx: AudioContext, destination: AudioNode);
|
|
22
|
+
get isBound(): boolean;
|
|
23
|
+
get plugins(): readonly IAudioGraphPlugin[];
|
|
24
|
+
/** Привязывает элемент к аудиографу. Создаёт MediaElementSource при первом вызове. */
|
|
25
|
+
bind(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Отвязывает элемент от аудиографа: источник подключается напрямую к ctx.destination,
|
|
28
|
+
* минуя все плагины (включая мастер-громкость). Это намеренное поведение — unbind
|
|
29
|
+
* полностью отключает элемент от любой обработки.
|
|
30
|
+
*/
|
|
31
|
+
unbind(): void;
|
|
32
|
+
addPlugin(plugin: IAudioGraphPlugin): void;
|
|
33
|
+
removePlugin(id: string): void;
|
|
34
|
+
/** Снимает сигнал с выхода источника параллельно (для визуализации). */
|
|
35
|
+
addAnalyser(analyser: AnalyserNode): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { IAudioGraphPlugin, IAudioEqualizerConfig, IAudioNormalizationConfig } from "./types";
|
|
2
|
+
export { AudioGraph } from "./AudioGraph";
|
|
3
|
+
export { VolumeFaderPlugin } from "./plugins/VolumeFaderPlugin";
|
|
4
|
+
export { EqualizerPlugin } from "./plugins/EqualizerPlugin";
|
|
5
|
+
export { NormalizerPlugin } from "./plugins/NormalizerPlugin";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IAudioGraphPlugin, IAudioEqualizer, IAudioEqualizerConfig } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Многополосный эквалайзер-плагин.
|
|
4
|
+
*
|
|
5
|
+
* Каждая частотная полоса из конфигурации получает собственный
|
|
6
|
+
* BiquadFilterNode (peaking). Полосы соединены последовательно между
|
|
7
|
+
* входом и выходом плагина:
|
|
8
|
+
*
|
|
9
|
+
* input → filter₁ → filter₂ → … → filterₙ → output
|
|
10
|
+
*
|
|
11
|
+
* Все экземпляры в рамках одного AudioContext имеют общие настройки
|
|
12
|
+
* усиления: ConstantSourceNodes (по одному на полосу) хранятся в WeakMap
|
|
13
|
+
* по ключу AudioContext и переиспользуются между экземплярами. Изменение
|
|
14
|
+
* усиления на любом экземпляре обновляет их все.
|
|
15
|
+
*/
|
|
16
|
+
export declare class EqualizerPlugin implements IAudioGraphPlugin {
|
|
17
|
+
readonly id = "equalizer";
|
|
18
|
+
private static _sources;
|
|
19
|
+
private readonly _inputNode;
|
|
20
|
+
private readonly _outputNode;
|
|
21
|
+
private readonly _filterMap;
|
|
22
|
+
readonly equalizer: IAudioEqualizer;
|
|
23
|
+
constructor(ctx: AudioContext, config: IAudioEqualizerConfig);
|
|
24
|
+
get inputNode(): AudioNode;
|
|
25
|
+
get outputNode(): AudioNode;
|
|
26
|
+
/** Сбросить все полосы к усилениям по умолчанию (влияет на все экземпляры). */
|
|
27
|
+
resetAll(): void;
|
|
28
|
+
/** Отключить все фильтры от общих ConstantSourceNodes. */
|
|
29
|
+
dispose(): void;
|
|
30
|
+
private rebuild;
|
|
31
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IAudioGraphPlugin, IAudioNormalizationConfig } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Плагин нормализации — нормализует громкость между медиапотоками.
|
|
4
|
+
*
|
|
5
|
+
* Поток сигнала: компрессор (лимитер) → gain
|
|
6
|
+
*
|
|
7
|
+
* GainNode компенсирует разницу между `lufs` потока и общим целевым
|
|
8
|
+
* уровнем. DynamicsCompressorNode работает как лимитер, порог которого
|
|
9
|
+
* задаётся значением `peak` потока.
|
|
10
|
+
*/
|
|
11
|
+
export declare class NormalizerPlugin implements IAudioGraphPlugin {
|
|
12
|
+
readonly id = "normalizer";
|
|
13
|
+
private readonly _compressor;
|
|
14
|
+
private readonly _gainNode;
|
|
15
|
+
constructor(ctx: AudioContext, config: IAudioNormalizationConfig);
|
|
16
|
+
get inputNode(): AudioNode;
|
|
17
|
+
get outputNode(): AudioNode;
|
|
18
|
+
/**
|
|
19
|
+
* Применяет конфигурацию нормализации: устанавливает порог лимитера
|
|
20
|
+
* из `peak` и вычисляет смещение усиления из `lufs`.
|
|
21
|
+
*/
|
|
22
|
+
applyConfig(config: IAudioNormalizationConfig): void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Milliseconds } from "../../utils/semanticTypes";
|
|
2
|
+
import type { IAudioGraphPlugin, IAudioFader } from "../types";
|
|
3
|
+
interface VolumeFaderConfig {
|
|
4
|
+
/** Длительность фейда в миллисекундах. */
|
|
5
|
+
readonly duration: Milliseconds;
|
|
6
|
+
/** Пользовательская кривая, передаваемая напрямую в setValueCurveAtTime. Если не указана, используется косинусное сглаживание. */
|
|
7
|
+
readonly curve?: Float32Array;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Плагин фейдера громкости — обёртка над GainNode, реализующая IAudioFader.
|
|
11
|
+
*
|
|
12
|
+
* Использует косинусную кривую сглаживания через setValueCurveAtTime
|
|
13
|
+
* для плавных фейдов. GainNode фейда независим от master volume GainNode —
|
|
14
|
+
* их значения перемножаются на стороне Web Audio API.
|
|
15
|
+
*
|
|
16
|
+
* По умолчанию: gain = 1 (единица — без ослабления).
|
|
17
|
+
*/
|
|
18
|
+
export declare class VolumeFaderPlugin implements IAudioGraphPlugin, IAudioFader {
|
|
19
|
+
readonly id = "volume-fader";
|
|
20
|
+
private readonly _gainNode;
|
|
21
|
+
private readonly _duration;
|
|
22
|
+
private readonly _curve;
|
|
23
|
+
private _fade;
|
|
24
|
+
constructor(ctx: AudioContext, config: VolumeFaderConfig);
|
|
25
|
+
get inputNode(): AudioNode;
|
|
26
|
+
get outputNode(): AudioNode;
|
|
27
|
+
get faded(): boolean;
|
|
28
|
+
appear(): void;
|
|
29
|
+
disappear(): void;
|
|
30
|
+
pause(): void;
|
|
31
|
+
resume(): void;
|
|
32
|
+
cancel(): void;
|
|
33
|
+
private _finishFade;
|
|
34
|
+
private _startFade;
|
|
35
|
+
private _buildEasingCurve;
|
|
36
|
+
private _scheduleCurve;
|
|
37
|
+
private _sampleIndex;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Плагин, который можно вставить в цепочку обработки аудио.
|
|
3
|
+
* Каждый плагин владеет своими внутренними AudioNodes и предоставляет
|
|
4
|
+
* пару вход/выход, к которым подключается цепочка.
|
|
5
|
+
*/
|
|
6
|
+
export interface IAudioGraphPlugin {
|
|
7
|
+
/** Уникальный идентификатор внутри цепочки — используется для удаления. */
|
|
8
|
+
readonly id: string;
|
|
9
|
+
/** Узел, к которому подключается предыдущий элемент цепочки. */
|
|
10
|
+
readonly inputNode: AudioNode;
|
|
11
|
+
/** Узел, который подключается к следующему элементу цепочки. */
|
|
12
|
+
readonly outputNode: AudioNode;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Высокоуровневая абстракция аудиографа.
|
|
16
|
+
*
|
|
17
|
+
* Управляет singleton AudioContext, цепочками плагинов для каждого
|
|
18
|
+
* источника и общим master gain node. Источники — это HTMLMediaElements,
|
|
19
|
+
* привязанные через createMediaElementSource — необратимая операция,
|
|
20
|
+
* обрабатываемая прозрачно.
|
|
21
|
+
*/
|
|
22
|
+
export interface IAudioGraph {
|
|
23
|
+
/** Базовый AudioContext (создаётся лениво при первом использовании). */
|
|
24
|
+
readonly context: AudioContext;
|
|
25
|
+
/** Текущее состояние AudioContext. */
|
|
26
|
+
readonly contextState: AudioContextState;
|
|
27
|
+
/**
|
|
28
|
+
* Возобновляет AudioContext — аудио проходит через граф.
|
|
29
|
+
*
|
|
30
|
+
* Может бросить исключение, если AudioContext был закрыт извне.
|
|
31
|
+
*/
|
|
32
|
+
enableContext(): Promise<void>;
|
|
33
|
+
/** Приостанавливает AudioContext — обработка аудио останавливается. */
|
|
34
|
+
disableContext(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Привязывает медиаэлемент к графу.
|
|
37
|
+
* При первом вызове для элемента вызывает createMediaElementSource
|
|
38
|
+
* (необратимо). Последующие вызовы для неподключённого элемента
|
|
39
|
+
* просто переподключают его.
|
|
40
|
+
*
|
|
41
|
+
* Может бросить исключение, если AudioContext был закрыт извне.
|
|
42
|
+
* В этом случае нужно вызвать dispose() и пересоздать AudioGraph.
|
|
43
|
+
*/
|
|
44
|
+
connectSource(element: HTMLMediaElement): Promise<void>;
|
|
45
|
+
/** Отключает медиаэлемент от цепочки плагинов (аудио продолжает играть напрямую, без обработки). */
|
|
46
|
+
disconnectSource(element: HTMLMediaElement): void;
|
|
47
|
+
/** Подключён ли элемент в данный момент и привязан ли он. */
|
|
48
|
+
isSourceConnected(element: HTMLMediaElement): boolean;
|
|
49
|
+
/** Добавляет плагин в цепочку обработки источника. */
|
|
50
|
+
addPlugin(element: HTMLMediaElement, plugin: IAudioGraphPlugin): void;
|
|
51
|
+
/** Удаляет плагин из цепочки источника по id. */
|
|
52
|
+
removePlugin(element: HTMLMediaElement, pluginId: string): void;
|
|
53
|
+
/** Все плагины в текущей цепочке источника. */
|
|
54
|
+
getPlugins(element: HTMLMediaElement): readonly IAudioGraphPlugin[];
|
|
55
|
+
/**
|
|
56
|
+
* Создаёт AnalyserNode, подключённый к выходному сигналу источника.
|
|
57
|
+
* Возвращает null, если источник не подключён.
|
|
58
|
+
* Анализатор сохраняется при добавлении/удалении плагинов
|
|
59
|
+
* (переподключается при пересборке цепочки).
|
|
60
|
+
*/
|
|
61
|
+
createAnalyser(element: HTMLMediaElement): AnalyserNode | null;
|
|
62
|
+
/** Устанавливает общую выходную громкость (0 = тишина, 1 = единица). */
|
|
63
|
+
setMasterVolume(volume: number): void;
|
|
64
|
+
/** Текущая общая громкость. */
|
|
65
|
+
getMasterVolume(): number;
|
|
66
|
+
/** Закрывает AudioContext и освобождает все ресурсы. */
|
|
67
|
+
dispose(): void;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Аудио-фейдер — управляет плавными нарастаниями/затуханиями громкости
|
|
71
|
+
* (fade in/out).
|
|
72
|
+
*
|
|
73
|
+
* Фейдер использует отдельный GainNode, выход которого умножается с
|
|
74
|
+
* master volume GainNode на стороне Web Audio API, что позволяет
|
|
75
|
+
* независимо управлять фейдом и общей громкостью.
|
|
76
|
+
*/
|
|
77
|
+
export interface IAudioFader {
|
|
78
|
+
/** Активен ли в данный момент фейд-рамп (включая паузу). */
|
|
79
|
+
readonly faded: boolean;
|
|
80
|
+
/** Принудительно устанавливает gain фейда в 0, затем нарастает до 1. */
|
|
81
|
+
appear(): void;
|
|
82
|
+
/** Принудительно устанавливает gain фейда в 1, затем затухает до 0. */
|
|
83
|
+
disappear(): void;
|
|
84
|
+
/** Замораживает активный фейд-рамп в текущей позиции. */
|
|
85
|
+
pause(): void;
|
|
86
|
+
/** Возобновляет ранее приостановленный фейд-рамп с замороженной позиции. */
|
|
87
|
+
resume(): void;
|
|
88
|
+
/** Отменяет активный фейд и устанавливает gain в целевое значение текущего рампа. */
|
|
89
|
+
cancel(): void;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Параметры нормализации аудио для медиапотока.
|
|
93
|
+
*
|
|
94
|
+
* - `lufs` — интегрированная громкость (LUFS), используется для расчёта
|
|
95
|
+
* смещения усиления, необходимого для приведения потока к общему
|
|
96
|
+
* целевому уровню.
|
|
97
|
+
* - `peak` — истинный пик (дБ), используется для настройки порога лимитера.
|
|
98
|
+
* - `targetLufs` — целевая громкость для нормализации (по умолчанию: -14 LUFS,
|
|
99
|
+
* де-факто стандарт для музыкального стриминга — Spotify, YouTube, Apple Music).
|
|
100
|
+
*/
|
|
101
|
+
export interface IAudioNormalizationConfig {
|
|
102
|
+
readonly lufs: number;
|
|
103
|
+
readonly peak: number;
|
|
104
|
+
readonly targetLufs?: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Конфигурация эквалайзера — отображение частота (Гц) → усиление (дБ).
|
|
108
|
+
* Передаётся при создании для определения доступных частотных полос.
|
|
109
|
+
*
|
|
110
|
+
* const config: IAudioEqualizerConfig = { 60: 0, 250: 0, 1000: 0, 8000: 0 };
|
|
111
|
+
*/
|
|
112
|
+
export interface IAudioEqualizerConfig {
|
|
113
|
+
readonly [frequency: number]: number;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Отдельная частотная полоса в эквалайзере.
|
|
117
|
+
* `value` отражает текущее усиление в дБ; `set` обновляет его,
|
|
118
|
+
* `reset` возвращает к значению по умолчанию.
|
|
119
|
+
*/
|
|
120
|
+
export interface IAudioEqualizerFilter {
|
|
121
|
+
readonly frequency: number;
|
|
122
|
+
readonly value: number;
|
|
123
|
+
set(value: number): void;
|
|
124
|
+
reset(): void;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Эквалайзер — набор частотных полос, индексированных по центральной
|
|
128
|
+
* частоте в Гц.
|
|
129
|
+
*/
|
|
130
|
+
export interface IAudioEqualizer {
|
|
131
|
+
readonly [frequency: number]: IAudioEqualizerFilter;
|
|
132
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const clearVideoElement: (video: HTMLMediaElement
|
|
1
|
+
export declare const clearVideoElement: (video: HTMLMediaElement) => void;
|