This is a sidekick project of mine.
This is based on JME-JFX libs.
It took me a bit to set the equipment complete, so here is what i had to do, to get the original sample work:
It is using JavaFX, so you have to setup your JDK Platform to 1.8
Additionally you need
JME-JFX
Furthermore you need the MovieShader. I also added 2 small testmovies to test my code
This was nice. I could play a video in the background of my gui and it looked very nice.
I just installed me a dropbox seconds before to support this thread with what’s needed to start, so if the link doesn’t work, there maybe something wrong with my dropbox settings. Ashes on my head, we’ll get it, if it’s wrong.
MyDropBox
Back to the code. I wanted it to play several video files, so i had to do two things. First is to make the MediaPlayer capable to change a MediaSource, which is done by the MediaView and secondly i needed to refresh the TextureMovie somehow, so i made it a Node, which i just reinstantiate, if MediaPlayer does so.
Least was the currently solved problem on what to do, when the Runnable of MediaPlayer wants to do some useful things, since the video file finished.
Lately i added the housework to a Callback into the applications enqueue.
To show my work i have broken down my Class into its vital functionality. In this example i changed the List, which is used to play to a simple ArrayList, so in my final approach a small thing differs, but i will tell about that at the end of this article.
So - enough talked - here is the code:
/*
* Copyright (c) 2015 Yves Tanas
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package mygame.mediaManager;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad;
import com.jme3x.jfx.media.TextureMovie;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.Callable;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.media.Media;
/** A simple media manager to play a list of videos
* @author Yves Tanas
*/
public class SimpleMediaManager extends Node{
SimpleApplication app;
MediaPlayer mp;
ArrayList<String> aryLst;
public void init(SimpleApplication app){
this.app = app;
aryLst = new ArrayList<String>();
aryLst.add("assets/Interface/vids/test2.mp4");
aryLst.add("assets/Interface/vids/test1.mp4");
MediaView mediaView = new MediaView();
MediaPlayer mp = initMediaPlayer(mediaView, aryLst.iterator());
TextureNode node = new TextureNode("mediaManagerTextureNode");
node.init(app, mp);
attachChild(node);
}
private MediaPlayer initMediaPlayer(final MediaView mediaView, final Iterator<String> urls){
if (urls.hasNext()){
mp = new MediaPlayer(new Media(new File(urls.next()).toURI().toASCIIString()));
mp.setAutoPlay(true);
mp.setOnEndOfMedia(new Runnable() {
@Override public void run() {
app.enqueue(
new Callable<Boolean>() {
public Boolean call() throws Exception {
mp.stop();
initMediaPlayer(mediaView, urls);
detachChildNamed("mediaManagerTextureNode");
TextureNode node = new TextureNode("mediaManagerTextureNode");
node.init(app, mp);
attachChild(node);
return true;
}
});
}
});
mediaView.setMediaPlayer(mp);
return mp;
} else return initMediaPlayer(mediaView, aryLst.iterator());
}
class TextureNode extends Node{
private TextureMovie tex;
public void init(SimpleApplication app,MediaPlayer mp){
this.tex = new TextureMovie(app, mp, TextureMovie.LetterboxMode.VALID_LETTERBOX);
this.tex.setLetterboxColor(ColorRGBA.Black);
final Geometry videoScreen = new Geometry("videoScreen", new Quad(10,10));
videoScreen.setLocalTranslation(-5, -5, 0);
final Material s1mat = new Material(app.getAssetManager(), "Interface/MovieShader.j3md");
s1mat.setTexture("ColorMap", this.tex.getTexture());
s1mat.setInt("SwizzleMode", tex.useShaderSwizzle());
videoScreen.setMaterial(s1mat);
attachChild(videoScreen);
}
public TextureNode(String name){
super(name);
}
}
}
In real scenario i change The iterator to a String value, because i have my own representation of that list, so it then looks like this:
private void initMediaPlayer(final MediaView mediaView, final String url){
mp = new MediaPlayer(new Media(new File(url).toURI().toASCIIString()));
mp.setAutoPlay(true);
mp.setOnEndOfMedia(new Runnable() {
@Override public void run() {
app.enqueue(
new Callable<Boolean>() {
public Boolean call() throws Exception {
mp.stop();
initMediaPlayer(mediaView, actualList.getPath()+actualList.getMediaLocation());
detachChild(node);
node = new TextureNode2("mediaManagerTextureNode");
node.init(app, mp);
attachChild(node);
return true;
}
});
}
});
mediaView.setMediaPlayer(mp);
}
Have a nice sunday !
Ah ! Since i forgot about that. A possibility why video isn’t playing could be, that the video decoding was not fitted to streaming video, so i had to find an decoding setup which is usable.
This is, why i attached those two small testmovies to the vids.rar. They are very small (1MB), very short and ready to use.