I want to return a specific byte range given a ReadableStream. It sounds easy but I can't find any way to skip through or read a specific amount of bytes from the stream since we can only read chunks. I would prefer to not store any data and just send the stream. It sounds like I could do this with a TransformStream and PipeThrough(). But I need some help wrapping my head around it.
Example: Given a ReadableStream of say 1000 bytes, I want to return another stream that starts at byte 300 and ends at byte 900.
I know this can easily be done with nodes createReadableStream(), but I need to run this in the browser so it cant use node.
Here's some skeleton code to get you started:
function byteRangeTransform(start, end) {
let bytesSeen = 0;
return new TransformStream({
transform(chunk, controller) {
const chunkStart = bytesSeen;
const chunkEnd = bytesSeen + chunk.byteLength;
bytesSeen += chunk.byteLength;
// Six cases:
// 1. Chunk entirely before start
if (chunkEnd < start) {
return;
}
// 2. Chunk starts before start, ends between start and end
if (chunkStart < start && chunkEnd >= start && chunkEnd <= end) {
const slice = /* TODO */;
controller.enqueue(slice);
return;
}
// 3. Chunk starts before start, ends after end
if (chunkStart < start && chunkEnd > end) {
// TODO
}
// 4. Chunk starts after start, ends between start and end
// 5. Chunk starts after start, ends after end
// 6. Chunk starts after end
}
});
}
const onlyInRange = originalReadable.pipeThrough(byteRangeTransform(300, 900));