dasha 4.0.0-alpha.9 → 4.0.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/README.md +73 -21
- package/dist/index.d.mts +491 -0
- package/dist/index.mjs +1751 -0
- package/package.json +24 -35
- package/dist/dasha.cjs +0 -1628
- package/dist/dasha.d.cts +0 -392
- package/dist/dasha.d.mts +0 -392
- package/dist/dasha.mjs +0 -1576
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/dasha)
|
|
5
5
|
[](https://www.npmjs.com/package/dasha)
|
|
6
6
|
|
|
7
|
-
Library for
|
|
7
|
+
Library for working with MPEG-DASH (`.mpd`) and HLS (`.m3u8`) manifests through a mediabunny-compatible `Input` API. Made with the purpose of obtaining a simplified representation convenient for further downloading of segments by URLs and getting basic metadata about the tracks.
|
|
8
8
|
|
|
9
9
|
> [!WARNING]
|
|
10
10
|
> This README is for the alpha version. Info about latest stable version is available on [NPM](https://www.npmjs.com/package/dasha/v/3.1.5) or [another GitHub branch](https://github.com/azot-labs/dasha/tree/v3).
|
|
@@ -13,34 +13,86 @@ Library for parsing MPEG-DASH (.mpd) and HLS (.m3u8) manifests. Made with the pu
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
15
15
|
```shell
|
|
16
|
-
npm
|
|
16
|
+
npm install dasha@alpha
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
### HLS
|
|
22
|
+
|
|
23
|
+
```ts
|
|
22
24
|
import fs from 'node:fs/promises';
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
import { desc, HLS_FORMATS, Input, UrlSource } from 'dasha';
|
|
26
|
+
|
|
27
|
+
async function saveVideo() {
|
|
28
|
+
const input = new Input({
|
|
29
|
+
source: new UrlSource(
|
|
30
|
+
'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8',
|
|
31
|
+
{ requestInit: { headers: { Referer: 'https://bitmovin.com/' } } },
|
|
32
|
+
),
|
|
33
|
+
formats: HLS_FORMATS,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const videoTracks = await input.getVideoTracks({
|
|
37
|
+
sortBy: async (track) => [
|
|
38
|
+
desc(await track.getDisplayHeight()),
|
|
39
|
+
// Tracks with matching resolution are sorted by bitrate
|
|
40
|
+
desc(await track.getBitrate()),
|
|
41
|
+
],
|
|
42
|
+
// Filter out #EXT-X-I-FRAME-STREAM-INF tracks
|
|
43
|
+
filter: async (track) => !(await track.hasOnlyKeyPackets()),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const bestVideoTrack = videoTracks[0];
|
|
47
|
+
|
|
48
|
+
const segments = await bestVideoTrack.getSegments();
|
|
49
|
+
|
|
50
|
+
const outputPath = 'output.mp4';
|
|
51
|
+
const urls = segments.map((segment) => segment.location.path);
|
|
52
|
+
const initSegment = segments[0]?.initSegment;
|
|
53
|
+
if (initSegment) urls.unshift(initSegment.location.path);
|
|
54
|
+
for (const url of urls) {
|
|
55
|
+
const content = await fetch(url).then((res) => res.arrayBuffer());
|
|
56
|
+
await fs.appendFile(outputPath, new Uint8Array(content));
|
|
36
57
|
}
|
|
37
|
-
}
|
|
58
|
+
};
|
|
38
59
|
```
|
|
39
60
|
|
|
40
|
-
|
|
61
|
+
### DASH
|
|
41
62
|
|
|
42
|
-
|
|
63
|
+
```ts
|
|
64
|
+
import fs from 'node:fs/promises';
|
|
65
|
+
import { DASH_FORMATS, Input, UrlSource, desc } from 'dasha';
|
|
43
66
|
|
|
44
|
-
|
|
67
|
+
async function saveDashVideo() {
|
|
68
|
+
const input = new Input({
|
|
69
|
+
source: new UrlSource(
|
|
70
|
+
'https://dash.akamaized.net/dash264/TestCases/1a/netflix/exMPD_BIP_TC1.mpd',
|
|
71
|
+
),
|
|
72
|
+
formats: DASH_FORMATS,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const videoTracks = await input.getVideoTracks({
|
|
76
|
+
sortBy: async (track) => [
|
|
77
|
+
desc(await track.getDisplayHeight()),
|
|
78
|
+
desc(await track.getBitrate()),
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const bestVideoTrack = videoTracks[0];
|
|
83
|
+
const segments = await bestVideoTrack.getSegments();
|
|
84
|
+
|
|
85
|
+
const outputPath = 'output.m4s';
|
|
86
|
+
const urls = segments.map((segment) => segment.location.path);
|
|
87
|
+
const initSegment = segments[0]?.initSegment;
|
|
88
|
+
if (initSegment) urls.unshift(initSegment.location.path);
|
|
89
|
+
for (const url of urls) {
|
|
90
|
+
const content = await fetch(url).then((res) => res.arrayBuffer());
|
|
91
|
+
await fs.appendFile(outputPath, new Uint8Array(content));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Credits
|
|
45
97
|
|
|
46
|
-
|
|
98
|
+
[mediabunny](https://github.com/Vanilagy/mediabunny)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import * as _$mediabunny from "mediabunny";
|
|
2
|
+
import { AudioCodec, DurationMetadataRequestOptions, EncodedPacket, FilePathSource, HLS_FORMATS, Input as Input$1, InputAudioTrack as InputAudioTrack$1, InputFormat, InputOptions, InputTrack as InputTrack$2, InputTrackQuery, InputTrackQuery as InputTrackQuery$1, InputVideoTrack as InputVideoTrack$1, MediaCodec, MetadataTags, PacketRetrievalOptions, Source, TrackDisposition, UrlSource, VideoCodec, asc, desc, prefer } from "mediabunny";
|
|
3
|
+
import { Element } from "@xmldom/xmldom";
|
|
4
|
+
|
|
5
|
+
//#region src/mediabunny.d.ts
|
|
6
|
+
type Segment$1 = {
|
|
7
|
+
timestamp: number;
|
|
8
|
+
duration: number;
|
|
9
|
+
relativeToUnixEpoch: boolean;
|
|
10
|
+
firstSegment: Segment$1 | null;
|
|
11
|
+
};
|
|
12
|
+
type HlsSegmentLocation = {
|
|
13
|
+
path: string;
|
|
14
|
+
offset: number;
|
|
15
|
+
length: number | null;
|
|
16
|
+
};
|
|
17
|
+
type HlsEncryptionInfo = {
|
|
18
|
+
method: 'AES-128';
|
|
19
|
+
keyUri: string;
|
|
20
|
+
iv: Uint8Array | null;
|
|
21
|
+
keyFormat: string;
|
|
22
|
+
} | {
|
|
23
|
+
method: 'SAMPLE-AES' | 'SAMPLE-AES-CTR';
|
|
24
|
+
};
|
|
25
|
+
type HlsSegment = Segment$1 & {
|
|
26
|
+
sequenceNumber: number | null;
|
|
27
|
+
location: HlsSegmentLocation;
|
|
28
|
+
encryption: HlsEncryptionInfo | null;
|
|
29
|
+
firstSegment: HlsSegment | null;
|
|
30
|
+
initSegment: HlsSegment | null;
|
|
31
|
+
lastProgramDateTimeSeconds: number | null;
|
|
32
|
+
};
|
|
33
|
+
type HlsSegmentedInput = {
|
|
34
|
+
segments: HlsSegment[];
|
|
35
|
+
runUpdateSegments(): Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
type InputTrackWithBacking = InputTrack & {
|
|
38
|
+
_backing: {
|
|
39
|
+
internalTrack: {
|
|
40
|
+
fullPath: string;
|
|
41
|
+
demuxer: {
|
|
42
|
+
getSegmentedInputForPath(path: string): HlsSegmentedInput;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/codec.d.ts
|
|
49
|
+
/**
|
|
50
|
+
* List of known video codecs, ordered by encoding preference.
|
|
51
|
+
* @group Codecs
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
declare const VIDEO_CODECS: readonly ["avc", "hevc", "vp8", "vp9", "av1", "vc1"];
|
|
55
|
+
/**
|
|
56
|
+
* List of known video dynamic ranges.
|
|
57
|
+
* @group Codecs
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
declare const VIDEO_DYNAMIC_RANGES: readonly ["sdr", "hlg", "hdr10", "hdr10+", "dv"];
|
|
61
|
+
/**
|
|
62
|
+
* List of known audio codecs, ordered by encoding preference.
|
|
63
|
+
* @group Codecs
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
declare const AUDIO_CODECS: readonly ["aac", "opus", "mp3", "vorbis", "flac", "alac", "ac3", "eac3", "dts"];
|
|
67
|
+
/**
|
|
68
|
+
* List of known subtitle codecs, ordered by encoding preference.
|
|
69
|
+
* @group Codecs
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
declare const SUBTITLE_CODECS: readonly ["srt", "vtt", "ttml", "dfxp", "ssa", "ass", "stpp", "wvtt"];
|
|
73
|
+
/**
|
|
74
|
+
* Union type of known video codecs.
|
|
75
|
+
* @group Codecs
|
|
76
|
+
* @public
|
|
77
|
+
*/
|
|
78
|
+
type VideoCodec$1 = (typeof VIDEO_CODECS)[number];
|
|
79
|
+
/**
|
|
80
|
+
* Union type of known video dynamic ranges.
|
|
81
|
+
* @group Codecs
|
|
82
|
+
* @public
|
|
83
|
+
*/
|
|
84
|
+
type VideoDynamicRange = (typeof VIDEO_DYNAMIC_RANGES)[number];
|
|
85
|
+
/**
|
|
86
|
+
* Union type of known audio codecs.
|
|
87
|
+
* @group Codecs
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
90
|
+
type AudioCodec$1 = (typeof AUDIO_CODECS)[number];
|
|
91
|
+
/**
|
|
92
|
+
* Union type of known subtitle codecs.
|
|
93
|
+
* @group Codecs
|
|
94
|
+
* @public
|
|
95
|
+
*/
|
|
96
|
+
type SubtitleCodec = (typeof SUBTITLE_CODECS)[number];
|
|
97
|
+
/**
|
|
98
|
+
* Union type of known media codecs.
|
|
99
|
+
* @group Codecs
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
type MediaCodec$1 = VideoCodec$1 | AudioCodec$1 | SubtitleCodec;
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/role-type.d.ts
|
|
105
|
+
declare const ROLE_TYPE: {
|
|
106
|
+
Subtitle: number;
|
|
107
|
+
Main: number;
|
|
108
|
+
Alternate: number;
|
|
109
|
+
Supplementary: number;
|
|
110
|
+
Commentary: number;
|
|
111
|
+
Dub: number;
|
|
112
|
+
Description: number;
|
|
113
|
+
Sign: number;
|
|
114
|
+
Metadata: number;
|
|
115
|
+
ForcedSubtitle: number;
|
|
116
|
+
};
|
|
117
|
+
type RoleType = (typeof ROLE_TYPE)[keyof typeof ROLE_TYPE];
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/dash/dash-misc.d.ts
|
|
120
|
+
type DashTrackType = 'video' | 'audio' | 'subtitle';
|
|
121
|
+
type DashEncryptionData = {
|
|
122
|
+
method: string;
|
|
123
|
+
key?: Uint8Array;
|
|
124
|
+
iv?: Uint8Array;
|
|
125
|
+
drm: {
|
|
126
|
+
widevine?: {
|
|
127
|
+
keyId?: string;
|
|
128
|
+
pssh?: string;
|
|
129
|
+
};
|
|
130
|
+
playready?: {
|
|
131
|
+
keyId?: string;
|
|
132
|
+
pssh?: string;
|
|
133
|
+
};
|
|
134
|
+
fairplay?: {
|
|
135
|
+
keyId?: string;
|
|
136
|
+
pssh?: string;
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
type DashParsedSegment = {
|
|
141
|
+
sequenceNumber: number | null;
|
|
142
|
+
timestamp?: number;
|
|
143
|
+
duration: number;
|
|
144
|
+
url: string;
|
|
145
|
+
startRange?: number;
|
|
146
|
+
expectLength?: number;
|
|
147
|
+
encryption: DashEncryptionData | null;
|
|
148
|
+
};
|
|
149
|
+
type DashTrackCommon = {
|
|
150
|
+
type: DashTrackType;
|
|
151
|
+
codec?: MediaCodec$1;
|
|
152
|
+
codecString: string | null;
|
|
153
|
+
languageCode?: string;
|
|
154
|
+
peakBitrate: number | null;
|
|
155
|
+
averageBitrate: number | null;
|
|
156
|
+
name: string | null;
|
|
157
|
+
default: boolean;
|
|
158
|
+
role?: RoleType;
|
|
159
|
+
groupId: string | null;
|
|
160
|
+
audioGroupId?: string;
|
|
161
|
+
subtitleGroupId?: string;
|
|
162
|
+
periodId: string | null;
|
|
163
|
+
extension: string | null;
|
|
164
|
+
isLive: boolean;
|
|
165
|
+
refreshIntervalMs: number;
|
|
166
|
+
initSegment: DashParsedSegment | null;
|
|
167
|
+
mediaSegments: DashParsedSegment[];
|
|
168
|
+
};
|
|
169
|
+
type DashParsedVideoTrack = DashTrackCommon & {
|
|
170
|
+
type: 'video';
|
|
171
|
+
width?: number;
|
|
172
|
+
height?: number;
|
|
173
|
+
frameRate?: number;
|
|
174
|
+
dynamicRange?: VideoDynamicRange;
|
|
175
|
+
};
|
|
176
|
+
type DashParsedAudioTrack = DashTrackCommon & {
|
|
177
|
+
type: 'audio';
|
|
178
|
+
numberOfChannels?: number;
|
|
179
|
+
sampleRate?: number;
|
|
180
|
+
descriptive?: boolean;
|
|
181
|
+
joc?: number;
|
|
182
|
+
};
|
|
183
|
+
type DashParsedSubtitleTrack = DashTrackCommon & {
|
|
184
|
+
type: 'subtitle';
|
|
185
|
+
cc?: boolean;
|
|
186
|
+
sdh?: boolean;
|
|
187
|
+
forced?: boolean;
|
|
188
|
+
};
|
|
189
|
+
type DashParsedTrack = DashParsedVideoTrack | DashParsedAudioTrack | DashParsedSubtitleTrack;
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/dash/dash-segmented-input.d.ts
|
|
192
|
+
type Segment = {
|
|
193
|
+
timestamp: number;
|
|
194
|
+
duration: number;
|
|
195
|
+
relativeToUnixEpoch: boolean;
|
|
196
|
+
};
|
|
197
|
+
type DashSegmentLocation = {
|
|
198
|
+
path: string;
|
|
199
|
+
offset: number;
|
|
200
|
+
length: number | null;
|
|
201
|
+
};
|
|
202
|
+
type DashEncryptionInfo = DashEncryptionData;
|
|
203
|
+
type DashSegment = Segment & {
|
|
204
|
+
sequenceNumber: number | null;
|
|
205
|
+
location: DashSegmentLocation;
|
|
206
|
+
encryption: DashEncryptionInfo | null;
|
|
207
|
+
firstSegment: DashSegment | null;
|
|
208
|
+
initSegment: DashSegment | null;
|
|
209
|
+
lastProgramDateTimeSeconds: number | null;
|
|
210
|
+
};
|
|
211
|
+
type SegmentRetrievalOptions = {
|
|
212
|
+
skipLiveWait?: boolean;
|
|
213
|
+
};
|
|
214
|
+
type TrackWithBacking = InputTrack$2 & {
|
|
215
|
+
_backing: {
|
|
216
|
+
getDecoderConfig(): Promise<VideoDecoderConfig | AudioDecoderConfig | null>;
|
|
217
|
+
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
218
|
+
getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
219
|
+
getNextPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
220
|
+
getKeyPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
221
|
+
getNextKeyPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
222
|
+
getHasOnlyKeyPackets?(): boolean | null | Promise<boolean | null>;
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
type PacketInfo = {
|
|
226
|
+
segment: DashSegment;
|
|
227
|
+
track: TrackWithBacking;
|
|
228
|
+
sourcePacket: EncodedPacket;
|
|
229
|
+
};
|
|
230
|
+
declare class DashSegmentedInput {
|
|
231
|
+
internalTrack: DashInternalTrack;
|
|
232
|
+
demuxer: DashInternalTrack['demuxer'];
|
|
233
|
+
segments: DashSegment[];
|
|
234
|
+
currentUpdateSegmentsPromise: Promise<void> | null;
|
|
235
|
+
lastSegmentUpdateTime: number;
|
|
236
|
+
nextInputCacheAge: number;
|
|
237
|
+
inputCache: {
|
|
238
|
+
age: number;
|
|
239
|
+
input: Input$1;
|
|
240
|
+
segment: DashSegment;
|
|
241
|
+
}[];
|
|
242
|
+
firstTrackPromise: Promise<TrackWithBacking> | null;
|
|
243
|
+
packetInfos: WeakMap<EncodedPacket, PacketInfo>;
|
|
244
|
+
firstSegmentFirstTimestamps: WeakMap<DashSegment, number>;
|
|
245
|
+
firstTimestampCache: WeakMap<Input$1<_$mediabunny.Source>, number>;
|
|
246
|
+
constructor(internalTrack: DashInternalTrack);
|
|
247
|
+
runUpdateSegments(): Promise<void>;
|
|
248
|
+
updateSegments(): Promise<void>;
|
|
249
|
+
getRemainingWaitTimeMs(): number;
|
|
250
|
+
getFirstSegment(): Promise<DashSegment>;
|
|
251
|
+
getSegmentAt(timestamp: number, options: SegmentRetrievalOptions): Promise<DashSegment | null>;
|
|
252
|
+
getNextSegmentIndex(segment: DashSegment): number;
|
|
253
|
+
getNextSegment(segment: DashSegment, options: SegmentRetrievalOptions): Promise<DashSegment | null>;
|
|
254
|
+
getPreviousSegment(segment: DashSegment): Promise<DashSegment>;
|
|
255
|
+
getInputForSegment(segment: DashSegment): Input$1;
|
|
256
|
+
getTrackForSegment(segment: DashSegment): Promise<TrackWithBacking | null>;
|
|
257
|
+
getFirstTrack(): Promise<TrackWithBacking>;
|
|
258
|
+
getFirstTimestampForInput(input: Input$1): Promise<number>;
|
|
259
|
+
getMediaOffset(segment: DashSegment, input: Input$1, track: InputTrack$2): Promise<number>;
|
|
260
|
+
createAdjustedPacket(packet: EncodedPacket, segment: DashSegment, track: TrackWithBacking): Promise<EncodedPacket>;
|
|
261
|
+
getDecoderConfig(): Promise<VideoDecoderConfig | AudioDecoderConfig | null>;
|
|
262
|
+
getHasOnlyKeyPackets(): Promise<boolean | null>;
|
|
263
|
+
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
264
|
+
getNextPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
265
|
+
getNextKeyPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
266
|
+
getNextPacketInternal(packet: EncodedPacket, options: PacketRetrievalOptions, keyframesOnly: boolean): Promise<EncodedPacket | null>;
|
|
267
|
+
getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
268
|
+
getKeyPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
269
|
+
getPacketInternal(timestamp: number, options: PacketRetrievalOptions, keyframesOnly: boolean): Promise<EncodedPacket | null>;
|
|
270
|
+
getLiveRefreshInterval(): Promise<number | null>;
|
|
271
|
+
}
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region src/dash/dash-demuxer.d.ts
|
|
274
|
+
type DashManifestInfo = {
|
|
275
|
+
mpdElement: Element;
|
|
276
|
+
isLive: boolean;
|
|
277
|
+
availabilityStartTime: string | null;
|
|
278
|
+
timeShiftBufferDepth: string;
|
|
279
|
+
mediaPresentationDuration: string | null;
|
|
280
|
+
};
|
|
281
|
+
type DashTrackInfo = {
|
|
282
|
+
type: 'video';
|
|
283
|
+
width: number | null;
|
|
284
|
+
height: number | null;
|
|
285
|
+
} | {
|
|
286
|
+
type: 'audio';
|
|
287
|
+
numberOfChannels: number | null;
|
|
288
|
+
} | {
|
|
289
|
+
type: 'subtitle';
|
|
290
|
+
};
|
|
291
|
+
type InternalTrack = {
|
|
292
|
+
id: number;
|
|
293
|
+
demuxer: DashDemuxer;
|
|
294
|
+
backingTrack: DashInputTrackBacking | null;
|
|
295
|
+
pairingMask: bigint;
|
|
296
|
+
track: DashParsedTrack;
|
|
297
|
+
info: DashTrackInfo;
|
|
298
|
+
};
|
|
299
|
+
type InternalVideoTrack = InternalTrack & {
|
|
300
|
+
info: Extract<DashTrackInfo, {
|
|
301
|
+
type: 'video';
|
|
302
|
+
}>;
|
|
303
|
+
track: Extract<DashParsedTrack, {
|
|
304
|
+
type: 'video';
|
|
305
|
+
}>;
|
|
306
|
+
};
|
|
307
|
+
type InternalAudioTrack = InternalTrack & {
|
|
308
|
+
info: Extract<DashTrackInfo, {
|
|
309
|
+
type: 'audio';
|
|
310
|
+
}>;
|
|
311
|
+
track: Extract<DashParsedTrack, {
|
|
312
|
+
type: 'audio';
|
|
313
|
+
}>;
|
|
314
|
+
};
|
|
315
|
+
type InternalSubtitleTrack = InternalTrack & {
|
|
316
|
+
info: Extract<DashTrackInfo, {
|
|
317
|
+
type: 'subtitle';
|
|
318
|
+
}>;
|
|
319
|
+
track: Extract<DashParsedTrack, {
|
|
320
|
+
type: 'subtitle';
|
|
321
|
+
}>;
|
|
322
|
+
};
|
|
323
|
+
type DashInternalTrack = InternalTrack;
|
|
324
|
+
declare class DashDemuxer {
|
|
325
|
+
input: Input$1;
|
|
326
|
+
metadataPromise: Promise<void> | null;
|
|
327
|
+
trackBackings: DashInputTrackBacking[] | null;
|
|
328
|
+
internalTracks: InternalTrack[] | null;
|
|
329
|
+
segmentedInputs: DashSegmentedInput[];
|
|
330
|
+
manifestUrl: string;
|
|
331
|
+
originalUrl: string;
|
|
332
|
+
headers: Record<string, string>;
|
|
333
|
+
mpdUrl: string;
|
|
334
|
+
baseUrl: string;
|
|
335
|
+
constructor(input: Input$1);
|
|
336
|
+
readMetadata(): Promise<void>;
|
|
337
|
+
getTrackBackings(): Promise<DashInputTrackBacking[]>;
|
|
338
|
+
getSegmentedInputForTrack(track: DashInternalTrack): DashSegmentedInput;
|
|
339
|
+
refreshTrackSegments(track: DashInternalTrack): Promise<void>;
|
|
340
|
+
getMimeType(): Promise<string>;
|
|
341
|
+
getMetadataTags(): Promise<MetadataTags>;
|
|
342
|
+
dispose(): void;
|
|
343
|
+
extractTracks(rawText: string): DashParsedTrack[];
|
|
344
|
+
parseManifest(rawText: string): DashManifestInfo;
|
|
345
|
+
appendPeriodTracks(tracks: DashParsedTrack[], manifest: DashManifestInfo, period: Element): void;
|
|
346
|
+
appendAdaptationSetTracks(params: {
|
|
347
|
+
tracks: DashParsedTrack[];
|
|
348
|
+
manifest: DashManifestInfo;
|
|
349
|
+
period: Element;
|
|
350
|
+
periodDurationSeconds: number;
|
|
351
|
+
periodBaseUrl: string;
|
|
352
|
+
adaptationSet: Element;
|
|
353
|
+
}): void;
|
|
354
|
+
createTrack(params: {
|
|
355
|
+
adaptationSet: Element;
|
|
356
|
+
representation: Element;
|
|
357
|
+
period: Element;
|
|
358
|
+
manifest: DashManifestInfo;
|
|
359
|
+
bitrate: number;
|
|
360
|
+
contentType: string | null;
|
|
361
|
+
mimeType: string | null;
|
|
362
|
+
frameRate: number | undefined;
|
|
363
|
+
}): DashParsedTrack;
|
|
364
|
+
populateTrackSegments(params: {
|
|
365
|
+
adaptationSet: Element;
|
|
366
|
+
period: Element;
|
|
367
|
+
representation: Element;
|
|
368
|
+
track: DashParsedTrack;
|
|
369
|
+
manifest: DashManifestInfo;
|
|
370
|
+
segmentBaseUrl: string;
|
|
371
|
+
periodDurationSeconds: number;
|
|
372
|
+
bitrate: number;
|
|
373
|
+
}): void;
|
|
374
|
+
findMatchingTrack(nextTracks: DashParsedTrack[], currentTrack: DashParsedTrack): DashParsedTrack | undefined;
|
|
375
|
+
refreshTracks(tracks: DashParsedTrack[]): Promise<void>;
|
|
376
|
+
fetchManifest(url: string): Promise<Response>;
|
|
377
|
+
resetManifestUrls(): void;
|
|
378
|
+
}
|
|
379
|
+
declare abstract class DashTrackBackingBase {
|
|
380
|
+
internalTrack: InternalTrack;
|
|
381
|
+
hydratedTrackPromise: Promise<any> | null;
|
|
382
|
+
constructor(internalTrack: InternalTrack);
|
|
383
|
+
abstract getType(): 'video' | 'audio' | 'subtitle';
|
|
384
|
+
hydrate(): Promise<any>;
|
|
385
|
+
delegate<T>(fn: (track: any) => T | Promise<T>): Promise<T>;
|
|
386
|
+
getId(): number;
|
|
387
|
+
getNumber(): number;
|
|
388
|
+
getCodec(): MediaCodec | null;
|
|
389
|
+
getInternalCodecId(): null;
|
|
390
|
+
getName(): string | null;
|
|
391
|
+
getLanguageCode(): string;
|
|
392
|
+
getTimeResolution(): Promise<any>;
|
|
393
|
+
isRelativeToUnixEpoch(): boolean;
|
|
394
|
+
getDisposition(): TrackDisposition;
|
|
395
|
+
getPairingMask(): bigint;
|
|
396
|
+
getBitrate(): number | null;
|
|
397
|
+
getAverageBitrate(): number | null;
|
|
398
|
+
getDurationFromMetadata(_options: DurationMetadataRequestOptions): Promise<number>;
|
|
399
|
+
getLiveRefreshInterval(): Promise<number | null>;
|
|
400
|
+
getHasOnlyKeyPackets(): boolean;
|
|
401
|
+
getDecoderConfig(): Promise<VideoDecoderConfig | AudioDecoderConfig | null>;
|
|
402
|
+
getMetadataCodecParameterString(): string | null;
|
|
403
|
+
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
404
|
+
getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
405
|
+
getNextPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
406
|
+
getKeyPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
407
|
+
getNextKeyPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
|
408
|
+
getSegmentedInput(): DashSegmentedInput;
|
|
409
|
+
getSegments(): Promise<DashSegment[]>;
|
|
410
|
+
}
|
|
411
|
+
declare class DashInputVideoTrackBacking extends DashTrackBackingBase {
|
|
412
|
+
internalTrack: InternalVideoTrack;
|
|
413
|
+
constructor(internalTrack: InternalVideoTrack);
|
|
414
|
+
getType(): "video";
|
|
415
|
+
getCodec(): VideoCodec | null;
|
|
416
|
+
getCodedWidth(): number | Promise<any>;
|
|
417
|
+
getCodedHeight(): number | Promise<any>;
|
|
418
|
+
getSquarePixelWidth(): number | Promise<any>;
|
|
419
|
+
getSquarePixelHeight(): number | Promise<any>;
|
|
420
|
+
getMetadataDisplayWidth(): number | null;
|
|
421
|
+
getMetadataDisplayHeight(): number | null;
|
|
422
|
+
getRotation(): number;
|
|
423
|
+
getColorSpace(): Promise<VideoColorSpaceInit>;
|
|
424
|
+
canBeTransparent(): Promise<any>;
|
|
425
|
+
}
|
|
426
|
+
declare class DashInputAudioTrackBacking extends DashTrackBackingBase {
|
|
427
|
+
internalTrack: InternalAudioTrack;
|
|
428
|
+
constructor(internalTrack: InternalAudioTrack);
|
|
429
|
+
getType(): "audio";
|
|
430
|
+
getCodec(): AudioCodec | null;
|
|
431
|
+
getNumberOfChannels(): number | Promise<any>;
|
|
432
|
+
getSampleRate(): number | Promise<any>;
|
|
433
|
+
}
|
|
434
|
+
declare class DashInputSubtitleTrackBacking extends DashTrackBackingBase {
|
|
435
|
+
internalTrack: InternalSubtitleTrack;
|
|
436
|
+
constructor(internalTrack: InternalSubtitleTrack);
|
|
437
|
+
getType(): "subtitle";
|
|
438
|
+
}
|
|
439
|
+
type DashInputTrackBacking = DashInputVideoTrackBacking | DashInputAudioTrackBacking | DashInputSubtitleTrackBacking;
|
|
440
|
+
declare class DashInputFormat extends InputFormat {
|
|
441
|
+
get name(): string;
|
|
442
|
+
get mimeType(): string;
|
|
443
|
+
_canReadInput(input: Input$1): Promise<boolean>;
|
|
444
|
+
_createDemuxer(input: Input$1): DashDemuxer;
|
|
445
|
+
}
|
|
446
|
+
declare const DASH: DashInputFormat;
|
|
447
|
+
declare const DASH_FORMATS: InputFormat[];
|
|
448
|
+
//#endregion
|
|
449
|
+
//#region src/mediabunny-input.d.ts
|
|
450
|
+
declare module 'mediabunny' {
|
|
451
|
+
interface Input<S extends Source = Source> {
|
|
452
|
+
_getTrackBackings(): Promise<unknown[]>;
|
|
453
|
+
_wrapBackingAsTrack(backing: unknown): InputTrack$2;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
type SegmentAccessMethods = {
|
|
457
|
+
getSegmentedInput(): HlsSegmentedInput | DashSegmentedInput;
|
|
458
|
+
getSegments(): Promise<(HlsSegment | DashSegment)[]>;
|
|
459
|
+
};
|
|
460
|
+
type MediabunnyTrackWithSegments = InputTrack$2 & SegmentAccessMethods;
|
|
461
|
+
type MediabunnyVideoTrackWithSegments = InputVideoTrack$1 & SegmentAccessMethods;
|
|
462
|
+
type MediabunnyAudioTrackWithSegments = InputAudioTrack$1 & SegmentAccessMethods;
|
|
463
|
+
type TrackBacking = Parameters<Input$1<Source>['_wrapBackingAsTrack']>[0];
|
|
464
|
+
declare const preserveSubtitleBackingsOnInput: (input: Input$1) => Input$1<Source>;
|
|
465
|
+
declare class SegmentedMediabunnyInput<S extends Source = Source> extends Input$1<S> {
|
|
466
|
+
#private;
|
|
467
|
+
_wrapBackingAsTrack(backing: TrackBacking): MediabunnyTrackWithSegments;
|
|
468
|
+
getTracks(query?: InputTrackQuery$1<MediabunnyTrackWithSegments>): Promise<MediabunnyTrackWithSegments[]>;
|
|
469
|
+
getVideoTracks(query?: InputTrackQuery$1<MediabunnyVideoTrackWithSegments>): Promise<MediabunnyVideoTrackWithSegments[]>;
|
|
470
|
+
getAudioTracks(query?: InputTrackQuery$1<MediabunnyAudioTrackWithSegments>): Promise<MediabunnyAudioTrackWithSegments[]>;
|
|
471
|
+
getPrimaryVideoTrack(query?: InputTrackQuery$1<MediabunnyVideoTrackWithSegments>): Promise<MediabunnyVideoTrackWithSegments | null>;
|
|
472
|
+
getPrimaryAudioTrack(query?: InputTrackQuery$1<MediabunnyAudioTrackWithSegments>): Promise<MediabunnyAudioTrackWithSegments | null>;
|
|
473
|
+
}
|
|
474
|
+
//#endregion
|
|
475
|
+
//#region src/index.d.ts
|
|
476
|
+
type DashaInputOptions<S extends Source = Source> = Omit<InputOptions<S>, 'formats'> & {
|
|
477
|
+
formats: readonly InputFormat[];
|
|
478
|
+
};
|
|
479
|
+
type InputSegment = HlsSegment | DashSegment;
|
|
480
|
+
type InputSegmentedInput = HlsSegmentedInput | DashSegmentedInput;
|
|
481
|
+
type InputTrack$1 = MediabunnyTrackWithSegments;
|
|
482
|
+
type InputVideoTrack = MediabunnyVideoTrackWithSegments;
|
|
483
|
+
type InputAudioTrack = MediabunnyAudioTrackWithSegments;
|
|
484
|
+
declare class Input<S extends Source = Source> extends SegmentedMediabunnyInput<S> {
|
|
485
|
+
constructor(options: DashaInputOptions<S>);
|
|
486
|
+
}
|
|
487
|
+
declare const isInput: (value: unknown) => value is Input;
|
|
488
|
+
declare const getSegmentedInput: (track: InputTrack$1) => InputSegmentedInput;
|
|
489
|
+
declare const getSegments: (track: InputTrack$1) => Promise<InputSegment[]>;
|
|
490
|
+
//#endregion
|
|
491
|
+
export { DASH, DASH_FORMATS, type DashSegment, type DashSegmentedInput, FilePathSource, HLS_FORMATS, type HlsSegment, type HlsSegmentedInput, Input, InputAudioTrack, InputSegment, InputSegmentedInput, InputTrack$1 as InputTrack, type InputTrackQuery, type InputTrackWithBacking, InputVideoTrack, UrlSource, asc, desc, getSegmentedInput, getSegments, isInput, prefer, preserveSubtitleBackingsOnInput };
|