parcel-bundler / parcel

The zero configuration build tool for the web. 📦🚀
https://parceljs.org
MIT License
43.52k stars 2.27k forks source link

bundle-text corruptions #9887

Open okwme opened 3 months ago

okwme commented 3 months ago

🐛 bug report

I'm using bundle-text to import and bundle an audio file (it's strange I know but I need the whole library in a single file). My method is converting the string into a Uint8Array and then use window.AudioContext to decodeAudioData. When the file is a wav it works (although quality sounds bad) and when I use mp3 I get the error Failed to execute 'decodeAudioData' on 'BaseAudioContext': Unable to decode audio data}. I tried converting the mp3 to base64 with an online service and saved the string that way. After converting from base64 with atob the decodeAudioData works. When I examine the difference between the bundle-text version of the string and the base64 version of the string I see small differences that makes me think bundle-text is corrupting the file or having trouble with a file of that size.

The start and end of the file after being converted from base64 looks like:

ID3\x04\x00\x00\x00\x00\x00#TSSE\x00\x00\x00\x0F\x00\x00\x03Lavf60.16.100\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ÿû@À\x00…ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª

Whereas the start and end of the file after being imported from bundle-text looks like:

ID3\x04\x00\x00\x00\x00\x00#TSSE\x00\x00\x00\x0F\x00\x00\x03Lavf60.16.100\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00��@�\x00…�������������������������������������������������

🎛 Configuration (.babelrc, package.json, cli command)

    "@parcel/transformer-inline-string": "2.12.0",
    "@parcel/optimizer-data-url": "2.12.0",
    "@parcel/transformer-inline": "^2.12.0",
    "parcel": "^2.12.0",
{
  "your": { "config": "here" }
}

🤔 Expected Behavior

I would expect the reading of the mp3 file as text to be convertible back into a playable file

😯 Current Behavior

Instead the file gets corrupted and is unable to be played as an audio file

💁 Possible Solution

Might be something to do with the size?

🔦 Context

I needed to inline mp3s so that I could ship a single file library despite being large.

💻 Code Sample

https://github.com/trifle-labs/anybody-problem


import { mp3example } from './files.js'
const fromBase64 = atob(mp3example)
console.log({ fromBase64 })

import whistle_8_T7 from 'bundle-text:/public/sound/whistle/whistle_8_T7.mp3'
console.log({ whistle_8_T7 })

let arrayBuffer = Uint8Array.from(whistle_8_T7, (e) => e.charCodeAt(0))
const audioContext = new window.AudioContext()
audioContext.decodeAudioData(
  arrayBuffer.buffer,
  (audioBuffer) => {
    // Now you have the AudioBuffer
    console.log('Decoded AudioBuffer:', audioBuffer)

    // You can now use the AudioBuffer, for example, to play the sound
    const source = audioContext.createBufferSource()
    source.buffer = audioBuffer
    source.connect(audioContext.destination)
    source.start(0)
  },
  (error) => {
    console.error('Error decoding audio data:', { error })
  }
)

🌍 Your Environment

Software Version(s)
Parcel ^2.12.0
Node v18.20.3
npm/Yarn yarn 1.22.22
Operating System Mac 14.5 (23F79)
okwme commented 3 months ago

Update: I saw the same problem when using bundle-text with font files. Similarly ended up manually encoding with base64 and importing them.