2024-06-07 12:08:20 +01:00
|
|
|
import { createInternalStream } from './manage.js';
|
|
|
|
import HLS from 'hls-parser';
|
2024-06-08 17:34:18 +01:00
|
|
|
|
|
|
|
function getURL(url) {
|
|
|
|
try {
|
|
|
|
return new URL(url);
|
|
|
|
} catch {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2024-06-07 12:08:20 +01:00
|
|
|
|
|
|
|
function transformObject(streamInfo, hlsObject) {
|
|
|
|
if (hlsObject === undefined) {
|
|
|
|
return (object) => transformObject(streamInfo, object);
|
|
|
|
}
|
|
|
|
|
2024-06-08 17:34:18 +01:00
|
|
|
let fullUrl;
|
|
|
|
if (getURL(hlsObject.uri)) {
|
|
|
|
fullUrl = hlsObject.uri;
|
|
|
|
} else {
|
|
|
|
fullUrl = new URL(hlsObject.uri, streamInfo.url);
|
|
|
|
}
|
|
|
|
|
|
|
|
hlsObject.uri = createInternalStream(fullUrl.toString(), streamInfo);
|
2024-06-07 12:08:20 +01:00
|
|
|
|
2024-06-23 17:17:11 +01:00
|
|
|
if (hlsObject.map) {
|
|
|
|
hlsObject.map = transformObject(streamInfo, hlsObject.map);
|
|
|
|
}
|
|
|
|
|
2024-06-07 12:08:20 +01:00
|
|
|
return hlsObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
function transformMasterPlaylist(streamInfo, hlsPlaylist) {
|
|
|
|
const makeInternalStream = transformObject(streamInfo);
|
|
|
|
|
|
|
|
const makeInternalVariants = (variant) => {
|
|
|
|
variant = transformObject(streamInfo, variant);
|
|
|
|
variant.video = variant.video.map(makeInternalStream);
|
|
|
|
variant.audio = variant.audio.map(makeInternalStream);
|
|
|
|
return variant;
|
|
|
|
};
|
|
|
|
hlsPlaylist.variants = hlsPlaylist.variants.map(makeInternalVariants);
|
|
|
|
|
|
|
|
return hlsPlaylist;
|
|
|
|
}
|
|
|
|
|
|
|
|
function transformMediaPlaylist(streamInfo, hlsPlaylist) {
|
|
|
|
const makeInternalSegments = transformObject(streamInfo);
|
|
|
|
hlsPlaylist.segments = hlsPlaylist.segments.map(makeInternalSegments);
|
|
|
|
hlsPlaylist.prefetchSegments = hlsPlaylist.prefetchSegments.map(makeInternalSegments);
|
|
|
|
return hlsPlaylist;
|
|
|
|
}
|
|
|
|
|
|
|
|
const HLS_MIME_TYPES = ["application/vnd.apple.mpegurl", "audio/mpegurl", "application/x-mpegURL"];
|
|
|
|
|
|
|
|
export function isHlsRequest (req) {
|
|
|
|
return HLS_MIME_TYPES.includes(req.headers['content-type']);
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function handleHlsPlaylist(streamInfo, req, res) {
|
|
|
|
let hlsPlaylist = await req.body.text();
|
|
|
|
hlsPlaylist = HLS.parse(hlsPlaylist);
|
|
|
|
|
|
|
|
hlsPlaylist = hlsPlaylist.isMasterPlaylist
|
|
|
|
? transformMasterPlaylist(streamInfo, hlsPlaylist)
|
|
|
|
: transformMediaPlaylist(streamInfo, hlsPlaylist);
|
|
|
|
|
|
|
|
hlsPlaylist = HLS.stringify(hlsPlaylist);
|
|
|
|
|
|
|
|
res.send(hlsPlaylist);
|
|
|
|
}
|