Denver Kunaka
Denver Kunaka

Reputation: 19

NodeJs base64 string incorrect

I'm trying to encode an mp3 file to base64. I'm reading file line by line using createInterface and then concatenate the strings.

I then base64 encode the string using new Buffer(str).string('base64')

The encoded base64 is incorrect with + signs at every line read (assumption)

PHP base64 is working fine.

The Node generated base64 SUQzAwAAAAZVbFRJVDIAAABOAAAATG92ZSBZb3UgVG9uaWdodCBmdC4gS2FiemEgRGUgU21hbGwsIERKIE1hcGhvcmlzYSAmIFNoYXNoYSB8IHd3dy5iZWF0emphbS5jb21UUEUxAAAAIwAAAFtCZWF0ekphbV1NRlIgU291bHMgfCBiZWF0emphbS5jb21UQUxCAAAAEQAAAHd3dy5iZWF0emphbS5jb21UWUVSAAAABQAAADIwMTlUQ09OAAAADgAAAFBlcmZlY3QgTXVzaWNDT01NAAAAJQAAAGVuZwBEb3dubG9hZGVkIEZyb20gd3d3LmJlYXR6amFtLmNvbUFQSUMAAXTvv70AAABpbWFnZS9qcGVnAABEb3dubG9hZGVkIEZyb20gd3d3LmJlYXR6amFtLmNvbQDvv73vv73vv73vv70AEEpGSUYAAQEAAAEAAQAA77+977+9AO+

PHP base64

SUQzAwAAAAZVbFRJVDIAAABOAAAATG92ZSBZb3UgVG9uaWdodCBmdC4gS2FiemEgRGUgU21hbGwsIERKIE1hcGhvcmlzYSAmIFNoYXNoYSB8IHd3dy5iZWF0emphbS5jb21UUEUxAAAAIwAAAFtCZWF0ekphbV1NRlIgU291bHMgfCBiZWF0emphbS5jb21UQUxCAAAAEQAAAHd3dy5iZWF0emphbS5jb21UWUVSAAAABQAAADIwMTlUQ09OAAAADgAAAFBlcmZlY3QgTXVzaWNDT01NAAAAJQAAAGVuZwBEb3dubG9hZGVkIEZyb20gd3d3LmJlYXR6amFtLmNvbUFQSUMAAXTDAAAAaW1hZ2UvanBlZwAARG93bmxvYWRlZCBGcm9tIHd3dy5iZWF0emphbS5jb20A/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAYGBgYHBgcICAcKCwoLCg8ODAwODxYQERAREBYiFRkVFRkVIh4kHhweJB42KiYmKjY+NDI0PkxERExfWl98fKcBBgYGBgcGBwgIBwoLCgsKDw4MDA4PFhAREBEQFiIVGRUVGRUiHiQeHB4kHjYqJiYqNj40MjQ+TERETF9aX3x8p//CABEIBAAEAAMBIgACEQEDEQH/xAAxAAEAAwEBAQAAAAAAAAAAAAAAAQIDBAUGAQEBAQEBAQAAAAAAAAAAAAAAAQIDBAX/2gAMAwEAAhADEAAAAvZmJ+H6wAoAAKTEgAIFAAEiJCCsWkoAAEAJAUEAEkiQAAAAEkJEJEJEJEAAAhIhIgKAAiRCYAAAUACEiEiAAAABKiRAAgAIARMEgACgApIBYAAASqEgAIACgARIAAACZIkABJCQAACABAUAAACwkQkQABEiEiBQLCRAgAFACgESISITEAAAIlLAAgAIAACgAElBYBIoAAAAAEiLVzbDUASAAACRAgkAAgAmISIkAAAAAESITFAAAoEJgCkSITACgImAAAAFAAAAAgAQEsACAAgKAAJUFiYmgAAQLQAkAJEJEJAAAAEhAEgEgBIAEpCQAAJITAAAiRCRCYAWEiABbCRAAITACgIkQkQkQmAAALQkBQESIEQlLAgAAABMTQWJKCwkQlUJESCJEJQAAAAAJSJAIEgIASgAkgAkiRCVQkQmaqsKpRCYAiElhMAEJEBYSITFAsJEARKoTACgAAQkQkQlUJEJEJECVEogQiYlCAAAqRYSoLElAAAAAAAABISAAoSBIJISCSQkRMohM2VmREpSEzpCZ1ITO1VmpVZVVowqtGLVZi0WRVYtYsKrIqsqqS1WghIqtCwkREqhJYAiRAAAUAAAABEiBCJSwIhMShAEjUJUFiSkmoATAEAAAAACTz+fu4e2envx2xWHQjweyl+2fTJ5WPJ9fy+k5Pc871bCWUTh0VEps+W+j8b1+jeZYnm49OfR6UykjyPY8fb0ejz/AENRzdLTxPb4PQIi0R4vf5vrZuqWEeZ18x6KWVfC9zxbfann6Yjg9DiPG9/m61vFowhhusJZeT2cnXpumOeuXz

Here is a sample code

var interface = readline.createInterface({
input: fs.createReadStream(file)
}),
str = '';

interface.on('line', (line)=>{
    str += line;
} )

interface.on('close',()=>{
var base =  new Buffer.from(str).toString('base64');
res.send(  `<audio autoplay controls><source src="data:audio/mp3;base64,${base}"></source></audio>` )
   
})

Upvotes: 1

Views: 2800

Answers (3)

vazsonyidl
vazsonyidl

Reputation: 471

Try with: const encoded = Buffer.from(stringValue, 'base64').toString();

Or atob() and btoa() functions (on client side). Here is the docs.

Upvotes: 0

jps
jps

Reputation: 22465

The combination of readLine.createInterface and fs.createReadStream doesn't make much sense, as createReadStream already fires events like data, error and end.

The problem is also that you read by line, but that's not how you could read a binary file. How would you define a line in a binary (here .mp3) file? The code seems to read chunks of data of different size (whatever it considers a line), and appends a string. Probably the byte that is interpreted as line end gets lost.

And lastly, you would also get in trouble when the files is very large, because you add everything to a string and then create a buffer from it and output it at once. So it would require more than 3 times the size of your mp3 file in memory.

The solution below only uses fs.createReadStream and limits the size of a chunk to 60.000 bytes by setting the {highWaterMark : 60000}.

Note: the default size is 65536, but that would not work for the following base64 encoding. The data size must be a multiple of 3!

The received data is a buffer, which can be converted to base64directly.

const fs = require('fs');
var file = "test.mp3";

let stream = fs.createReadStream(file, {highWaterMark : 60000});

stream.on('data', (data) => {
    console.log("data length " + data.length)
    var base = data.toString('base64');
    fs.appendFile('test.b64', base, function (err,data) {
        if (err) {
          return console.log(err);
        }
        console.log("wrote " + base.length + " bytes");
      })  

}).on('error', err => {
    console.log(err);
}).on('end', () => {
    console.log("success");
});

Upvotes: 0

IronMan
IronMan

Reputation: 1960

perhaps use Buffer.from(str).toString('base64')

Upvotes: 2

Related Questions