Search code examples
javavlcj

In vlcj, what's the "level" get by the AudioTrackInfo?


I'm discovering vlcj and make some try with the methods and the tutorials. I'm looking for the "sound pressure level" (like in VUMeters). In the AudioTrackInfo, I found and interesting method called "Level". But it returns 0. Why ? Does this level is the "sound pressure" I'm looking for ? If not, how to get that value ?

Here is my simple (and dirty) code used for the trial :

import java.util.List;

import uk.co.caprica.vlcj.component.AudioMediaPlayerComponent;
import uk.co.caprica.vlcj.player.AudioTrackInfo;
import uk.co.caprica.vlcj.player.MediaPlayer;
import uk.co.caprica.vlcj.player.MediaPlayerEventAdapter;
import uk.co.caprica.vlcj.player.TrackInfo;
import uk.co.caprica.vlcj.player.TrackType;

public class BasicAudioPlayer {

private final AudioMediaPlayerComponent mpc;
private static String[] playList = new String[] {
        "Sam Brown - Stop (Official Music Video) - YouTube.mp3",
        "Bon Jovi - Bed Of Roses - YouTube.mp3",
        "Kendji Girac - Conmigo - YouTube.mp3",
        "http://live.radiooxygene.fr:7710/"};

private BasicAudioPlayer() {
    mpc = new AudioMediaPlayerComponent();

    mpc.getMediaPlayer().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
        @Override
        public void stopped(MediaPlayer mediaPlayer) {
            exit(0);
        }

        @Override
        public void finished(MediaPlayer mediaPlayer) {
            exit(0);
        }

        @Override
        public void error(MediaPlayer mediaPlayer) {
            exit(1);
        }
    });

}

private void prepare(String mrl) {
    mpc.getMediaPlayer().prepareMedia(mrl);
    mpc.getMediaPlayer().parseMedia();

}

private void start(String mrl) {
    mpc.getMediaPlayer().playMedia(mrl);
    //I introduce a threadsleep just for the trial
    //to be sure that I'm not in the fade-in of the song
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    List<TrackInfo> trackInfo = mpc.getMediaPlayer().getTrackInfo(TrackType.AUDIO);
    for (TrackInfo track : trackInfo) {
        if (track instanceof AudioTrackInfo) {
            AudioTrackInfo audioTrack = (AudioTrackInfo) track;
            System.out.println(audioTrack.toString());
            System.out.println(audioTrack.level());
        }
    }
}

private void exit (int result) {
    mpc.release();
    System.exit(result);
}

public static void main(String[] args) {
    BasicAudioPlayer bap = new BasicAudioPlayer();
    bap.prepare(playList[2]);
    bap.start(playList[2]);
    try {
        Thread.currentThread().join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

}

Thank you for all your answers. Regards.


Solution

  • I don't know precisely what that "level" attribute is, but it's something like the encoder level used to prepare the track.

    Whatever it is, it's not what you're looking for.

    To get the "pressure" data you want, you need to use the "direct" audio player - this gives you access to the native audio sample buffer which you can then do your frequency analysis on.

    The downside is that if you capture the audio sample data like this, then VLC will not actually play the audio - you must play it yourself.

    For vlcj this basically means playing it using a Java API. For example, the JavaSound API can play it. There is an example in the vlcj test sources that shows this. There is too much code to reproduce it in this answer, you can find it here:

    https://github.com/caprica/vlcj/tree/master/src/test/java/uk/co/caprica/cj/test/directaudio