aiscy
aiscy

Reputation: 143

vlcj - How to change the volume of audio before playing it?

I tried this

val player: MediaPlayer = MediaPlayerFactory("-vvv").mediaPlayers().newMediaPlayer()
val result0: Boolean = player.audio().setVolume(50) // result0: true
player.media().play("/path/to/audio.ogg")
val result1: Boolean = player.audio().setVolume(50) // result1: false

and this

val player: MediaPlayer = MediaPlayerFactory("-vvv").mediaPlayers().newMediaPlayer()
val result0 = player.audio().setVolume(50) // result0: true
player.media().prepare("/path/to/audio.ogg")
val result1: Boolean = player.audio().setVolume(50) // result1: false
player.controls().play()
val result2: Boolean = player.audio().setVolume(50) // result2: false

but the volume remains at 100%. The only way I found is to make something like this

val player: MediaPlayer = MediaPlayerFactory("-vvv").mediaPlayers().newMediaPlayer()
player.events().addMediaPlayerEventListener(object : MediaPlayerEventAdapter() {
    override fun mediaPlayerReady(mediaPlayer: MediaPlayer) {
        mediaPlayer.submit {
            mediaPlayer.audio().setVolume(50)
        }
    }
})
player.media().play("/path/to/audio.ogg")

But the solution is a bit far from ideal. Because it starts to play, plays a bit, and then whoosh, the volume has changed.

I tried vlcj 4.4.0 and 4.5.2, VLC 3.0.8 and 3.0.10, jdk8 and 14, but it works in the same way.

Upvotes: 1

Views: 945

Answers (1)

caprica
caprica

Reputation: 4146

This is something that unfortunately does not work in VLC 3.x, but does work in the upcoming VLC 4.x (at the time of writing this answer, VLC 4 is still in development).

The following code works for me using the latest VLC 4 built from source, and the latest vlcj-5 snapshot:

import uk.co.caprica.vlcj.player.component.AudioPlayerComponent;
import uk.co.caprica.vlcj.test.VlcjTest;

public class AudioMediaPlayerComponentTest extends VlcjTest {

    public static void main(String[] args) throws Exception {
        String mrl = "/home/music/some-cool-synthwave-tune.mp3";

        AudioPlayerComponent audioMediaPlayerComponent = new AudioPlayerComponent();
        audioMediaPlayerComponent.mediaPlayer().audio().setVolume(5);
        audioMediaPlayerComponent.mediaPlayer().media().play(mrl);

        Thread.currentThread().join();
    }
}

The initial volume for the media player comes from the OS volume settings, and in fact the OS volume setting is linked both ways to the media player. Changing the volume in one place is reflected in the other.

Volume handling through LibVLC generally just seems much better in VLC 4.

If you're stuck on VLC 3, which is reasonable at the present time, then unfortunately you're also stuck with some sort of compromise solution like using the "ready" event that you've already found.

All the ready event does is to wait for the first position-changed event, and that event was created specifically as a compromise for purposes like this.

I tested all the native event callbacks available for the media player, and nothing worked to set the volume before playback had actually started.

This leaves you with the following, as you already found:

import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.component.AudioPlayerComponent;
import uk.co.caprica.vlcj.test.VlcjTest;

public class AudioMediaPlayerComponentTest extends VlcjTest {

    public static void main(String[] args) throws Exception {
        String mrl = "/home/music/some-cool-synthwave-tune.mp3";

        AudioPlayerComponent audioMediaPlayerComponent = new AudioPlayerComponent() {
            @Override
            public void mediaPlayerReady(MediaPlayer mediaPlayer) {
                mediaPlayer.audio().setVolume(30);
            }
        };

        audioMediaPlayerComponent.mediaPlayer().media().play(mrl);

        Thread.currentThread().join();
    }
}

A completely sideways alternative might be to play the shortest possible silent media as a kind of pre-roll - when that media is finished (there's a finished or stopped event you can listen for) you should then be able to set the volume and play your actual media. I did not try this.

Upvotes: 2

Related Questions