Last active
October 10, 2021 08:19
-
-
Save jayfella/8a0dc65354b358c9e5f632a047d0686b to your computer and use it in GitHub Desktop.
Playing videos in jMonkeyEngine using VLC4J4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// compile group: 'uk.co.caprica', name: 'vlcj', version: '4.1.0' | |
package com.jayfella.test; | |
import com.jme3.app.SimpleApplication; | |
import com.jme3.material.Material; | |
import com.jme3.material.Materials; | |
import com.jme3.material.RenderState; | |
import com.jme3.math.FastMath; | |
import com.jme3.scene.Geometry; | |
import com.jme3.scene.shape.Quad; | |
import com.jme3.system.AppSettings; | |
import com.jme3.texture.Image; | |
import com.jme3.texture.Texture2D; | |
import com.jme3.util.BufferUtils; | |
import uk.co.caprica.vlcj.factory.MediaPlayerFactory; | |
import uk.co.caprica.vlcj.player.base.MediaPlayer; | |
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer; | |
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormat; | |
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormatCallback; | |
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.RenderCallbackAdapter; | |
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.format.RV32BufferFormat; | |
import java.nio.ByteBuffer; | |
public class TestVlcPlayer4 extends SimpleApplication { | |
public static void main(String... args) { | |
TestVlcPlayer4 testVlcPlayer4 = new TestVlcPlayer4(); | |
AppSettings appSettings = new AppSettings(true); | |
appSettings.setResolution(1280, 720); | |
//appSettings.setFrameRate(120); | |
appSettings.setTitle("Test :: VLC4J"); | |
appSettings.setUseJoysticks(true); | |
testVlcPlayer4.setSettings(appSettings); | |
testVlcPlayer4.setShowSettings(false); | |
testVlcPlayer4.setPauseOnLostFocus(false); | |
testVlcPlayer4.start(); | |
} | |
// private final BufferedImage image; | |
private MediaPlayerFactory factory; | |
private EmbeddedMediaPlayer mediaPlayer; | |
private String media = "M:\\Antz (1998).mkv"; | |
private int width = 720; | |
private int height = 400; | |
@Override | |
public void simpleInitApp() { | |
flyCam.setMoveSpeed(100); | |
Image image = new Image(); | |
image.setWidth(width); | |
image.setHeight(height); | |
image.setFormat(Image.Format.BGRA8); | |
image.setData(BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4)); | |
Texture2D jmeTexture = new Texture2D(image); | |
factory = new MediaPlayerFactory(); | |
mediaPlayer = factory.mediaPlayers().newEmbeddedMediaPlayer(); | |
mediaPlayer.videoSurface().set(factory.videoSurfaces().newVideoSurface( | |
new TestBufferFormatCallback(), | |
new JmeRenderCallbackAdapter(jmeTexture), | |
false)); | |
mediaPlayer.media().play(media); | |
Geometry screenGeom = new Geometry("Video Screen", new Quad(width, height)); | |
screenGeom.setMaterial(new Material(assetManager, Materials.UNSHADED)); | |
screenGeom.getMaterial().setTexture("ColorMap", jmeTexture); | |
rootNode.attachChild(screenGeom); | |
// a little hack to prevent flipping Y. | |
screenGeom.rotate(0, FastMath.PI, FastMath.PI); | |
screenGeom.getMaterial().getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Front); | |
screenGeom.move(-image.getWidth() * 0.5f, image.getHeight() * 0.5f, 0); | |
} | |
private final class TestBufferFormatCallback implements BufferFormatCallback { | |
@Override | |
public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) { | |
return new RV32BufferFormat(width, height); | |
} | |
} | |
public class JmeRenderCallbackAdapter extends RenderCallbackAdapter { | |
private ByteBuffer imageBuffer; | |
private Texture2D texture; | |
int width; | |
int height; | |
public JmeRenderCallbackAdapter(Texture2D texture) { | |
super(new int[texture.getImage().getWidth() * texture.getImage().getHeight()]); | |
width = texture.getImage().getWidth(); | |
height = texture.getImage().getHeight(); | |
imageBuffer = BufferUtils.clone(texture.getImage().getData(0)); | |
this.texture = texture; | |
} | |
@Override | |
protected void onDisplay(MediaPlayer mediaPlayer, int[] rgbBuffer) { | |
// Simply copy buffer to the image and repaint | |
if(imageBuffer != null){ | |
imageBuffer.rewind(); | |
imageBuffer.clear(); | |
for(int i : rgbBuffer){ | |
imageBuffer.putInt(i); | |
} | |
texture.getImage().setData(BufferUtils.clone(imageBuffer)); | |
texture.getImage().setUpdateNeeded(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment