mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-16 17:23:43 +08:00
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
/**
|
|
* HLS Manifest Parser Utility
|
|
* Parses m3u8 manifests and extracts segment information
|
|
*/
|
|
|
|
export interface Segment {
|
|
url: string;
|
|
duration: number;
|
|
startTime: number;
|
|
}
|
|
|
|
export async function parseHLSManifest(src: string): Promise<Segment[]> {
|
|
const response = await fetch(src);
|
|
if (!response.ok) {
|
|
const errorMsg = response.status === 503
|
|
? `Network unavailable (Service Worker offline): ${src}`
|
|
: `Failed to fetch manifest (${response.status}): ${src}`;
|
|
throw new Error(errorMsg);
|
|
}
|
|
const manifestText = await response.text();
|
|
|
|
const lines = manifestText.split('\n');
|
|
const segments: Segment[] = [];
|
|
const baseUrl = src.substring(0, src.lastIndexOf('/') + 1);
|
|
let currentSegmentDuration = 0;
|
|
let currentStartTime = 0;
|
|
|
|
for (const line of lines) {
|
|
const trimmed = line.trim();
|
|
if (trimmed.startsWith('#EXTINF:')) {
|
|
const durationStr = trimmed.substring(8).split(',')[0];
|
|
currentSegmentDuration = parseFloat(durationStr);
|
|
} else if (trimmed && !trimmed.startsWith('#')) {
|
|
// Use URL API to resolve relative paths correctly against the manifest URL
|
|
// This handles cases where baseUrl might end with / and segment starts with /
|
|
const segmentUrl = new URL(trimmed, src).toString();
|
|
segments.push({
|
|
url: segmentUrl,
|
|
duration: currentSegmentDuration,
|
|
startTime: currentStartTime
|
|
});
|
|
currentStartTime += currentSegmentDuration;
|
|
}
|
|
}
|
|
|
|
return segments;
|
|
}
|