Add HLS reading tests, InputTrack.hasOnlyKeyPackets, faster whole-file reading

This commit is contained in:
Vanilagy
2026-03-10 13:32:52 +01:00
parent c088a31384
commit ff523c01c8
13 changed files with 940 additions and 207 deletions
+60 -4
View File
@@ -7,7 +7,7 @@
*/
import { InputDisposedError } from './input';
import { assert, clamp, getUint24, MaybePromise, toDataView } from './misc';
import { assert, clamp, getUint24, MaybePromise, textDecoder, toDataView } from './misc';
import { DEFAULT_MAX_READ_POSITION, DEFAULT_MIN_READ_POSITION, Source } from './source';
export class Reader {
@@ -35,10 +35,15 @@ export class Reader {
return null;
}
if (this.fileSizeNonStrict != null && start + length > this.fileSizeNonStrict) {
if (this.fileSizeNonStrict !== null && start + length > this.fileSizeNonStrict) {
return null;
}
if (length === 0) {
const buffer = new Uint8Array(0);
return new FileSlice(buffer, toDataView(buffer), 0, start, start);
}
const end = start + length;
const result = this.source._read(start, end, DEFAULT_MIN_READ_POSITION, DEFAULT_MAX_READ_POSITION);
@@ -68,7 +73,7 @@ export class Reader {
return null;
}
if (this.fileSizeNonStrict != null) {
if (this.fileSizeNonStrict !== null) {
return this.requestSlice(
start,
clamp(this.fileSizeNonStrict - start, minLength, maxLength),
@@ -82,7 +87,7 @@ export class Reader {
}
// The slice couldn't fit, meaning we must know the file size now
assert(this.fileSizeNonStrict != null);
assert(this.fileSizeNonStrict !== null);
return this.requestSlice(
start,
@@ -97,6 +102,46 @@ export class Reader {
}
}
}
requestEntireFile(): MaybePromise<FileSlice | null> {
if (this.fileSizeNonStrict !== null) {
return this.requestSlice(0, this.fileSizeNonStrict);
}
const CHUNK_SIZE = 1024;
return (async () => {
const chunks: Uint8Array[] = [];
let currentSize = 0;
while (true) {
if (chunks.length === 1 && this.fileSizeNonStrict !== null) {
// It only took one read to get to know the whole file size
return this.requestSlice(0, this.fileSizeNonStrict);
}
const startOffset = chunks.length * CHUNK_SIZE;
let slice = this.requestSliceRange(startOffset, 0, CHUNK_SIZE);
if (slice instanceof Promise) slice = await slice;
if (!slice) {
break;
}
chunks.push(readBytes(slice, slice.length));
currentSize += slice.length;
}
const joined = new Uint8Array(currentSize);
let offset = 0;
for (const chunk of chunks) {
joined.set(chunk, offset);
offset += chunk.length;
}
return new FileSlice(joined, toDataView(joined), 0, 0, currentSize);
})();
}
}
export class FileSlice {
@@ -333,6 +378,17 @@ export const readAscii = (slice: FileSlice, length: number) => {
return str;
};
export const readAllLines = (slice: FileSlice, length: number, options?: {
ignore?: (line: string) => boolean;
}) => {
const text = textDecoder.decode(readBytes(slice, length));
const lines = text.split('\n')
.map(x => x.trim())
.filter(x => x.length > 0 && !options?.ignore?.(x));
return lines;
};
export class LineReader {
getReader: () => MaybePromise<Reader>;
ignore?: (line: string) => boolean;