mirror of
https://github.com/imputnet/cobalt.git
synced 2025-07-18 19:28:29 +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",
|
"name": "cobalt",
|
||||||
"version": "7.14.1",
|
"version": "7.14.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cobalt",
|
"name": "cobalt",
|
||||||
"version": "7.14.1",
|
"version": "7.14.2",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"content-disposition-header": "0.6.0",
|
"content-disposition-header": "0.6.0",
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { request } from 'undici';
|
import { request } from 'undici';
|
||||||
import { Readable } from 'node:stream';
|
import { Readable } from 'node:stream';
|
||||||
import { assert } from 'console';
|
import { assert } from 'console';
|
||||||
|
import { createInternalStream } from './manage.js';
|
||||||
import { getHeaders } from './shared.js';
|
import { getHeaders } from './shared.js';
|
||||||
|
import HLS from 'hls-parser';
|
||||||
|
|
||||||
const CHUNK_SIZE = BigInt(8e6); // 8 MB
|
const CHUNK_SIZE = BigInt(8e6); // 8 MB
|
||||||
const min = (a, b) => a < b ? a : b;
|
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) {
|
export async function internalStream(streamInfo, res) {
|
||||||
if (streamInfo.service === 'youtube') {
|
if (streamInfo.service === 'youtube') {
|
||||||
return handleYoutubeStream(streamInfo, res);
|
return handleYoutubeStream(streamInfo, res);
|
||||||
@ -97,8 +129,12 @@ export async function internalStream(streamInfo, res) {
|
|||||||
if (req.statusCode < 200 || req.statusCode > 299)
|
if (req.statusCode < 200 || req.statusCode > 299)
|
||||||
return res.end();
|
return 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.pipe(res);
|
||||||
req.body.on('error', () => res.end());
|
req.body.on('error', () => res.end());
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
streamInfo.controller.abort();
|
streamInfo.controller.abort();
|
||||||
}
|
}
|
||||||
|
@ -108,12 +108,6 @@ export function destroyInternalStream(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function wrapStream(streamInfo) {
|
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;
|
const url = streamInfo.urls;
|
||||||
|
|
||||||
if (typeof url === 'string') {
|
if (typeof url === 'string') {
|
||||||
|
Loading…
Reference in New Issue
Block a user