{"record":{"id":"e1f71cffcd88d049","repo":"libgdx/libgdx","slug":"error-while-preloading-mp3","errorCode":null,"errorMessage":"Error while preloading MP3","messagePattern":"Error while preloading MP3","errorType":"exception","errorClass":"GdxRuntimeException","httpStatus":null,"severity":"error","filePath":"backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/audio/Mp3.java","lineNumber":52,"sourceCode":"\n\t\tprivate Bitstream bitstream;\n\t\tprivate OutputBuffer outputBuffer;\n\t\tprivate MP3Decoder decoder;\n\n\t\tpublic Music (OpenALLwjglAudio audio, FileHandle file) {\n\t\t\tsuper(audio, file);\n\t\t\tif (audio.noDevice) return;\n\t\t\tbitstream = new Bitstream(file.read());\n\t\t\tdecoder = new MP3Decoder();\n\t\t\ttry {\n\t\t\t\tHeader header = bitstream.readFrame();\n\t\t\t\tif (header == null) throw new GdxRuntimeException(\"Empty MP3\");\n\t\t\t\tint channels = header.mode() == Header.SINGLE_CHANNEL ? 1 : 2;\n\t\t\t\toutputBuffer = new OutputBuffer(channels, false);\n\t\t\t\tdecoder.setOutputBuffer(outputBuffer);\n\t\t\t\tsetup(channels, 16, header.getSampleRate());\n\t\t\t} catch (BitstreamException e) {\n\t\t\t\tthrow new GdxRuntimeException(\"Error while preloading MP3\", e);\n\t\t\t}\n\t\t}\n\n\t\tpublic int read (byte[] buffer) {\n\t\t\ttry {\n\t\t\t\tboolean setup = bitstream == null;\n\t\t\t\tif (setup) {\n\t\t\t\t\tbitstream = new Bitstream(file.read());\n\t\t\t\t\tdecoder = new MP3Decoder();\n\t\t\t\t}\n\n\t\t\t\tint totalLength = 0;\n\t\t\t\tint minRequiredLength = buffer.length - OutputBuffer.BUFFERSIZE * 2;\n\t\t\t\twhile (totalLength <= minRequiredLength) {\n\t\t\t\t\tHeader header = bitstream.readFrame();\n\t\t\t\t\tif (header == null) break;\n\t\t\t\t\tif (setup) {\n\t\t\t\t\t\tint channels = header.mode() == Header.SINGLE_CHANNEL ? 1 : 2;","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/libgdx/libgdx/blob/97f40861878058087be0685ca167ddfde132134b/backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/audio/Mp3.java#L34-L70","documentation":"Thrown by Mp3.Music's constructor when the first readFrame() raises a javazoom.jl.decoder.BitstreamException — JLayer's parser choked on the bitstream before a frame could even be examined (the null-header 'Empty MP3' case is separate). The cause is chained so the underlying parse error (e.g. INVALID_FRAME, BITSTREAM_LAST) is visible.","triggerScenarios":"new Music(...) where file.read() yields data that breaks JLayer's bitstream parser: truncated mid-header files, corrupted ID3v2 tags with wrong sizes, or non-MP3 bytes.","commonSituations":"Partially downloaded/streamed MP3s; assets corrupted in transfer (FTP text mode); large ID3v2 tags with embedded art that JLayer 1.0.1 mishandles.","solutions":["Re-obtain the MP3 from a trusted source and verify integrity (checksum or re-encode via ffmpeg)","Strip oversized/complex ID3 tags (ffmpeg -i in.mp3 -c copy -map_metadata -1 out.mp3) to rule out tag parsing issues","If files are fetched over the network at runtime, download fully before calling newMusic (or check Content-Length)","Catch GdxRuntimeException around Gdx.audio.newMusic and skip/fallback the track so one bad asset doesn't kill the app"],"exampleFix":"# before\n# track.mp3 truncated at 30% -> BitstreamException -> \"Error while preloading MP3\"\n\n# after\nffmpeg -i track.mp3 -c copy -map_metadata -1 track_clean.mp3\n# full re-encode if still failing:\nffmpeg -i track.mp3 -codec:a libmp3lame -qscale:a 4 track_clean.mp3","handlingStrategy":"try-catch","validationCode":"// cheap sanity check before loading\nFileHandle f = Gdx.files.internal(\"s.mp3\");\nboolean plausible = f.length() > 4096;\n// full validation requires decoding; use a tool at build time instead (ffmpeg -v error)","typeGuard":null,"tryCatchPattern":"try {\n    music = Gdx.audio.newMusic(f);\n} catch (GdxRuntimeException e) {\n    if (e.getCause() instanceof javazoom.jl.decoder.BitstreamException) {\n        Gdx.app.error(\"Audio\", \"corrupt mp3: \" + f, e);\n    }\n}","preventionTips":["Run ffmpeg -v error -i asset.mp3 -f null - over audio assets in CI","Strip heavy ID3 artwork tags from game assets","Ship OGG where possible; the JLayer MP3 path is the most fragile"],"tags":["audio","mp3","jlayer","corruption","asset"],"backgroundTag":null,"analyzedSha":"97f40861878058087be0685ca167ddfde132134b","analyzedAt":"2026-08-14T10:52:53.492Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}