setMediaTime not setting specified time on realized player - java

I've a situation where I'm creating an instance of javax.Media.player (to play audio in wav foramt) using javax.Media.Manager and I've code which looks like:-
Player player = null;
MediaLocator locator = new MediaLocator("file path to wav file");
Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, new Boolean(true));
try {
player = Manager.createRealizedPlayer(locator);
}
catch (CannotRealizeException e) {
e.printStackTrace();
}
player.addControllerListener(this);
player.start();
player.setMediaTime();
And after having an instance of player I'm invoking setMediaTime on it, the problem is that sometimes the player is updated with the time provided and sometime not.
Can anyone please suggest me that what mistake I'm making.

Finally, I got this working by tweaking my code, I obtained the player instance by
Manager.createPlayer(localtor)
and got my player realized by using busy waiting method, as soon as the player gets realized I invoke the setMediaTime method to set the audio start off set.
The reason why I was facing this problem was that, BasicPlayer from JMF API spwan a new thread if the fresh player instance is created and once the player is started and realized calling setMediaTime won't have any effect on that, basically this was more a threading issue which I overlooked.

Related

Java, Javafx MediaPlayer, doesn't seem to release mp3 file, even when using .dispose() method

So, I've searched around quite a bit, and haven't found anything that resolves this. (found someone asking in 2016, with no answers and did it somewhat differently, also I've found some that didn't care if the file was deleted on exit, or on next start up, which I do)
I have an application where I have one button for letting a user pick an mp3 file on the computer, and one button that let's the user play that sound back, when the user is done, he/she can click a save button that is supposed to delete the mp3 file that is stored in the user's folder, and then replace it with the new one the user picked, they are supposed to do this continuously, so deleting the previous file on exit isn't very good, as it could lead to a big heap of temp files that needs to be deleted on exit, and checked for on launch.
so, from what I can gather it seems to be a Windows-centric problem where a file opened in mediaplayer isn't released properly(or something like that, was a bit hard to follow..), so I was wondering if there is a way to force the MediaPlayer object to release the Media object/file, or maybe a way to find out and have a listener for when the dispose() method is done doing it's thing, so that I can delete the file while the java program continues to run afterwards?
here is a code snippet to illustrate the problem.
import javafx.application.Application;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main extends Application {
public static void main(String[] args){launch(args);}
#Override
public void start(Stage primaryStage) throws Exception {
Path path = Paths.get("some/file/path.mp3"); //making a path for the Media object and for deleting later
Media media = new Media(path.toUri().toString()); //Making a Media object for the Mediaplayer
MediaPlayer mediaPlayer = new MediaPlayer(media); //Making a MediaPlayer
mediaPlayer.play(); //playing just to make sure it has been used
mediaPlayer.stop(); //stopping the player
mediaPlayer.dispose(); //disposing of the MediaPlayer
//checking to see that the MediaPlayer has been disposed of at least
try {
if (mediaPlayer.getStatus().equals(MediaPlayer.Status.DISPOSED)) {
Files.delete(path); //trying to delete, and subsequently crashing..
}
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0); //terminating program
}
}
edit(added the exception thrown(replacing my actual path with the dummy one)):
java.nio.file.FileSystemException: some/file/path.mp3: The process cannot access the file because it is being used by another process.
my current thought on a solution is to have a file where I mark files for deletion when the program starts next, and keeping track of what files should be copied over to the user folder then.
or maybe even not actually saving the files in the users folder, and rather keeping a reference to the users files in a text file or something or other, while I just have a general "sounds folder" that I can get things from..
or something like that, but I thought I'd at least ask you people if you had any ideas on how to solve it as I initially wanted to do it.
Really sorry if this should end up as a duplicate, I haven't really found any answers that have helped when searching for this, but if you do, then please send me on my way over to wherever that is :)
Thank you for any Ideas you might have, and hope the English is understandable, also, if you want any more info or anything, please let me know :)
Edit 2:
So, I've found a "bad" workaround, where I use the AudioInputStream to play a sound with a Clip, as here I can control the stream, and close it before deleting the file, this seems to work quite well, only problem with this is that I am now limited to wav files(afaik), but I can work with that for now at least, but not leaving it as an answer, as a MediaPlayer solution would be far better imo.
Edit 3(forgot to add the code)(got the audio part from here: https://stackoverflow.com/a/11025384/10044355):
Path path = Paths.get("some/file/path.wav");
File yourFile = new File(path.toString());
AudioInputStream stream = null;
AudioFormat format;
DataLine.Info info;
Clip clip;
try {
stream = AudioSystem.getAudioInputStream(yourFile);
}catch (Exception e){
e.printStackTrace();
}
format = stream.getFormat();
info = new DataLine.Info(Clip.class, format);
clip = (Clip) AudioSystem.getLine(info);
clip.open(stream);
clip.start();
clip.stop();
stream.close();
Files.delete(path);

libGDX - If I play a Sound, my Android-Phone stutters/have a micro lag

I'm new in libGDX and if I play a Sound, I have a micro stutter/lag.
My File has the ".wav" extension. - I already tried:
change the file-extensions
make the file-duration longer
I appreciate your help! :))
have a nice day
Recommend setting up an asset manager that loads the sound once before it is needed. This will allow for reuse and encapsulating the process of loading assets for all or parts of an application. Recommend strongly against recreating (reloading) the sound each time. Wave or ogg both work well. Some articles / posts recommend changing the size.
Create object or decode Sound file at once inside create() or in show() method and play that sound whenever you required.
private Sound hit;
#Override
public void create() {
hit = Gdx.audio.newSound(Gdx.files.internal("sfx_hit.wav"));
}
public void playSound(){
hit.play(0.5f);
}
#Override
public void dispose() {
hit.dispose(); // <- only dispose when you're no using further
}
Possible reason : Decoding a compressed file takes times so avoid to decode file each time when you want to play sound and Sample rate of your clip should be lower for fast processing.

