dasha 4.4.3 → 4.4.4
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 +5 -1
- package/dist/index.mjs +79 -32
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -183,6 +183,7 @@ type Segment = {
|
|
|
183
183
|
};
|
|
184
184
|
type DashSegmentLocation = {
|
|
185
185
|
path: string;
|
|
186
|
+
sourcePath: string;
|
|
186
187
|
offset: number;
|
|
187
188
|
length: number | null;
|
|
188
189
|
};
|
|
@@ -360,7 +361,10 @@ declare class DashDemuxer {
|
|
|
360
361
|
}): void;
|
|
361
362
|
findMatchingTrack(nextTracks: DashParsedTrack[], currentTrack: DashParsedTrack): DashParsedTrack | undefined;
|
|
362
363
|
refreshTracks(tracks: DashParsedTrack[]): Promise<void>;
|
|
363
|
-
|
|
364
|
+
fetchManifestText(url: string): Promise<{
|
|
365
|
+
text: string;
|
|
366
|
+
url: string;
|
|
367
|
+
}>;
|
|
364
368
|
resetManifestUrls(): void;
|
|
365
369
|
}
|
|
366
370
|
declare abstract class DashTrackBackingBase {
|
package/dist/index.mjs
CHANGED
|
@@ -316,6 +316,21 @@ const getDashTrackMatchKey = (track) => JSON.stringify({
|
|
|
316
316
|
const getSourcePath = (source) => {
|
|
317
317
|
if ("rootPath" in source && typeof source.rootPath === "string") return source.rootPath;
|
|
318
318
|
};
|
|
319
|
+
const resolvePathedSourceRequest = async (source, request) => {
|
|
320
|
+
const pathedSource = source;
|
|
321
|
+
if (typeof pathedSource._resolveRequest !== "function") throw new Error("DASH input currently requires a pathed source such as UrlSource.");
|
|
322
|
+
return await pathedSource._resolveRequest(request);
|
|
323
|
+
};
|
|
324
|
+
const resolvePathedSourcePath = async (source, request) => {
|
|
325
|
+
const ref = await resolvePathedSourceRequest(source, request);
|
|
326
|
+
try {
|
|
327
|
+
const path = getSourcePath(ref.source);
|
|
328
|
+
if (!path) throw new Error("DASH segment requests must resolve to a pathed source.");
|
|
329
|
+
return path;
|
|
330
|
+
} finally {
|
|
331
|
+
ref.free();
|
|
332
|
+
}
|
|
333
|
+
};
|
|
319
334
|
const normalizeHeaders$1 = (headers) => {
|
|
320
335
|
if (!headers) return {};
|
|
321
336
|
if (headers instanceof Headers) return Object.fromEntries(headers.entries());
|
|
@@ -333,30 +348,45 @@ const getSourceHeaders$1 = (source) => {
|
|
|
333
348
|
const getSourceFetch = (source) => {
|
|
334
349
|
return ("_options" in source && source._options && typeof source._options === "object" ? source._options : void 0)?.fetchFn ?? fetch;
|
|
335
350
|
};
|
|
351
|
+
const fetchDashManifest = async (source, url) => {
|
|
352
|
+
const response = await getSourceFetch(source)(url, { headers: getSourceHeaders$1(source) });
|
|
353
|
+
if (!response.ok) throw new Error(`Failed to fetch DASH manifest: ${response.status} ${response.statusText} (${response.url})`);
|
|
354
|
+
return response;
|
|
355
|
+
};
|
|
336
356
|
const parseOriginalUrlFromManifest = (text) => text.match(/<!--\s*URL:\s*([^\n]+?)\s*-->/)?.[1]?.trim();
|
|
337
357
|
const loadDashManifest = async (source) => {
|
|
338
358
|
const manifestPath = getSourcePath(source);
|
|
339
359
|
if (!manifestPath) throw new Error("DASH input currently requires a pathed source such as UrlSource.");
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
360
|
+
const manifestRef = await resolvePathedSourceRequest(source, {
|
|
361
|
+
path: manifestPath,
|
|
362
|
+
isRoot: true
|
|
363
|
+
});
|
|
364
|
+
const manifestSource = manifestRef.source;
|
|
365
|
+
const resolvedManifestPath = getSourcePath(manifestSource);
|
|
366
|
+
try {
|
|
367
|
+
if (!resolvedManifestPath) throw new Error("DASH manifest requests must resolve to a pathed source.");
|
|
368
|
+
if (resolvedManifestPath.startsWith("http://") || resolvedManifestPath.startsWith("https://")) {
|
|
369
|
+
const response = await fetchDashManifest(manifestSource, resolvedManifestPath);
|
|
370
|
+
return {
|
|
371
|
+
text: await response.text(),
|
|
372
|
+
url: response.url || resolvedManifestPath
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (resolvedManifestPath.startsWith("file:")) {
|
|
376
|
+
const text = await readFile(new URL(resolvedManifestPath), "utf8");
|
|
377
|
+
return {
|
|
378
|
+
text,
|
|
379
|
+
url: parseOriginalUrlFromManifest(text) ?? resolvedManifestPath
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
const text = await readFile(resolvedManifestPath, "utf8");
|
|
350
383
|
return {
|
|
351
384
|
text,
|
|
352
|
-
url: parseOriginalUrlFromManifest(text) ??
|
|
385
|
+
url: parseOriginalUrlFromManifest(text) ?? resolvedManifestPath
|
|
353
386
|
};
|
|
387
|
+
} finally {
|
|
388
|
+
manifestRef.free();
|
|
354
389
|
}
|
|
355
|
-
const text = await readFile(manifestPath, "utf8");
|
|
356
|
-
return {
|
|
357
|
-
text,
|
|
358
|
-
url: parseOriginalUrlFromManifest(text) ?? manifestPath
|
|
359
|
-
};
|
|
360
390
|
};
|
|
361
391
|
const isLikelyDashPath = (source) => {
|
|
362
392
|
const path = getSourcePath(source);
|
|
@@ -1831,23 +1861,27 @@ const getLeastRecentlyUsedIndex = (entries) => {
|
|
|
1831
1861
|
}
|
|
1832
1862
|
return bestIndex;
|
|
1833
1863
|
};
|
|
1834
|
-
const getSegmentLocation = (segment) => ({
|
|
1835
|
-
path:
|
|
1864
|
+
const getSegmentLocation = async (input, segment) => ({
|
|
1865
|
+
path: await resolvePathedSourcePath(input.source, {
|
|
1866
|
+
path: segment.url,
|
|
1867
|
+
isRoot: false
|
|
1868
|
+
}),
|
|
1869
|
+
sourcePath: segment.url,
|
|
1836
1870
|
offset: segment.startRange ?? 0,
|
|
1837
1871
|
length: segment.expectLength ?? null
|
|
1838
1872
|
});
|
|
1839
|
-
const createInitSegment = (segment) => ({
|
|
1873
|
+
const createInitSegment = async (input, segment) => ({
|
|
1840
1874
|
timestamp: 0,
|
|
1841
1875
|
duration: 0,
|
|
1842
1876
|
relativeToUnixEpoch: false,
|
|
1843
1877
|
firstSegment: null,
|
|
1844
1878
|
sequenceNumber: segment.sequenceNumber,
|
|
1845
|
-
location: getSegmentLocation(segment),
|
|
1879
|
+
location: await getSegmentLocation(input, segment),
|
|
1846
1880
|
encryption: segment.encryption,
|
|
1847
1881
|
initSegment: null,
|
|
1848
1882
|
lastProgramDateTimeSeconds: null
|
|
1849
1883
|
});
|
|
1850
|
-
const trackToDashSegments = (internalTrack) => {
|
|
1884
|
+
const trackToDashSegments = async (input, internalTrack) => {
|
|
1851
1885
|
const mediaSegments = internalTrack.track.mediaSegments;
|
|
1852
1886
|
if (mediaSegments.length === 0) return [];
|
|
1853
1887
|
let nextTimestamp = 0;
|
|
@@ -1860,7 +1894,7 @@ const trackToDashSegments = (internalTrack) => {
|
|
|
1860
1894
|
relativeToUnixEpoch: false,
|
|
1861
1895
|
firstSegment: null,
|
|
1862
1896
|
sequenceNumber: mediaSegment.sequenceNumber,
|
|
1863
|
-
location: getSegmentLocation(mediaSegment),
|
|
1897
|
+
location: await getSegmentLocation(input, mediaSegment),
|
|
1864
1898
|
encryption: mediaSegment.encryption,
|
|
1865
1899
|
initSegment: null,
|
|
1866
1900
|
lastProgramDateTimeSeconds: null
|
|
@@ -1869,7 +1903,7 @@ const trackToDashSegments = (internalTrack) => {
|
|
|
1869
1903
|
nextTimestamp = timestamp + mediaSegment.duration;
|
|
1870
1904
|
}
|
|
1871
1905
|
const firstSegment = segments[0] ?? null;
|
|
1872
|
-
const initSegment = internalTrack.track.initSegment ? createInitSegment(internalTrack.track.initSegment) : null;
|
|
1906
|
+
const initSegment = internalTrack.track.initSegment ? await createInitSegment(input, internalTrack.track.initSegment) : null;
|
|
1873
1907
|
for (const segment of segments) {
|
|
1874
1908
|
segment.firstSegment = firstSegment;
|
|
1875
1909
|
segment.initSegment = initSegment;
|
|
@@ -1905,8 +1939,9 @@ var DashSegmentedInput = class {
|
|
|
1905
1939
|
})();
|
|
1906
1940
|
}
|
|
1907
1941
|
async updateSegments() {
|
|
1942
|
+
const input = this.demuxer.input;
|
|
1908
1943
|
await this.demuxer.refreshTrackSegments(this.internalTrack);
|
|
1909
|
-
this.segments = trackToDashSegments(this.internalTrack);
|
|
1944
|
+
this.segments = await trackToDashSegments(input, this.internalTrack);
|
|
1910
1945
|
}
|
|
1911
1946
|
getRemainingWaitTimeMs() {
|
|
1912
1947
|
if (!this.internalTrack.track.isLive) return 0;
|
|
@@ -1970,7 +2005,7 @@ var DashSegmentedInput = class {
|
|
|
1970
2005
|
if (segment.initSegment && segment.initSegment !== segment) initInput = this.getInputForSegment(segment.initSegment);
|
|
1971
2006
|
const formatOptions = { ...input._formatOptions };
|
|
1972
2007
|
const segmentInput = preserveSubtitleBackingsOnInput(new Input$1({
|
|
1973
|
-
source: new CustomPathedSource(segment.location.
|
|
2008
|
+
source: new CustomPathedSource(segment.location.sourcePath, async (request) => {
|
|
1974
2009
|
if (!request.isRoot) throw new Error("Nested requests are not supported for DASH segments.");
|
|
1975
2010
|
const proxiedRequest = {
|
|
1976
2011
|
...request,
|
|
@@ -2764,11 +2799,10 @@ var DashDemuxer = class {
|
|
|
2764
2799
|
}
|
|
2765
2800
|
async refreshTracks(tracks) {
|
|
2766
2801
|
if (!tracks.length) return;
|
|
2767
|
-
const response = await this.
|
|
2768
|
-
const rawText = await response.text();
|
|
2802
|
+
const response = await this.fetchManifestText(this.manifestUrl).catch(() => this.fetchManifestText(this.originalUrl));
|
|
2769
2803
|
this.manifestUrl = response.url;
|
|
2770
2804
|
this.resetManifestUrls();
|
|
2771
|
-
const nextTracks = this.extractTracks(
|
|
2805
|
+
const nextTracks = this.extractTracks(response.text);
|
|
2772
2806
|
for (const track of tracks) {
|
|
2773
2807
|
const nextTrack = this.findMatchingTrack(nextTracks, track);
|
|
2774
2808
|
if (!nextTrack) continue;
|
|
@@ -2781,10 +2815,23 @@ var DashDemuxer = class {
|
|
|
2781
2815
|
track.subtitleGroupId = nextTrack.subtitleGroupId;
|
|
2782
2816
|
}
|
|
2783
2817
|
}
|
|
2784
|
-
async
|
|
2785
|
-
const
|
|
2786
|
-
|
|
2787
|
-
|
|
2818
|
+
async fetchManifestText(url) {
|
|
2819
|
+
const manifestRef = await resolvePathedSourceRequest(this.input.source, {
|
|
2820
|
+
path: url,
|
|
2821
|
+
isRoot: true
|
|
2822
|
+
});
|
|
2823
|
+
const manifestSource = manifestRef.source;
|
|
2824
|
+
try {
|
|
2825
|
+
const resolvedUrl = getSourcePath(manifestSource);
|
|
2826
|
+
if (!resolvedUrl) throw new Error("DASH manifest requests must resolve to a pathed source.");
|
|
2827
|
+
const response = await fetchDashManifest(manifestSource, resolvedUrl);
|
|
2828
|
+
return {
|
|
2829
|
+
text: await response.text(),
|
|
2830
|
+
url: response.url || resolvedUrl
|
|
2831
|
+
};
|
|
2832
|
+
} finally {
|
|
2833
|
+
manifestRef.free();
|
|
2834
|
+
}
|
|
2788
2835
|
}
|
|
2789
2836
|
resetManifestUrls() {
|
|
2790
2837
|
this.mpdUrl = this.manifestUrl;
|