refactor(downloads): add readableStreamIterator for easier stream handling
- Introduced `readableStreamIterator` to convert ReadableStream into async iterable. - Updated `LosslessAPI` to utilize `readableStreamIterator` for handling response body. - Modified `ZipNeutralinoWriter` to use `readableStreamIterator` for reading chunks.
This commit is contained in:
parent
61aebf7994
commit
cd64239ba1
3 changed files with 34 additions and 13 deletions
15
js/api.js
15
js/api.js
|
|
@ -21,6 +21,7 @@ import { triggerDownload, applyAudioPostProcessing } from './download-utils.ts';
|
|||
import { isCustomFormat } from './ffmpegFormats.ts';
|
||||
import { DownloadProgress } from './progressEvents.js';
|
||||
import { resolveDownloadTotalBytes } from './downloadProgressUtils.js';
|
||||
import { readableStreamIterator } from './readableStreamIterator.js';
|
||||
|
||||
export const DASH_MANIFEST_UNAVAILABLE_CODE = 'DASH_MANIFEST_UNAVAILABLE';
|
||||
export { resolveDownloadTotalBytes };
|
||||
|
|
@ -1431,19 +1432,13 @@ export class LosslessAPI {
|
|||
let receivedBytes = 0;
|
||||
|
||||
if (response.body) {
|
||||
const reader = response.body.getReader();
|
||||
const chunks = [];
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
for await (const chunk of readableStreamIterator(response.body)) {
|
||||
chunks.push(chunk);
|
||||
receivedBytes += chunk.byteLength;
|
||||
|
||||
if (value) {
|
||||
chunks.push(value);
|
||||
receivedBytes += value.byteLength;
|
||||
|
||||
onProgress?.(new DownloadProgress(receivedBytes, totalBytes || undefined));
|
||||
}
|
||||
onProgress?.(new DownloadProgress(receivedBytes, totalBytes || undefined));
|
||||
}
|
||||
|
||||
const defaultMime = isVideo ? 'video/mp4' : 'audio/flac';
|
||||
|
|
|
|||
|
|
@ -135,9 +135,7 @@ export class ZipNeutralinoWriter implements IBulkDownloadWriter {
|
|||
const reader = response.body.getReader();
|
||||
let receivedLength = 0;
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
for await (const value of readableStreamIterator(response.body)) {
|
||||
const chunk = value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);
|
||||
await bridge.filesystem.appendBinaryFile(savePath, chunk);
|
||||
receivedLength += value.length;
|
||||
|
|
|
|||
28
js/readableStreamIterator.ts
Normal file
28
js/readableStreamIterator.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Converts a ReadableStream into an async iterable iterator.
|
||||
* @template T The type of data chunks yielded from the stream.
|
||||
* @param stream The ReadableStream to convert into an async iterable.
|
||||
* @yields Chunks of data from the stream as they become available.
|
||||
* @example
|
||||
* ```typescript
|
||||
* const response = await fetch('https://example.com/data');
|
||||
* for await (const chunk of readableStreamIterator(response.body)) {
|
||||
* console.log(chunk);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export async function* readableStreamIterator<T>(stream: ReadableStream<T>): AsyncIterableIterator<T> {
|
||||
const reader = stream.getReader();
|
||||
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
|
||||
if (value) {
|
||||
yield value;
|
||||
}
|
||||
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue