mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-28 03:13:51 +02:00
fix: two long-running HLS transcode issues (#355)
* fix: release targets from Output._targets on finalize Long-running HLS transcodes leak memory. Every finalized BufferTarget stays in _targets until the outer Output closes, pinning its buffer. Writer.finalize() already does this cleanup for writer-based flows; extend it to buffer-finalize paths via the public 'finalized' event. * fix: ReadOrchestrator LRU eviction picks only drained workers assert(pendingSlices.length === 0) fires under heavy concurrent reads (e.g. multi-rendition HLS decode from BlobSource). LRU filter only checked !running; workers with queued slices could be evicted. Add pendingSlices.length === 0 to the filter. * fix: export AppendOnlyStreamTarget from index Missing from the re-export; public docs import it by name. * fix: join HLS init segment path with root + playlist path Init path went through _getTarget bare; segments got joined with rootPath + playlist.path. Playlist-relative URI then can't resolve when the playlist lives in a subdirectory. * Fix targets not being cleaned up, fix paused workers with remaining pending slices, modify doc block, fixed isRoot not being changed on proxied requests --------- Co-authored-by: Vanilagy <[email protected]>
This commit is contained in:
co-authored by
Vanilagy
parent
7acae8dda1
commit
b05cdbe7e0
+12
-3
@@ -898,6 +898,11 @@ export class HlsMuxer extends Muxer {
|
||||
target: new PathedTarget(
|
||||
fullSegmentPath,
|
||||
async (request: TargetRequest) => {
|
||||
const proxiedRequest: TargetRequest = {
|
||||
...request,
|
||||
isRoot: false,
|
||||
};
|
||||
|
||||
if (request.isRoot) {
|
||||
if (playlist.singleFile) {
|
||||
const slice = playlist.singleFile.target.slice(playlist.singleFile.nextOffset);
|
||||
@@ -905,7 +910,7 @@ export class HlsMuxer extends Muxer {
|
||||
|
||||
return slice;
|
||||
} else {
|
||||
const target = await this.output._getTarget(request);
|
||||
const target = await this.output._getTarget(proxiedRequest);
|
||||
outputTarget = target;
|
||||
target.on('write', ({ end }) => segmentSize = Math.max(segmentSize, end));
|
||||
|
||||
@@ -913,7 +918,7 @@ export class HlsMuxer extends Muxer {
|
||||
}
|
||||
}
|
||||
|
||||
return this.output._getTarget(request);
|
||||
return this.output._getTarget(proxiedRequest);
|
||||
},
|
||||
),
|
||||
initTarget: async () => {
|
||||
@@ -955,8 +960,12 @@ export class HlsMuxer extends Muxer {
|
||||
info: null,
|
||||
};
|
||||
|
||||
const fullInitPath = joinPaths(
|
||||
joinPaths(pathedTarget.rootPath, playlist.path),
|
||||
initPath,
|
||||
);
|
||||
const target = await this.output._getTarget({
|
||||
path: initPath,
|
||||
path: fullInitPath,
|
||||
isRoot: false,
|
||||
mimeType: playlist.segmentFormat.mimeType,
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ENCRYPTION_KEY_CACHE_GROUP, Input } from '../input';
|
||||
import { Segment, SegmentedInput, SegmentedInputTrackDeclaration, SegmentRetrievalOptions } from '../segmented-input';
|
||||
import { toDataView, joinPaths, last, assert, binarySearchLessOrEqual, arrayArgmin, wait } from '../misc';
|
||||
import { readAllLines, readBytes, Reader } from '../reader';
|
||||
import { CustomPathedSource, ReadableStreamSource, SourceRef } from '../source';
|
||||
import { CustomPathedSource, ReadableStreamSource, SourceRef, SourceRequest } from '../source';
|
||||
import { HlsDemuxer } from './hls-demuxer';
|
||||
import {
|
||||
AttributeList,
|
||||
@@ -568,6 +568,11 @@ export class HlsSegmentedInput extends SegmentedInput {
|
||||
async (request) => {
|
||||
assert(request.isRoot); // Shouldn't fail since we don't allow recursive HLS
|
||||
|
||||
const proxiedRequest: SourceRequest = {
|
||||
...request,
|
||||
isRoot: false,
|
||||
};
|
||||
|
||||
let ref: SourceRef;
|
||||
const needsSlice = hlsSegment.location.offset > 0 || hlsSegment.location.length !== null;
|
||||
|
||||
@@ -576,7 +581,7 @@ export class HlsSegmentedInput extends SegmentedInput {
|
||||
|| hlsSegment.encryption.method === 'SAMPLE-AES'
|
||||
|| hlsSegment.encryption.method === 'SAMPLE-AES-CTR'
|
||||
) {
|
||||
ref = await this.input._getSourceCached(request);
|
||||
ref = await this.input._getSourceCached(proxiedRequest);
|
||||
|
||||
if (needsSlice) {
|
||||
const slice = ref.source.slice(
|
||||
@@ -591,7 +596,7 @@ export class HlsSegmentedInput extends SegmentedInput {
|
||||
const encryption = hlsSegment.encryption;
|
||||
assert(encryption.iv);
|
||||
|
||||
let ciphertextRef = await this.input._getSourceCached(request);
|
||||
let ciphertextRef = await this.input._getSourceCached(proxiedRequest);
|
||||
if (needsSlice) {
|
||||
// Slice before decrypting
|
||||
const slice = ciphertextRef.source.slice(
|
||||
|
||||
Reference in New Issue
Block a user