Skip to content

TamKungZ/jlayer-custom

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JLayer - TamKungZ_ Custom Fork

Java Status License JitPack MvnRepository

mp3 logo small

main logo

MP3 Decoder in pure Java - Enhanced for reliable playback in Minecraft mods

Fork Purpose: Fixed critical ArrayIndexOutOfBoundsException affecting VBR and high-bitrate MP3 files. Built for Rhythm mod but works as drop-in replacement for any JLayer use case.


What's Fixed

Critical Bug: ArrayIndexOutOfBoundsException

Index 433 out of bounds for length 433
at javazoom.jl.decoder.Bitstream.getBits()

Root Cause: Original code used fixed buffer size (433) for bounds checking, but MP3 frames have variable sizes (especially VBR).

Solution: Check against actual frameSize for each frame instead of buffer capacity.

Impact:

  • ✅ VBR MP3s now work correctly
  • ✅ 320kbps files no longer crash
  • ✅ LAME-encoded files play reliably
  • ✅ Success rate: ~30% → 95%+

Changes in Bitstream.getBits()

// Before: Fixed bounds (WRONG for VBR)
if (wordPointer >= frameBuffer.length)  // Always 433

// After: Dynamic bounds (CORRECT)
int maxWords = (frameSize + 3) / 4;     // Actual frame size
if (wordPointer >= maxWords)

Installation

Maven Central (Recommended)

Maven

<dependency>
    <groupId>io.github.tamkungz</groupId>
    <artifactId>jlayer-custom</artifactId>
    <version>1.0.2.2</version>
</dependency>

Gradle

repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.github.tamkungz:jlayer-custom:1.0.2.2'
}

Gradle Kotlin DSL

repositories {
    mavenCentral()
}

dependencies {
    implementation("io.github.tamkungz:jlayer-custom:1.0.2.2")
}

Alternative: JitPack

Maven

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.tamkungz</groupId>
    <artifactId>jlayer-custom</artifactId>
    <version>1.0.2.2</version>
</dependency>

Gradle

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.tamkungz:jlayer-custom:1.0.2.2'
}

Version Notes

However, for the best user experience, we recommend using the latest version.

1.0.2.x
The 1.0.2.* line focuses solely on fixing issues from the original JLayer implementation. There are no new features or behavioral changes. If your project previously used JLayer (2010–2024), this version is recommended for maximum compatibility.

1.0.5+
Version 1.0.5 includes several internal improvements aimed at better performance. While execution efficiency is enhanced, some legacy code that depends on the original JLayer behavior may require minor adjustments.


Enhancements

1. Robust Bounds Checking

  • Input parameter validation (number_of_bits <= 0)
  • Dynamic frame size calculation for VBR support
  • Safe handling of partial frames at buffer boundaries
  • Prevents pointer overflow in multi-word reads

2. Graceful Error Recovery

  • Returns safe values instead of crashing
  • Allows decoder to skip corrupted frames
  • Maintains valid internal state after errors

3. New API Methods

  • BitstreamException(Throwable): Better error chaining
  • Bitstream.isClosed() / isEOF(): State management
  • Player.isClosed(): Check player state
  • jlp.stop(): Controlled playback shutdown
  • jlp.getPlayer(): Access underlying Player instance
  • jlp.isPlaying(): Check active playback status
  • Enhanced VBR header parsing
  • Improved thread safety and resource cleanup

4. No API Changes

  • 100% compatible with original JLayer
  • Drop-in replacement - just change dependency
  • All existing code works without modification

Testing

Tested with 254+ diverse MP3 files:

  • ✅ CBR: 128kbps, 192kbps, 320kbps
  • ✅ VBR: LAME v3.98+, modern encoders
  • ✅ Various sample rates: 44.1kHz, 48kHz, 32kHz
  • ✅ Stereo and mono files
  • ✅ Files with ID3v1/v2 tags and no tags

Comprehensive Test Suite (JUnit 5):

  • BitstreamTest: Header parsing, frame reading, state management
  • BitstreamEdgeCaseTest: Edge cases, concurrent access, large reads
  • JavaSoundAudioDeviceTest: Audio device creation and registry
  • jlpTest: Playback, volume control, thread safety

Before fix: ~30% success rate (crashes on VBR/320kbps)
After fix: 95%+ success rate


License

LGPL (same as original JLayer)


Credits


Original README (Click to expand)

DESCRIPTION

JLayer is a library that decodes/plays/converts MPEG 1/2/2.5 Layer 1/2/3 (i.e. MP3) in real time for the JAVA(tm) platform. This is a non-commercial project and anyone can add his contribution. JLayer is licensed under LGPL (see LICENSE).

Usage

FAQ

Do I need JMF to run JLayer player?

No, JMF is not required. You need a Java 17+ runtime with JavaSound 1.0 compliance.

How to run the MP3TOWAV converter?

java javazoom.jl.converter.jlc -v -p output.wav yourfile.mp3

How to run the simple MP3 player?

java javazoom.jl.player.jlp localfile.mp3

or

java javazoom.jl.player.jlp -url http://www.aserver.com/remotefile.mp3

How to run the advanced (threaded) MP3 player?

java javazoom.jl.player.advanced.jlap localfile.mp3

Does simple MP3 player support streaming?

Yes, use the following command to play music from stream:

java javazoom.jl.player.jlp -url http://www.shoutcastserver.com:8000

Does JLayer support MPEG 2.5?

Yes, it works fine for all files generated with LAME.

Does JLayer support VBR?

Yes, It supports VBRI and XING VBR header too.

How to get ID3v1 or ID3v2 tags from JLayer API?

The API provides a getRawID3v2() method to get an InputStream on ID3v2 frames.

How to skip frames to have a seek feature?

<<<<<<< HEAD

See javazoom.jl.player.advanced.jlap source to learn how to skip frames.

Project Homepage

http://www.javazoom.net/javalayer/javalayer.html

JAVA and MP3 online Forums

http://www.javazoom.net/services/forums/index.jsp

Packages

No packages published

Languages

  • Java 99.6%
  • Python 0.4%