How can I play Video Files using VLCJ and JavaFX?

I'm aware that JavaFX has it's own media player, but I do not know if it can play MP4 files.
Even if it could, I would still prefer to use VLCJ as VLC supports more formats and varieties than I can count in my near-catatonic state.
I've followed the example posted by Caprical in his VLCJ-JavaFX GitHub but it does, well, nothing.
It doesn't error, but it does nothing.
Looking into the code, it seems the issue is in the Timeline event handler:
private final EventHandler<ActionEvent> nextFrame = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
Memory[] nativeBuffers = mediaPlayerComponent.getMediaPlayer().lock();
if (nativeBuffers != null) { //<-----This is always NULL so everything in the block is skipped . . .
// FIXME there may be more efficient ways to do this...
// Since this is now being called by a specific rendering time, independent of the native video callbacks being
// invoked, some more defensive conditional checks are needed
Memory nativeBuffer = nativeBuffers[0];
if (nativeBuffer != null) {
ByteBuffer byteBuffer = nativeBuffer.getByteBuffer(0, nativeBuffer.size());
BufferFormat bufferFormat = ((DefaultDirectMediaPlayer) mediaPlayerComponent.getMediaPlayer()).getBufferFormat();
if (bufferFormat.getWidth() > 0 && bufferFormat.getHeight() > 0) {
pixelWriter.setPixels(0, 0, bufferFormat.getWidth(), bufferFormat.getHeight(), pixelFormat, byteBuffer, bufferFormat.getPitches()[0]);
}
}
}
mediaPlayerComponent.getMediaPlayer().unlock();
};
};
It's been suggested I get the logs but that will have to wait as I'm slipping into unconsciousness as I make this post (when I return to the land of the living, I will see about what I can do to post some). If there is a better way to make this happen, I'm all for it if someone can direct me there. Thanks...
The vlcj-javafx sample on the Github project works just fine.
You say in your question that vlcj "doesn't error, but it does nothing".
Well, there are two ways to check for errors which you don't show in the code you posted in your question.
The mediaPlayer.playMedia() method returns a boolean to say whether VLC accepted your MRL or not - did you check the return value? Note that even if this method returns true, it does not categorically mean VLC could play your media, but if it returns false it categorically means it could not be played.
You should add a MediaPlayerEventLister to your media player and provide implementations for "playing()" and "error()". These callbacks will be triggered asynchronously - because that's how LibVLC works - only then can you conclude whether vlcj "doesn't error", or "does nothing".
I suspect your media failed to start, probably because of a wrong filename.

How do I get a VLC Media Player in Java without a Displayable Component?

