dasha 4.3.1 → 4.4.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.
- package/dist/index.d.mts +58 -10
- package/dist/index.mjs +202 -7
- package/package.json +7 -7
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import * as _$mediabunny from "mediabunny";
|
|
2
1
|
import { AudioCodec as AudioCodec$1, DurationMetadataRequestOptions, EncodedPacket, FilePathSource, HLS, 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, MP3, MP4, MaybePromise, MediaCodec as MediaCodec$1, MetadataTags, PacketRetrievalOptions, PathedSource, Source, SourceRef, SubtitleCodec as SubtitleCodec$1, TrackDisposition, UrlSource, VideoCodec as VideoCodec$1, asc, desc, prefer } from "mediabunny";
|
|
3
|
-
import * as _$_xmldom_xmldom0 from "@xmldom/xmldom";
|
|
4
2
|
|
|
5
3
|
//#region src/mediabunny.d.ts
|
|
6
4
|
type Segment$1 = {
|
|
@@ -104,7 +102,7 @@ declare const ROLE_TYPE: {
|
|
|
104
102
|
type RoleType = (typeof ROLE_TYPE)[keyof typeof ROLE_TYPE];
|
|
105
103
|
//#endregion
|
|
106
104
|
//#region src/dash/dash-misc.d.ts
|
|
107
|
-
type Element =
|
|
105
|
+
type Element = import('@xmldom/xmldom').Element;
|
|
108
106
|
type DashTrackType = 'video' | 'audio' | 'subtitle';
|
|
109
107
|
type DashEncryptionData = {
|
|
110
108
|
method: string;
|
|
@@ -231,7 +229,7 @@ declare class DashSegmentedInput {
|
|
|
231
229
|
firstTrackPromise: Promise<TrackWithBacking> | null;
|
|
232
230
|
packetInfos: WeakMap<EncodedPacket, PacketInfo>;
|
|
233
231
|
firstSegmentFirstTimestamps: WeakMap<DashSegment, number>;
|
|
234
|
-
firstTimestampCache: WeakMap<Input$1<
|
|
232
|
+
firstTimestampCache: WeakMap<Input$1<import("mediabunny").Source>, number>;
|
|
235
233
|
constructor(internalTrack: DashInternalTrack);
|
|
236
234
|
runUpdateSegments(): Promise<void>;
|
|
237
235
|
updateSegments(): Promise<void>;
|
|
@@ -563,16 +561,19 @@ type SegmentAccessMethods = {
|
|
|
563
561
|
type TrackMetadataOverrideMethods = {
|
|
564
562
|
setLanguageCode(value: string): void;
|
|
565
563
|
};
|
|
564
|
+
type TrackSourceMethods = {
|
|
565
|
+
readonly source: Source;
|
|
566
|
+
};
|
|
566
567
|
type VideoDynamicRangeMethods = {
|
|
567
568
|
getDynamicRange(): Promise<VideoDynamicRange>;
|
|
568
569
|
};
|
|
569
570
|
type MediabunnySubtitleTrackLike = InputTrack$2 & {
|
|
570
571
|
type: 'subtitle';
|
|
571
572
|
};
|
|
572
|
-
type InputTrack$1 = InputTrack$2 & SegmentAccessMethods & TrackMetadataOverrideMethods;
|
|
573
|
-
type InputVideoTrack = InputVideoTrack$1 & SegmentAccessMethods & VideoDynamicRangeMethods & TrackMetadataOverrideMethods;
|
|
574
|
-
type InputAudioTrack = InputAudioTrack$1 & SegmentAccessMethods & TrackMetadataOverrideMethods;
|
|
575
|
-
type InputSubtitleTrack = MediabunnySubtitleTrackLike & SegmentAccessMethods & TrackMetadataOverrideMethods;
|
|
573
|
+
type InputTrack$1 = InputTrack$2 & SegmentAccessMethods & TrackMetadataOverrideMethods & TrackSourceMethods;
|
|
574
|
+
type InputVideoTrack = InputVideoTrack$1 & SegmentAccessMethods & VideoDynamicRangeMethods & TrackMetadataOverrideMethods & TrackSourceMethods;
|
|
575
|
+
type InputAudioTrack = InputAudioTrack$1 & SegmentAccessMethods & TrackMetadataOverrideMethods & TrackSourceMethods;
|
|
576
|
+
type InputSubtitleTrack = MediabunnySubtitleTrackLike & SegmentAccessMethods & TrackMetadataOverrideMethods & TrackSourceMethods;
|
|
576
577
|
type InputSubtitleSource = PathedSource | SourceRef<PathedSource>;
|
|
577
578
|
type InputSubtitleTrackMetadata = {
|
|
578
579
|
codec?: SubtitleCodec | null;
|
|
@@ -582,6 +583,14 @@ type InputSubtitleTrackMetadata = {
|
|
|
582
583
|
name?: string | null;
|
|
583
584
|
pairWith?: InputVideoTrack | Iterable<InputVideoTrack>;
|
|
584
585
|
};
|
|
586
|
+
type InputAudioSource = Source | SourceRef<Source>;
|
|
587
|
+
type InputAudioTrackPairing = InputVideoTrack | Iterable<InputVideoTrack> | 'all' | 'primary' | false;
|
|
588
|
+
type InputAudioTracksOptions = {
|
|
589
|
+
filter?: InputTrackQuery$1<InputAudioTrack>['filter'];
|
|
590
|
+
formats?: readonly InputFormat[];
|
|
591
|
+
pairWith?: InputAudioTrackPairing;
|
|
592
|
+
sortBy?: InputTrackQuery$1<InputAudioTrack>['sortBy'];
|
|
593
|
+
};
|
|
585
594
|
type SegmentableBacking = {
|
|
586
595
|
getId(): number;
|
|
587
596
|
getNumber(): number;
|
|
@@ -601,17 +610,54 @@ type SegmentableBacking = {
|
|
|
601
610
|
getDecoderConfig?(): Promise<VideoDecoderConfig | AudioDecoderConfig | null>;
|
|
602
611
|
getMetadataCodecParameterString?(): string | null | Promise<string | null>;
|
|
603
612
|
getSegmentedInput?(): HlsSegmentedInput | DashSegmentedInput;
|
|
613
|
+
getSource?(): Source;
|
|
604
614
|
};
|
|
605
615
|
type NativeTrackBacking = SegmentableBacking;
|
|
606
616
|
type TrackBacking = NativeTrackBacking | SegmentableBacking;
|
|
607
617
|
declare const BACKING_TYPE_SUBTITLE = "subtitle";
|
|
608
618
|
declare const BACKING_TYPE_AUDIO = "audio";
|
|
609
619
|
declare const BACKING_TYPE_VIDEO = "video";
|
|
620
|
+
declare class ImportedAudioTrackBacking {
|
|
621
|
+
#private;
|
|
622
|
+
constructor(params: {
|
|
623
|
+
backing: SegmentableBacking;
|
|
624
|
+
id: number;
|
|
625
|
+
number: number;
|
|
626
|
+
source: Source;
|
|
627
|
+
});
|
|
628
|
+
getType(): string;
|
|
629
|
+
getId(): number;
|
|
630
|
+
getNumber(): number;
|
|
631
|
+
getCodec(): MediaCodec$1 | Promise<MediaCodec$1 | null> | null;
|
|
632
|
+
getInternalCodecId(): string | number | Uint8Array<ArrayBufferLike> | Promise<string | number | Uint8Array<ArrayBufferLike> | null> | null;
|
|
633
|
+
getName(): string | Promise<string | null> | null;
|
|
634
|
+
getLanguageCode(): string | Promise<string>;
|
|
635
|
+
getTimeResolution(): number | Promise<number>;
|
|
636
|
+
isRelativeToUnixEpoch(): boolean | Promise<boolean>;
|
|
637
|
+
getDisposition(): {};
|
|
638
|
+
getPairingMask(): bigint;
|
|
639
|
+
getSource(): Source;
|
|
640
|
+
getBitrate(): number | Promise<number | null> | null;
|
|
641
|
+
getAverageBitrate(): number | Promise<number | null> | null;
|
|
642
|
+
getDurationFromMetadata(options: unknown): Promise<number | null>;
|
|
643
|
+
getLiveRefreshInterval(): Promise<number | null>;
|
|
644
|
+
getHasOnlyKeyPackets(): boolean;
|
|
645
|
+
getDecoderConfig(): Promise<VideoDecoderConfig | AudioDecoderConfig | null>;
|
|
646
|
+
getMetadataCodecParameterString(): string | Promise<string | null> | null;
|
|
647
|
+
getNumberOfChannels(): number | Promise<number>;
|
|
648
|
+
getSampleRate(): number | Promise<number>;
|
|
649
|
+
getFirstPacket(options: unknown): Promise<EncodedPacket | null>;
|
|
650
|
+
getPacket(timestamp: number, options: unknown): Promise<EncodedPacket | null>;
|
|
651
|
+
getNextPacket(packet: EncodedPacket, options: unknown): Promise<EncodedPacket | null>;
|
|
652
|
+
getKeyPacket(timestamp: number, options: unknown): Promise<EncodedPacket | null>;
|
|
653
|
+
getNextKeyPacket(packet: EncodedPacket, options: unknown): Promise<EncodedPacket | null>;
|
|
654
|
+
getSegmentedInput(): any;
|
|
655
|
+
}
|
|
610
656
|
declare const preserveSubtitleBackingsOnInput: (input: Input$1) => Input$1<Source>;
|
|
611
657
|
declare class SegmentedMediabunnyInput<S extends Source = Source> extends Input$1<S> {
|
|
612
658
|
#private;
|
|
613
659
|
_wrapBackingAsTrack(backing: TrackBacking): InputTrack$1;
|
|
614
|
-
_getSyntheticTrackBackings(type?: typeof BACKING_TYPE_VIDEO | typeof BACKING_TYPE_AUDIO | typeof BACKING_TYPE_SUBTITLE): Promise<(ExternalSubtitleTrackBacking | HlsSubtitleTrackBacking)[]>;
|
|
660
|
+
_getSyntheticTrackBackings(type?: typeof BACKING_TYPE_VIDEO | typeof BACKING_TYPE_AUDIO | typeof BACKING_TYPE_SUBTITLE): Promise<(ImportedAudioTrackBacking | ExternalSubtitleTrackBacking | HlsSubtitleTrackBacking)[]>;
|
|
615
661
|
getTracks(query?: InputTrackQuery$1<InputTrack$1>): Promise<InputTrack$1[]>;
|
|
616
662
|
getVideoTracks(query?: InputTrackQuery$1<InputVideoTrack>): Promise<InputVideoTrack[]>;
|
|
617
663
|
getAudioTracks(query?: InputTrackQuery$1<InputAudioTrack>): Promise<InputAudioTrack[]>;
|
|
@@ -619,6 +665,8 @@ declare class SegmentedMediabunnyInput<S extends Source = Source> extends Input$
|
|
|
619
665
|
getPrimaryVideoTrack(query?: InputTrackQuery$1<InputVideoTrack>): Promise<InputVideoTrack | null>;
|
|
620
666
|
getPrimaryAudioTrack(query?: InputTrackQuery$1<InputAudioTrack>): Promise<InputAudioTrack | null>;
|
|
621
667
|
addSubtitleTrack(source: InputSubtitleSource, metadata?: InputSubtitleTrackMetadata): InputSubtitleTrack;
|
|
668
|
+
addAudioTracks(source: InputAudioSource, options?: InputAudioTracksOptions): Promise<InputAudioTrack[]>;
|
|
669
|
+
dispose(): void;
|
|
622
670
|
}
|
|
623
671
|
//#endregion
|
|
624
672
|
//#region src/index.d.ts
|
|
@@ -633,4 +681,4 @@ declare class Input<S extends Source = Source> extends SegmentedMediabunnyInput<
|
|
|
633
681
|
declare const isInput: (value: unknown) => value is Input;
|
|
634
682
|
declare const ALL_FORMATS: InputFormat[];
|
|
635
683
|
//#endregion
|
|
636
|
-
export { ALL_FORMATS, type AudioCodec, DASH, DASH_FORMATS, type DashSegment, type DashSegmentedInput, FilePathSource, HLS, HLS_FORMATS, type HlsSegment, type HlsSegmentedInput, Input, type InputAudioTrack, InputSegment, InputSegmentedInput, type InputSubtitleSource, type InputSubtitleTrack, type InputSubtitleTrackMetadata, type InputTrack$1 as InputTrack, type InputTrackQuery, type InputTrackWithBacking, type InputVideoTrack, MP3, MP4, type MaybePromise, type MediaCodec, type SubtitleCodec, UrlSource, type VideoCodec, type VideoDynamicRange, asc, desc, isInput, prefer, preserveSubtitleBackingsOnInput };
|
|
684
|
+
export { ALL_FORMATS, type AudioCodec, DASH, DASH_FORMATS, type DashSegment, type DashSegmentedInput, FilePathSource, HLS, HLS_FORMATS, type HlsSegment, type HlsSegmentedInput, Input, type InputAudioSource, type InputAudioTrack, type InputAudioTrackPairing, type InputAudioTracksOptions, InputSegment, InputSegmentedInput, type InputSubtitleSource, type InputSubtitleTrack, type InputSubtitleTrackMetadata, type InputTrack$1 as InputTrack, type InputTrackQuery, type InputTrackWithBacking, type InputVideoTrack, MP3, MP4, type MaybePromise, type MediaCodec, type SubtitleCodec, UrlSource, type VideoCodec, type VideoDynamicRange, asc, desc, isInput, prefer, preserveSubtitleBackingsOnInput };
|
package/dist/index.mjs
CHANGED
|
@@ -1237,6 +1237,7 @@ const getHlsSubtitleTrackBackings = (input) => {
|
|
|
1237
1237
|
//#endregion
|
|
1238
1238
|
//#region src/mediabunny-input.ts
|
|
1239
1239
|
const CUSTOM_SUBTITLE_TRACK_ID_OFFSET = 1e9;
|
|
1240
|
+
const CUSTOM_AUDIO_TRACK_ID_OFFSET = 2e9;
|
|
1240
1241
|
const CUSTOM_PAIRING_BIT_START = 1024n;
|
|
1241
1242
|
const EXTRA_PAIRING_MASK = Symbol.for("dasha.extra-pairing-mask");
|
|
1242
1243
|
const ORIGINAL_GET_PAIRING_MASK = Symbol.for("dasha.original-get-pairing-mask");
|
|
@@ -1382,6 +1383,136 @@ const BACKING_TYPE_AUDIO = "audio";
|
|
|
1382
1383
|
const BACKING_TYPE_VIDEO = "video";
|
|
1383
1384
|
const BASE_INPUT_PATCHED = Symbol.for("dasha.base-mediabunny-input-patched");
|
|
1384
1385
|
const PRESERVE_SUBTITLE_BACKINGS = Symbol.for("dasha.preserve-subtitle-backings");
|
|
1386
|
+
const getDefaultAudioTrackFormats = (source) => {
|
|
1387
|
+
return isLikelyDashPath(source instanceof SourceRef ? source.source : source) ? [DASH, ...ALL_FORMATS$1] : [...ALL_FORMATS$1, DASH];
|
|
1388
|
+
};
|
|
1389
|
+
var WholeResourceAudioSegmentedInput = class {
|
|
1390
|
+
segments = [];
|
|
1391
|
+
#source;
|
|
1392
|
+
constructor(source) {
|
|
1393
|
+
this.#source = source;
|
|
1394
|
+
}
|
|
1395
|
+
async runUpdateSegments() {
|
|
1396
|
+
if (this.segments.length > 0) return;
|
|
1397
|
+
const sourceWithRootPath = this.#source;
|
|
1398
|
+
if (typeof sourceWithRootPath.rootPath !== "string") return;
|
|
1399
|
+
const segment = {
|
|
1400
|
+
timestamp: 0,
|
|
1401
|
+
duration: 0,
|
|
1402
|
+
relativeToUnixEpoch: false,
|
|
1403
|
+
firstSegment: null,
|
|
1404
|
+
sequenceNumber: 0,
|
|
1405
|
+
location: {
|
|
1406
|
+
path: sourceWithRootPath.rootPath,
|
|
1407
|
+
offset: 0,
|
|
1408
|
+
length: null
|
|
1409
|
+
},
|
|
1410
|
+
encryption: null,
|
|
1411
|
+
initSegment: null,
|
|
1412
|
+
lastProgramDateTimeSeconds: null
|
|
1413
|
+
};
|
|
1414
|
+
segment.firstSegment = segment;
|
|
1415
|
+
this.segments = [segment];
|
|
1416
|
+
}
|
|
1417
|
+
};
|
|
1418
|
+
var ImportedAudioTrackBacking = class {
|
|
1419
|
+
#backing;
|
|
1420
|
+
#id;
|
|
1421
|
+
#number;
|
|
1422
|
+
#source;
|
|
1423
|
+
#wholeResourceSegmentedInput;
|
|
1424
|
+
constructor(params) {
|
|
1425
|
+
this.#backing = params.backing;
|
|
1426
|
+
this.#id = params.id;
|
|
1427
|
+
this.#number = params.number;
|
|
1428
|
+
this.#source = params.source;
|
|
1429
|
+
this.#wholeResourceSegmentedInput = new WholeResourceAudioSegmentedInput(params.source);
|
|
1430
|
+
}
|
|
1431
|
+
getType() {
|
|
1432
|
+
return BACKING_TYPE_AUDIO;
|
|
1433
|
+
}
|
|
1434
|
+
getId() {
|
|
1435
|
+
return this.#id;
|
|
1436
|
+
}
|
|
1437
|
+
getNumber() {
|
|
1438
|
+
return this.#number;
|
|
1439
|
+
}
|
|
1440
|
+
getCodec() {
|
|
1441
|
+
return this.#backing.getCodec();
|
|
1442
|
+
}
|
|
1443
|
+
getInternalCodecId() {
|
|
1444
|
+
return this.#backing.getInternalCodecId?.() ?? null;
|
|
1445
|
+
}
|
|
1446
|
+
getName() {
|
|
1447
|
+
return this.#backing.getName?.() ?? null;
|
|
1448
|
+
}
|
|
1449
|
+
getLanguageCode() {
|
|
1450
|
+
return this.#backing.getLanguageCode?.() ?? "und";
|
|
1451
|
+
}
|
|
1452
|
+
getTimeResolution() {
|
|
1453
|
+
return this.#backing.getTimeResolution?.() ?? 1e3;
|
|
1454
|
+
}
|
|
1455
|
+
isRelativeToUnixEpoch() {
|
|
1456
|
+
return this.#backing.isRelativeToUnixEpoch?.() ?? false;
|
|
1457
|
+
}
|
|
1458
|
+
getDisposition() {
|
|
1459
|
+
return this.#backing.getDisposition?.() ?? {};
|
|
1460
|
+
}
|
|
1461
|
+
getPairingMask() {
|
|
1462
|
+
return 0n;
|
|
1463
|
+
}
|
|
1464
|
+
getSource() {
|
|
1465
|
+
return this.#source;
|
|
1466
|
+
}
|
|
1467
|
+
getBitrate() {
|
|
1468
|
+
return this.#backing.getBitrate?.() ?? null;
|
|
1469
|
+
}
|
|
1470
|
+
getAverageBitrate() {
|
|
1471
|
+
return this.#backing.getAverageBitrate?.() ?? null;
|
|
1472
|
+
}
|
|
1473
|
+
getDurationFromMetadata(options) {
|
|
1474
|
+
return this.#backing.getDurationFromMetadata?.(options) ?? Promise.resolve(null);
|
|
1475
|
+
}
|
|
1476
|
+
getLiveRefreshInterval() {
|
|
1477
|
+
return this.#backing.getLiveRefreshInterval?.() ?? Promise.resolve(null);
|
|
1478
|
+
}
|
|
1479
|
+
getHasOnlyKeyPackets() {
|
|
1480
|
+
return true;
|
|
1481
|
+
}
|
|
1482
|
+
getDecoderConfig() {
|
|
1483
|
+
return this.#backing.getDecoderConfig?.() ?? Promise.resolve(null);
|
|
1484
|
+
}
|
|
1485
|
+
getMetadataCodecParameterString() {
|
|
1486
|
+
return this.#backing.getMetadataCodecParameterString?.() ?? null;
|
|
1487
|
+
}
|
|
1488
|
+
getNumberOfChannels() {
|
|
1489
|
+
return this.#backing.getNumberOfChannels?.() ?? 0;
|
|
1490
|
+
}
|
|
1491
|
+
getSampleRate() {
|
|
1492
|
+
return this.#backing.getSampleRate?.() ?? 0;
|
|
1493
|
+
}
|
|
1494
|
+
getFirstPacket(options) {
|
|
1495
|
+
return this.#backing.getFirstPacket?.(options) ?? Promise.resolve(null);
|
|
1496
|
+
}
|
|
1497
|
+
getPacket(timestamp, options) {
|
|
1498
|
+
return this.#backing.getPacket?.(timestamp, options) ?? Promise.resolve(null);
|
|
1499
|
+
}
|
|
1500
|
+
getNextPacket(packet, options) {
|
|
1501
|
+
return this.#backing.getNextPacket?.(packet, options) ?? Promise.resolve(null);
|
|
1502
|
+
}
|
|
1503
|
+
getKeyPacket(timestamp, options) {
|
|
1504
|
+
return this.#backing.getKeyPacket?.(timestamp, options) ?? Promise.resolve(null);
|
|
1505
|
+
}
|
|
1506
|
+
getNextKeyPacket(packet, options) {
|
|
1507
|
+
return this.#backing.getNextKeyPacket?.(packet, options) ?? Promise.resolve(null);
|
|
1508
|
+
}
|
|
1509
|
+
getSegmentedInput() {
|
|
1510
|
+
if (this.#backing.getSegmentedInput) return this.#backing.getSegmentedInput();
|
|
1511
|
+
const hlsBacking = this.#backing;
|
|
1512
|
+
if (hlsBacking.internalTrack?.demuxer?.getSegmentedInputForPath) return hlsBacking.internalTrack.demuxer.getSegmentedInputForPath(hlsBacking.internalTrack.fullPath);
|
|
1513
|
+
return this.#wholeResourceSegmentedInput;
|
|
1514
|
+
}
|
|
1515
|
+
};
|
|
1385
1516
|
const getBackingType = (backing) => backing.getType?.();
|
|
1386
1517
|
const queryWrappedTracks = (input, backings, query) => {
|
|
1387
1518
|
return queryTracks(backings.map((backing) => input._wrapBackingAsTrack(backing)), query);
|
|
@@ -1414,6 +1545,9 @@ const getSegmentedInputForTrack = (track) => {
|
|
|
1414
1545
|
return internalTrack.demuxer.getSegmentedInputForPath(internalTrack.fullPath);
|
|
1415
1546
|
};
|
|
1416
1547
|
const getTrackBacking = (track) => track._backing;
|
|
1548
|
+
const getTrackSource = (track) => {
|
|
1549
|
+
return getTrackBacking(track).getSource?.() ?? track.input.source;
|
|
1550
|
+
};
|
|
1417
1551
|
const getTrackMetadataOverrides = (backing) => backing[TRACK_METADATA_OVERRIDES] ??= {};
|
|
1418
1552
|
const ensureLanguageCodeOverridePatch = (backing) => {
|
|
1419
1553
|
const patchedBacking = backing;
|
|
@@ -1426,6 +1560,7 @@ const setTrackLanguageCode = (track, value) => {
|
|
|
1426
1560
|
getTrackMetadataOverrides(ensureLanguageCodeOverridePatch(getTrackBacking(track))).languageCode = value;
|
|
1427
1561
|
};
|
|
1428
1562
|
const addSegmentAccess = (track) => new Proxy(track, { get(target, prop) {
|
|
1563
|
+
if (prop === "source") return getTrackSource(target);
|
|
1429
1564
|
if (prop === "getDynamicRange" && target instanceof InputVideoTrack) return () => getDynamicRangeForTrack(target);
|
|
1430
1565
|
if (prop === "setLanguageCode") return (value) => setTrackLanguageCode(target, value);
|
|
1431
1566
|
if (prop === "getSegmentedInput") return () => getSegmentedInputForTrack(target);
|
|
@@ -1479,13 +1614,17 @@ const preserveSubtitleBackingsOnInput = (input) => {
|
|
|
1479
1614
|
Object.assign(input, { [PRESERVE_SUBTITLE_BACKINGS]: true });
|
|
1480
1615
|
return input;
|
|
1481
1616
|
};
|
|
1482
|
-
var SegmentedMediabunnyInput = class extends Input$1 {
|
|
1617
|
+
var SegmentedMediabunnyInput = class SegmentedMediabunnyInput extends Input$1 {
|
|
1483
1618
|
#trackCache = /* @__PURE__ */ new WeakMap();
|
|
1484
1619
|
#subtitleTrackCache = /* @__PURE__ */ new WeakMap();
|
|
1485
1620
|
#hlsSubtitleBackingsPromise = null;
|
|
1486
1621
|
#customSubtitleBackings = [];
|
|
1622
|
+
#customAudioBackings = [];
|
|
1623
|
+
#audioInputs = [];
|
|
1487
1624
|
#nextCustomSubtitleTrackId = CUSTOM_SUBTITLE_TRACK_ID_OFFSET;
|
|
1488
1625
|
#nextCustomSubtitleTrackNumber = CUSTOM_SUBTITLE_TRACK_ID_OFFSET;
|
|
1626
|
+
#nextCustomAudioTrackId = CUSTOM_AUDIO_TRACK_ID_OFFSET;
|
|
1627
|
+
#nextCustomAudioTrackNumber = CUSTOM_AUDIO_TRACK_ID_OFFSET;
|
|
1489
1628
|
#nextPairingBitIndex = null;
|
|
1490
1629
|
async #queryTracks(query, type) {
|
|
1491
1630
|
const internalInput = this;
|
|
@@ -1500,9 +1639,11 @@ var SegmentedMediabunnyInput = class extends Input$1 {
|
|
|
1500
1639
|
return wrapped;
|
|
1501
1640
|
}
|
|
1502
1641
|
async _getSyntheticTrackBackings(type) {
|
|
1503
|
-
if (type
|
|
1504
|
-
const
|
|
1505
|
-
|
|
1642
|
+
if (type === BACKING_TYPE_VIDEO) return [];
|
|
1643
|
+
const audioBackings = type !== BACKING_TYPE_SUBTITLE ? [...this.#customAudioBackings] : [];
|
|
1644
|
+
const backings = type !== BACKING_TYPE_AUDIO ? [...this.#customSubtitleBackings] : [];
|
|
1645
|
+
if (type === BACKING_TYPE_AUDIO) return audioBackings;
|
|
1646
|
+
if (await this.getFormat() !== HLS$1) return [...audioBackings, ...backings];
|
|
1506
1647
|
if (!this.#hlsSubtitleBackingsPromise) {
|
|
1507
1648
|
const promise = getHlsSubtitleTrackBackings(this).catch((error) => {
|
|
1508
1649
|
if (this.#hlsSubtitleBackingsPromise === promise) this.#hlsSubtitleBackingsPromise = null;
|
|
@@ -1510,7 +1651,11 @@ var SegmentedMediabunnyInput = class extends Input$1 {
|
|
|
1510
1651
|
});
|
|
1511
1652
|
this.#hlsSubtitleBackingsPromise = promise;
|
|
1512
1653
|
}
|
|
1513
|
-
return [
|
|
1654
|
+
return [
|
|
1655
|
+
...audioBackings,
|
|
1656
|
+
...backings,
|
|
1657
|
+
...await this.#hlsSubtitleBackingsPromise
|
|
1658
|
+
];
|
|
1514
1659
|
}
|
|
1515
1660
|
#wrapSubtitleBacking(backing) {
|
|
1516
1661
|
const existing = this.#subtitleTrackCache.get(backing);
|
|
@@ -1556,6 +1701,31 @@ var SegmentedMediabunnyInput = class extends Input$1 {
|
|
|
1556
1701
|
this.#customSubtitleBackings.push(backing);
|
|
1557
1702
|
return this._wrapBackingAsTrack(backing);
|
|
1558
1703
|
}
|
|
1704
|
+
async addAudioTracks(source, options = {}) {
|
|
1705
|
+
const audioInput = new SegmentedMediabunnyInput({
|
|
1706
|
+
source,
|
|
1707
|
+
formats: [...options.formats ?? getDefaultAudioTrackFormats(source)]
|
|
1708
|
+
});
|
|
1709
|
+
this.#audioInputs.push(audioInput);
|
|
1710
|
+
const audioTracks = await audioInput.getAudioTracks({
|
|
1711
|
+
filter: options.filter,
|
|
1712
|
+
sortBy: options.sortBy
|
|
1713
|
+
});
|
|
1714
|
+
const pairWith = await this.#getAudioPairingVideoTracks(options.pairWith);
|
|
1715
|
+
const importedTracks = [];
|
|
1716
|
+
for (const audioTrack of audioTracks) {
|
|
1717
|
+
const backing = new ImportedAudioTrackBacking({
|
|
1718
|
+
id: this.#nextCustomAudioTrackId++,
|
|
1719
|
+
number: this.#nextCustomAudioTrackNumber++,
|
|
1720
|
+
backing: getTrackBacking(audioTrack),
|
|
1721
|
+
source: audioInput.source
|
|
1722
|
+
});
|
|
1723
|
+
this.#pairAudioBacking(backing, pairWith);
|
|
1724
|
+
this.#customAudioBackings.push(backing);
|
|
1725
|
+
importedTracks.push(this._wrapBackingAsTrack(backing));
|
|
1726
|
+
}
|
|
1727
|
+
return importedTracks;
|
|
1728
|
+
}
|
|
1559
1729
|
#takeSubtitleSourceRef(source) {
|
|
1560
1730
|
const rawSource = source instanceof SourceRef ? source.source : source;
|
|
1561
1731
|
if (!(rawSource instanceof Object) || !("rootPath" in rawSource) || !("ref" in rawSource) || typeof rawSource.ref !== "function") throw new TypeError("source must be a pathed source such as UrlSource or FilePathSource.");
|
|
@@ -1572,13 +1742,28 @@ var SegmentedMediabunnyInput = class extends Input$1 {
|
|
|
1572
1742
|
}
|
|
1573
1743
|
return tracks;
|
|
1574
1744
|
}
|
|
1745
|
+
async #getAudioPairingVideoTracks(pairWith) {
|
|
1746
|
+
if (pairWith === false) return [];
|
|
1747
|
+
if (!pairWith || pairWith === "all") return this.getVideoTracks();
|
|
1748
|
+
if (pairWith === "primary") {
|
|
1749
|
+
const primaryVideoTrack = await this.getPrimaryVideoTrack();
|
|
1750
|
+
return primaryVideoTrack ? [primaryVideoTrack] : [];
|
|
1751
|
+
}
|
|
1752
|
+
return this.#toPairableVideoTracks(pairWith);
|
|
1753
|
+
}
|
|
1575
1754
|
#isIterable(value) {
|
|
1576
1755
|
return typeof value === "object" && value !== null && Symbol.iterator in value;
|
|
1577
1756
|
}
|
|
1578
1757
|
#pairSubtitleBacking(subtitleBacking, videoTracks) {
|
|
1758
|
+
this.#pairBackingWithVideoTracks(subtitleBacking, videoTracks);
|
|
1759
|
+
}
|
|
1760
|
+
#pairAudioBacking(audioBacking, videoTracks) {
|
|
1761
|
+
this.#pairBackingWithVideoTracks(audioBacking, videoTracks);
|
|
1762
|
+
}
|
|
1763
|
+
#pairBackingWithVideoTracks(backing, videoTracks) {
|
|
1579
1764
|
for (const track of videoTracks) {
|
|
1580
1765
|
const bit = this.#allocatePairingBit();
|
|
1581
|
-
this.#appendPairingMask(
|
|
1766
|
+
this.#appendPairingMask(backing, bit);
|
|
1582
1767
|
this.#appendPairingMask(track._backing, bit);
|
|
1583
1768
|
}
|
|
1584
1769
|
}
|
|
@@ -1590,7 +1775,11 @@ var SegmentedMediabunnyInput = class extends Input$1 {
|
|
|
1590
1775
|
#getInitialPairingBitIndex() {
|
|
1591
1776
|
const loadedBackings = [...this._trackBackingsCache ?? []];
|
|
1592
1777
|
let maxBitIndex = -1n;
|
|
1593
|
-
for (const backing of [
|
|
1778
|
+
for (const backing of [
|
|
1779
|
+
...loadedBackings,
|
|
1780
|
+
...this.#customSubtitleBackings,
|
|
1781
|
+
...this.#customAudioBackings
|
|
1782
|
+
]) {
|
|
1594
1783
|
const mask = backing.getPairingMask?.() ?? 0n;
|
|
1595
1784
|
if (mask === 0n) continue;
|
|
1596
1785
|
const bitIndex = BigInt(mask.toString(2).length - 1);
|
|
@@ -1605,6 +1794,12 @@ var SegmentedMediabunnyInput = class extends Input$1 {
|
|
|
1605
1794
|
patchedBacking[ORIGINAL_GET_PAIRING_MASK] = backing.getPairingMask?.bind(backing) ?? (() => 0n);
|
|
1606
1795
|
Object.assign(backing, { getPairingMask: () => (patchedBacking[ORIGINAL_GET_PAIRING_MASK]?.() ?? 0n) | (patchedBacking[EXTRA_PAIRING_MASK] ?? 0n) });
|
|
1607
1796
|
}
|
|
1797
|
+
dispose() {
|
|
1798
|
+
if (this.disposed) return;
|
|
1799
|
+
super.dispose();
|
|
1800
|
+
for (const input of this.#audioInputs) input.dispose();
|
|
1801
|
+
this.#audioInputs.length = 0;
|
|
1802
|
+
}
|
|
1608
1803
|
};
|
|
1609
1804
|
//#endregion
|
|
1610
1805
|
//#region src/dash/dash-segmented-input.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dasha",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.1",
|
|
4
4
|
"description": "Streaming manifest parser",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
}
|
|
46
46
|
],
|
|
47
47
|
"engines": {
|
|
48
|
-
"node": ">=22.
|
|
48
|
+
"node": ">=22.19"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@xmldom/xmldom": "^0.9.10",
|
|
@@ -55,12 +55,12 @@
|
|
|
55
55
|
"mediabunny": "^1.45.2"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@types/node": "^25.
|
|
59
|
-
"oxfmt": "^0.
|
|
60
|
-
"oxlint": "^1.
|
|
61
|
-
"tsdown": "^0.22.
|
|
58
|
+
"@types/node": "^25.9.1",
|
|
59
|
+
"oxfmt": "^0.52.0",
|
|
60
|
+
"oxlint": "^1.67.0",
|
|
61
|
+
"tsdown": "^0.22.1",
|
|
62
62
|
"typescript": "^6.0.3",
|
|
63
|
-
"vitest": "^4.1.
|
|
63
|
+
"vitest": "^4.1.7"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"test": "vitest",
|