caprica / vlcj

Java framework for the vlc media player
http://www.capricasoftware.co.uk/projects/vlcj
1.13k stars 259 forks source link

vlcj properlly calling the overided "public void muted" method. #1079

Closed courteous closed 3 years ago

courteous commented 3 years ago

Hello Mark,

after reading several closed issues i.e. 835, 395, 901 I am still facing a problem with the muting the video stream. example code I define a global variable private EmbeddedMediaPlayer embeddedMediaPlayer;

and then in a a particular method i initialize the media player

            this.mediaPlayerFactory = new MediaPlayerFactory( this.myVlcDebugVariable);
        this.embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();

            this.embeddedMediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {

                @Override
                public void muted(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayerObj, boolean muted) {
                    System.out.println("Trying to mute the embeddedMediaPlayer audio ");
                    mediaPlayerObj.audio().mute();
                }

                @Override
                public void finished(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayerObj) {
                    System.out.println("embeddedMediaPlayer finished  playing");

                }

            });

in another method of the same class i call

`this.embeddedMediaPlayer.audio().setMute(true);`

or this.embeddedMediaPlayer.audio().mute();

but nothing is muted at all. How to call the overrided "public void muted" event properly?

I do have 2 media player factories and 2 separate embeddedMediaPlayers. From the previous examples i understood that the expected behavior is that bought of the embeddedMediaPlayers will be muted. However in my example noting is muted at all. Should something else be done except adding the mute event trough the MediaPlayerEventAdapter? Is there any working example or some test where i can take a peek?

I am using version 4.7.1. i.e.

    <dependency>
        <groupId>uk.co.caprica</groupId>
        <artifactId>vlcj</artifactId>
        <version>4.7.1</version>
    </dependency>
caprica commented 3 years ago

Using mute() is only useful if you know for sure what the current mute state is. So I would only recommend using setMute(true|false).

As far as I can remember, with VLC 3.x you can't reliably change audio before the playback has started - I am not 100% sure this is still the case, but it certainly used to be so.

courteous commented 3 years ago

Hello Mark,

I do not thing that setMute is working correctly, muting does working but setting it back to unmute does not work. At least not on Windows 10. Here is a code example with the proof. I.e. this code stops at line "embeddedMediaPlayer.audio().setMute(false);"


final CountDownLatch sync = new CountDownLatch(1);

        String file = "file:///C:/Users/Courteous/Downloads/Music.wav";

        MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory("-vvv");
        EmbeddedMediaPlayer embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();

        uk.co.caprica.vlcj.player.base.MediaApi mediaApi = embeddedMediaPlayer.media();

        embeddedMediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
            @Override
            public void error(MediaPlayer mediaPlayerObj) {
                System.out.println("Error event called.");
                sync.countDown();
            }

            @Override
            public void finished(MediaPlayer mediaPlayerObj) {
                System.out.println("Finished event called.");
                sync.countDown();
            }

            @Override
            public void muted(MediaPlayer mediaPlayerObj, boolean muted) {
                System.out.println("Muted event called.");
                mediaPlayerObj.audio().mute();
                mediaPlayerObj.audio().setMute(false);

            }

            @Override
            public void volumeChanged(MediaPlayer mediaPlayerObj, float volume) {
                System.out.println("volume event called.");
                mediaPlayerObj.audio().setVolume(0);
            }

        });

        Boolean prepared = mediaApi.prepare(file);
        System.out.println("Is correctly prepared " + prepared);
        Boolean isPlaying  = mediaApi.play(file);
        System.out.println("Is playing  " + isPlaying);

        if (isPlaying) {
            embeddedMediaPlayer.audio().setMute(true);

        }

        boolean isPlayingClip = embeddedMediaPlayer.status().isPlaying();
        if (isPlayingClip) {
            embeddedMediaPlayer.audio().setMute(false);

        }
        try {
            sync.await();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        embeddedMediaPlayer.controls().stop();
        embeddedMediaPlayer.release();
        mediaPlayerFactory.release();

        System.out.println("end");
caprica commented 3 years ago

I don't see proof of anything. What do you mean it "stops"?

courteous commented 3 years ago

Well with the following line "embeddedMediaPlayer.audio().setMute(true);"

the embededPlayer is indeed beeing muted, and the sound is not played trough the speakers, but I was expecting that the line embeddedMediaPlayer.audio().setMute(false); will unmute the Player, but that does not occur. Or do i have some logical error?

caprica commented 3 years ago

So is isPlayingClip true or false?

courteous commented 3 years ago

isPlayingClip is true, i set up a breakpoint in order to make sure that the line embeddedMediaPlayer.audio().setMute(false); is beeing runned.

I have here short WAV clip that is about 3 minutes long to test this.

courteous commented 3 years ago

and basically in that moment i was expecting that the sound will resume trough the speakers

caprica commented 3 years ago

vlcj does this:

public void setMute(boolean mute) {
    libvlc_audio_set_mute(mediaPlayerInstance, mute ? 1 : 0);
}

Not much can go wrong there.

caprica commented 3 years ago

You should really be doing something event-based anyway, like listening for an audio elementary stream created event or something.

Not sure which version of LibVLC those events came with though.

courteous commented 3 years ago

do you know how can i debug the libvlc call, how this can be done shell i use GCC? Can you give an example of that listening for an audio elementary stream. I would like to try this.

caprica commented 3 years ago

I know with 100% certainty, that under normal conditions, the setMute(true|false) call works.

It is not for me to tell you how to use gdb, but you could do that if you wanted. In the past, I have debugged problems like this by adding log statements to VLC itself and running my own specially-built VLC - that is not so hard these days, you can even get a pre-made Docker container to do your build for you. I don't use Docker for that, so that would be your choice.

In your specific case however, I don't think you will get much from it. Probably this issue is due to some condition where at some particular time the audio output does not want to let you change the volume controls.

If you check the vlcj-player project and run it, it has mute controls - if that does NOT work for you, then that shows a problem with your VLC. If it does work, it shows some problem with your own application's usage of vlcj/LibVLC.

courteous commented 3 years ago

Hello Mark,

thanks for the feedback. I think you are right i will leave the gcc and try to take a peek into the vlcj-player project and particularly the

class final class MuteAction extends MediaPlayerAction .

I will try to extend from the same class and see if that will help.

Many thanks for the help and the feedback.

caprica commented 3 years ago

I would also strongly advise you to try and use events rather than that status API - this is because a lot of things happen asynchronously.

My thinking is that the mute controls should work as soon as an audio elementary stream created event is received.

With LibVLC 4.0.0 and vlcj 5.0.0 (both still in development) I am pretty sure it will be possible to set audio controls before playing any media.

caprica commented 3 years ago

If there's nothing to more to add, I will close this soon.

courteous commented 3 years ago

damn i was too late , i added a new comment trough a ticket #1082

caprica commented 3 years ago

You're not too late, I would have just reopened the ticket.