UNPKG

streamsaver

Version:

StreamSaver writes stream to the filesystem directly - asynchronous

100 lines (85 loc) 3.48 kB
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> </head> <body> <button id="$start">Start</button> <script src="https://cdn.jsdelivr.net/npm/web-streams-polyfill@2.0.2/dist/ponyfill.min.js"></script> <!-- includes blob.stream() polyfill while Also making File constructor work in some browser that don't support it --> <script src="https://cdn.jsdelivr.net/gh/eligrey/Blob.js/Blob.js"></script> <script src="../StreamSaver.js"></script> <script src="zip-stream.js"></script> <script> $start.onclick = () => { const fileStream = streamSaver.createWriteStream('archive.zip') const file1 = new File(['file1 content'], '/streamsaver-zip-example/file1.txt') // File Like object works too const file2 = { name: '/streamsaver-zip-example/file2.txt', stream () { // if you want to play it cool and use new api's // // const { readable, writable } = new TextEncoderStream() // writable.write('file2 content') // return readable return new ReadableStream({ start (ctrl) { ctrl.enqueue(new TextEncoder().encode('file2 generated with readableStream')) ctrl.close() } }) } } const blob = new Blob(['support blobs too']) const file3 = { name: '/streamsaver-zip-example/blob-example.txt', stream: () => blob.stream() } // Ideally world i would just have done something like TextEncoderStream // where you would get { readable writable } = new ZIP() // // readable would be piped to streamsaver, and the writer would accept // file-like object, but that made it dependent on WritableStream... // // So i built ZIP-Stream simular to a ReadbleStream but you enqueue // file-like objects meaning it should have at at the very least name, stream() // // it supports pull() too that gets called when it ask for more files. // // NOTE: My zip library can't generate zip's over 4gb and has no compresseion // it was built solo for the purpus of saving multiple files in browser const readableZipStream = new ZIP({ start (ctrl) { ctrl.enqueue(file1) ctrl.enqueue(file2) ctrl.enqueue(file3) ctrl.enqueue({name: '/streamsaver-zip-example/empty folder', directory: true}) // ctrl.close() }, async pull (ctrl) { const url = 'https://d8d913s460fub.cloudfront.net/videoserver/cat-test-video-320x240.mp4' const res = await fetch(url) const stream = () => res.body const name = '/streamsaver-zip-example/cat.mp4' ctrl.enqueue({ name, stream }) ctrl.close() } }) // more optimized if (window.WritableStream && readableZipStream.pipeTo) { return readableZipStream.pipeTo(fileStream).then(() => console.log('done writing')) } window.writer = fileStream.getWriter() const reader = readableZipStream.getReader() const pump = () => reader.read() .then(res => res.done ? writer.close() : writer.write(res.value).then(pump)) pump() } </script> </body> </html>