I'm working with the VLCJ Bindings and have finally been able to get several roadblocks. Now I am here.
I have no need (at this time), nor desire for, a visible Media Player component (the EmbeddedMediaPlayerComponent). All I need (for now) is to play Audio Files.
I have the following method in place to handle that for me:
public static void Play(File AudioFile){
if (!LibVLCLoader.Loaded) LibVLCLoader.loadLibVLC();
EmbeddedMediaPlayerComponent EMPC = new EmbeddedMediaPlayerComponent();
if (EMPC.getMediaPlayer().prepareMedia(AudioFile.getAbsolutePath())){
EMPC.getMediaPlayer().addMediaPlayerEventListener(new MediaPlayerEventAdapter(){
#Override public void subItemFinished(MediaPlayer p, int i){
EMPC.release(true);
}
});
Platform.runLater(() -> EMPC.getMediaPlayer().play());
}
}
But I keep getting this exception:
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: The video surface component must be displayable
Which I understand. It makes sense. But I don't NEED it visible. I just need the sound. How can I make that happen?
EmbeddedMediaPlayer is only for the case where you want to literally embed a video surface inside your application.
If you just need audio, there's an AudioMediaPlayerComponent for expressly this purpose.
To create such a component, simply:
AudioMediaPlayerComponent audioMediaPlayerComponent =
new AudioMediaPlayerComponent();
You can subclass it, for example to customise behaviour and easily implement event handlers.
Using the so-called "component" media players gives you a slightly nicer/easier API than using the non-"component" media players that are created via the MediaPlayerFactory.
This works just fine if your media is an audio file.
If your media is actually video, but you only want to play the audio track, then even if you use the AudioMediaPlayerComponent by default VLC will open a video window. In this case you still need to actually disable the video output - the simplest way to do this is to tell VLC to use vcodec=dummy.
I really don't agree with tricks like creating a window and moving it off-screen, or sizing it down to 1x1, it's just not necessary.
In the code posted in the original question there is an unrelated problem. The EMPC and EMP variable will go out-of-scope when the Play() method terminates, making the media player eligible for garbage collection. What will happen is that some random time later your application will likely crash because the native hooks that vlcj uses will call back into a Java object that no longer exists. You need to keep your media player references alive via hard references.
Okay so it turns out you can create your own MediaPlayer object outside of the EmbeddedMediaPlayerComponent like so:
public static void Play(File AudioFile){
if (!LibVLCLoader.Loaded) LibVLCLoader.loadLibVLC();
MediaPlayerFactory MPF = new MediaPlayerFactory(
"--video-title=vlcj video output",
"--no-snapshot-preview",
"--quiet",
"--quiet-synchro",
"--sub-filter=logo:marq",
"--intf=dummy"
);
EmbeddedMediaPlayer EMP = MPF.newEmbeddedMediaPlayer();
if (EMP.prepareMedia(AudioFile.getAbsolutePath())){
EMP.addMediaPlayerEventListener(new MediaPlayerEventAdapter(){
#Override public void subItemFinished(MediaPlayer p, int i){
EMP.release();
MPF.release();
}
});
Platform.runLater(() -> EMP.play());
} else{
EMP.release();
MPF.release();
}
}

Java applet sound issues, sound continues on close, and I can't sign the sound files

So I was working on a mini game, and for the first time I added sound to my game, but I ran into two issues, the first is that when I load the applet up in my browser, and I close the tab when I'm done, the background music continues to play for a bit. I'm using this to play the background:
AudioClip audioClip = getAudioClip(getCodeBase(), "bg.wav");
audioClip.loop();
And that's inside the init()
My second problem is that whenever I start the applet, it brings up that warning saying there is a mixture of signed and unsigned code, and that it could be unsafe. I've never gotten that before, so I assume it's the sound files, what can I do about that?
http://www.FreeMinecraftHost.com/ParticleDefender is where the applet is hosted if you would like to see the message it brings up.
The warning I got did not say anything about 'mixing signed & unsigned code', but I refused the 'allow trusted code' dialog to check that the applet will work in a sand-box. It seems to work just fine, I could move left & right, shoot, destroy enemies, be destroyed by them, hear the (v. loud) music track, and restart the game.
Since the applet element indicates only a single Jar, and the main class is in that Jar, I cannot understand how you could get a message like you saw. Nevertheless, the solution to not get any prompts seems obvious.
Don't sign the Jar!
That guy was a jerk messed up my answer (like I said it's been years)
Anyways, Here is my audio handler, on closer inspection I relized that in my program I was looping the background music, about a 1 min audio file. The audio clip would be interuped on a win/loose/or exit by a seperate very short clip and the audio would self terminate. You could kill your music this way just by playing a short clip of nothing or some exit sound.
By the way what I said in my first answer was not a guess we really did have to do that back then.
private void musicHandler(int musicFunction)
{
for( int counter =0; counter < 3; counter++)
audioClip[counter].stop();
if(musicFunction == 0)
audioClip[musicFunction].loop();
else
audioClip[musicFunction].play();
}
AudioClip audioClip[] = new AudioClip[10];
private void musicLoader()
{
try
{
URL baseURL = new URL("file:" + System.getProperty("user.dir") + "/");
URL completeURL = new URL(baseURL, "game.wav");
audioClip[0] = Applet.newAudioClip(completeURL);
completeURL = new URL(baseURL, "TAPS.WAV");
audioClip[1] = Applet.newAudioClip(completeURL);
completeURL = new URL(baseURL, "YEAH.WAV");
audioClip[2] = Applet.newAudioClip(completeURL);
audioClip[0].loop();
}
catch (MalformedURLException exception) {}
}

Categories

Resources