mirror of
https://github.com/imputnet/cobalt.git
synced 2025-07-18 03:08:30 +00:00
improvement: HLS support for internal streams
This commit is contained in:
parent
abd9f2eb87
commit
9d457d8022
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cobalt",
|
||||
"version": "7.14.1",
|
||||
"version": "7.14.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cobalt",
|
||||
"version": "7.14.1",
|
||||
"version": "7.14.2",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"content-disposition-header": "0.6.0",
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { request } from 'undici';
|
||||
import { Readable } from 'node:stream';
|
||||
import { assert } from 'console';
|
||||
import { createInternalStream } from './manage.js';
|
||||
import { getHeaders } from './shared.js';
|
||||
import HLS from 'hls-parser';
|
||||
|
||||
const CHUNK_SIZE = BigInt(8e6); // 8 MB
|
||||
const min = (a, b) => a < b ? a : b;
|
||||
@ -73,6 +75,36 @@ async function handleYoutubeStream(streamInfo, res) {
|
||||
}
|
||||
}
|
||||
|
||||
function transformHLSMediaPlaylist(streamInfo, hlsPlaylist) {
|
||||
function generateInternalStreamsOfSegments(segment) {
|
||||
const fullUri = new URL(segment.uri, streamInfo.url).toString();
|
||||
segment.uri = createInternalStream(fullUri, streamInfo);
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
hlsPlaylist.segments =
|
||||
hlsPlaylist.segments.map(generateInternalStreamsOfSegments);
|
||||
hlsPlaylist.prefetchSegments =
|
||||
hlsPlaylist.prefetchSegments.map(generateInternalStreamsOfSegments);
|
||||
|
||||
return hlsPlaylist;
|
||||
}
|
||||
|
||||
async function handleHLSPlaylist(streamInfo, req, res) {
|
||||
let hlsPlaylist = await req.body.text();
|
||||
hlsPlaylist = HLS.parse(hlsPlaylist);
|
||||
|
||||
// NOTE no processing module is passing the master playlist
|
||||
assert(!hlsPlaylist.isMasterPlaylist);
|
||||
|
||||
hlsPlaylist = transformHLSMediaPlaylist(streamInfo, hlsPlaylist);
|
||||
hlsPlaylist = HLS.stringify(hlsPlaylist);
|
||||
|
||||
res.write(hlsPlaylist);
|
||||
res.end();
|
||||
}
|
||||
|
||||
export async function internalStream(streamInfo, res) {
|
||||
if (streamInfo.service === 'youtube') {
|
||||
return handleYoutubeStream(streamInfo, res);
|
||||
@ -97,8 +129,12 @@ export async function internalStream(streamInfo, res) {
|
||||
if (req.statusCode < 200 || req.statusCode > 299)
|
||||
return res.end();
|
||||
|
||||
req.body.pipe(res);
|
||||
req.body.on('error', () => res.end());
|
||||
if (["application/vnd.apple.mpegurl", "audio/mpegurl"].includes(req.headers['content-type'])) {
|
||||
await handleHLSPlaylist(streamInfo, req, res);
|
||||
} else {
|
||||
req.body.pipe(res);
|
||||
req.body.on('error', () => res.end());
|
||||
}
|
||||
} catch {
|
||||
streamInfo.controller.abort();
|
||||
}
|
||||
|
@ -108,12 +108,6 @@ export function destroyInternalStream(url) {
|
||||
}
|
||||
|
||||
function wrapStream(streamInfo) {
|
||||
/* m3u8 links are currently not supported
|
||||
* for internal streams, skip them */
|
||||
if (M3U_SERVICES.includes(streamInfo.service)) {
|
||||
return streamInfo;
|
||||
}
|
||||
|
||||
const url = streamInfo.urls;
|
||||
|
||||
if (typeof url === 'string') {
|
||||
|
Loading…
Reference in New Issue
Block a user