Node.js can't create Blobs? [duplicate]
Asked Answered
B

4

143

I am working with node.js and I streamed my Audio to my node.js server. Now I noticed during the process of building the audio blob:

var audioBlob = new Blob([dataview], { type: 'audio/wav' });

That I get a ReferenceError at new Blob. It seems that Blob is not supported. How can I create a blob which I would like to save with node.js fs module?

Butcher answered 1/2, 2013 at 19:8 Comment(8)
What is Blob? Where does it come from?Swingeing
All common browser support it developer.mozilla.org/de/docs/DOM/BlobButcher
Yeah, but a blob isn't a native Node.js type.. You know, Number, String, Boolean, Object, Array, etc. Why don't you create an object prototype or a module for NPM? Did you check NPM for anything like what you need?Barbour
I found a Blobbuilder module but it is outdated and not working.Thats why I am asking if there is a way to create a Blob inside node.js. I haven´t built a wav file object prototype yet.Butcher
Try Buffer. Blob isn't available because it's defined by a DOM API and Node is not a DOM implementation.Chessboard
@Jonathan I will have a look on this, but is it possible to define the MIME type?Butcher
@Butcher Yes and no. You can always add a mime property to the Buffer since it's still dynamic. But, MIME types are for communicating binary data; not so much for saving to disk.Chessboard
var bufferL = mergeBuffers(recBuffersL, recLength); var bufferR = mergeBuffers(recBuffersR, recLength); var interleaved = interleave(bufferL, bufferR); var dataview = encodeWAV(interleaved); //var audioBlob = new Blob([dataview], { type: 'audio/wav' }); Here is the example. Your suggestion is to create a buffer and then use fs.writeFile('test.wav', <buffer variable>, function(err){ if (err) console.log(err); }); ?Butcher
D
43

Since Node.js 18, Blob is immediately accessible as a global:

new Blob([]);
//=> Blob {size: 0, type: ''}

Otherwise, since Node.js 16, Blob can be imported:

import {Blob} from 'node:buffer';

new Blob([]);
//=> Blob {size: 0, type: ''}

Otherwise, just use cross-blob:

import Blob from 'cross-blob';
 
new Blob([]);
//=> Blob {size: 0, type: ''}
 
// Global patch (to support external modules like is-blob).
globalThis.Blob = Blob;
Dael answered 16/11, 2019 at 23:35 Comment(6)
Error:Must use import to load ES ModulesOptic
cross-blob now uses ESM - updated the answerDael
Blob is the default export of cross-blob, its just import Blob from 'cross-blob'Ardine
isn't cross-blob just using fetch-blob?Marbling
Yes, it is most useful for cross-platform situations where you don't know whether you are running in Node.js or the browser.Dael
But how to import in express server.js which is not a module so I cant import BlobSprayberry
S
11
Note: This answer only applies if you want to follow the Richie Bendall's answer.

Short answer:

Avoid importing Blob from 'node:buffer'.

Instead, prefer importing it like this (as explained in the NodeJS docs. (implementation example here)):

import { Blob } from 'buffer';

Long answer:

The Richie Bendall's answer helped me a lot. But it seems that importing Blob from node:buffer breaks the Jest unit tests, throwing this error:

 FAIL  dist/tests/unit/users/getOneById.spec.js
  ● Test suite failed to run

    ENOENT: no such file or directory, open 'node:buffer'

      2 | import config from '../config/config';
      3 | import { getFileExt, getFileName, removeFile } from './file';
    > 4 | import { Blob } from 'node:buffer';
        | ^
      5 |
      6 | class PdfHelpers {
      7 |

      at Runtime.readFile (node_modules/jest-runtime/build/index.js:2118:21)
      at Object.<anonymous> (src/helpers/pdf.ts:4:1)

Instead of trying to mock the node:buffer import with some weird/tricky code, I took a look at the NodeJS documentation examples. So it demonstrates that Blob can be imported from 'buffer'

import { Blob } from 'buffer';

// ...

// Only the import is changing, don't change your existing implementation
const blob = new Blob([buf], { type: 'application/pdf' });

And all Jest errors have been gone away!

Sheldon answered 30/8, 2021 at 10:28 Comment(3)
Importing with the node: protocol appears to have been fixed in Jest 27.1.0 which was released only 3 days before this answer was posted. github.com/facebook/jest/releases/tag/v27.1.0Dael
Can you help fix module '"buffer"' has no exported member 'Blob'.ts(2305)Dosh
@Dosh I would say it's due to the Node version you're using, but you have a topic on this issue here: https://mcmap.net/q/161393/-module-39-quot-buffer-quot-39-has-no-exported-member-39-blob-39 which suggests to set your package.json dependency for @types/node to "@types/node": "^16.0.0".Sheldon
I
-1

You can try use Readable.from(value.buffer) from "stream" node api.

It solved to me on FormData append file to send.

Iridaceous answered 3/1, 2023 at 14:26 Comment(0)
P
-2

Another solution to consider is to use a Base64 String to transfer data from the Server to the client.

I am working on a Node.js project where I receive audio data in the form of an ArrayBuffer, and I want to send and play that data in the browser. Most of my struggles came from trying to send the ArrayBuffer to the client or trying to convert the ArrayBuffer and send a Buffer.

What ended up being a simple solution for me was to

  1. Convert the ArrayBuffer to a Base64 encoded String on the Server
  2. Return/Send the Base64 String to the client from the server
  3. Create an Audio element/object on the client side and play the sound

I used base64-arraybuffer to perform the ArrayBuffer > Base64 String conversion (though, it may be simple to do this without a package).

I used tips from here to create the audio element on the client side.

*I haven't done much in the way of testing limits - so I don't know how this might handle large audio files.

Priscian answered 1/5, 2020 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.