@Empire_Phoenix and @abies made an excellent job at making a powerful solution for putting movies on Texture.
I’ve made an AppState for the simplest use case: showing a movie full screen.
You attach the appstate and the movie plays, and detaches itself when finished.
Usage:
stateManager.attach(new MovieAppState("Movies/powered-by-jme3.mp4"));
Requires this lib:
Also requires Java8 (Java7 users was recently forced to upgrade to Java8 anyway). This also means that this solution doesn’t work on Android (but I believe that you can use an Activity to do the same thing).
The JME3-JFX uses internal oracle classes that may break even between minor revision. You need to bundle a JVM with your application.
Also requires the appropriate codec to be installed. More info here: http://www.oracle.com/technetwork/java/javafx/downloads/supportedconfigurations-1506746.html
Requires your application to extend SimpleApplication, and put this code, or else!
@Override
public void simpleInitApp() {
PlatformImpl.startup(new Runnable() {
@Override public void run() {
}
});
@Override
public void destroy() {
super.destroy();
PlatformImpl.exit();
}
The code assumes that the movie is in 16/9 aspect ratio. If the user is running on 4/3 then black bands are showed (the result isn’t perfect, but still better that full stretch).
If running crazy aspect ratio you get even less optimal results
Do I forget something? Ah yes, the MovieAppState!
import com.jme3.app.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.media.Media;
import javafx.scene.media.MediaException;
import javafx.scene.media.MediaPlayer;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3x.jfx.media.TextureMovie;
import com.jme3x.jfx.media.TextureMovie.LetterboxMode;
import com.simsilica.lemur.event.BaseAppState;
import org.lwjgl.opengl.Display;
/**
*
*/
public class MovieAppState extends BaseAppState {
private TextureMovie textureMovie;
private MediaPlayer mp;
Geometry screen1;
String movie;
public MovieAppState(String movie) {
this.movie = movie;
}
@Override
protected void initialize(Application app) {
Media media = new Media(Thread.currentThread().getContextClassLoader().getResource(movie).toString());
media.errorProperty().addListener(new ChangeListener<MediaException>() {
@Override
public void changed(final ObservableValue<? extends MediaException> observable, final MediaException oldValue, final MediaException newValue) {
newValue.printStackTrace();
}
});
this.mp = new MediaPlayer(media);
this.mp.setOnEndOfMedia(new Runnable() {
public void run() {
stopping = true;
}
});
this.mp.play();
boolean squareScreen = ((0f + Display.getWidth()) / Display.getHeight()) < 1.6f;
this.textureMovie = new TextureMovie(app, this.mp, squareScreen ? LetterboxMode.VALID_LETTERBOX : LetterboxMode.VALID_SQUARE);
this.textureMovie.setLetterboxColor(ColorRGBA.Black);
screen1 = new Geometry("Screen1", new Quad(Display.getWidth(), Display.getHeight()));
final Material s1mat = new Material(app.getAssetManager(), "com/jme3x/jfx/media/MovieShader.j3md");
s1mat.setTexture("ColorMap", this.textureMovie.getTexture());
s1mat.setInt("SwizzleMode", textureMovie.useShaderSwizzle());
screen1.setMaterial(s1mat);
((SimpleApplication) app).getGuiNode().attachChild(screen1);
}
boolean stopping = false;
@Override
public void update(float tpf) {
if (stopping) {
((SimpleApplication) getApplication()).getGuiNode().detachChild(screen1);
cleanup();
setEnabled(false);
}
}
@Override
protected void cleanup(Application app) {
this.mp.stop();
}
@Override
protected void enable() {
}
@Override
protected void disable() {
stopping = true;
}
}