どうも、hide92795です
ゲームエンジンの作成にあたり、結構悩んでいたのが動画再生についてです。
Javaで動画再生といえばJMFを使用したものが有名ですが、プラットホームごとのインストーラーがあったり、プラットホームに依存しないバージョンだと対応フォーマットが皆無に等しかったりといろいろと難点があったのです。
さらにLWJGLではSwing上にて動作自体はできるものの、JMF用のPanelに切り替えた時にどんな問題が発生するかわからないなど結構なリスクがありました。
そこでグーグル先生で色々調べていたところ、
http://www.java-gaming.org/index.php?topic=24846.30
↑のサイトを見つけました。この中の画像が貼り付けられている投稿に書かれているURL
http://www.java-gaming.org/?action=pastebin&id=23
こちらにはソースコードが書かれています。
投稿があったスレッド名は「VLCJ in OpenGL / LWJGL」です。
このVLCJというのはVLCPlayerの機能をJavaで使えるようにしているライブラリです。
VLCJ – http://www.capricasoftware.co.uk/vlcj/
ではまず下準備から
今回はWindows&Eclipse使用を前提としています。
1.必要なライブラリ等
・LWJGL
・VLCJ(↑のURLからDL出来ます)
・JNA(jna.jar, platform.jar)(VLCJのダウンロードページにリンクがあります。)
・libvlc.dll&libvlccore.dll(VLCのインストールディレクトリにあります)
2.ソースコード
基本的には先程のURLのソースですが、一部修正をしてあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
import java.nio.ByteBuffer; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE; import uk.co.caprica.vlcj.player.MediaPlayerFactory; import uk.co.caprica.vlcj.player.direct.DirectMediaPlayer; import uk.co.caprica.vlcj.player.direct.RenderCallback; import uk.co.caprica.vlcj.runtime.RuntimeUtil; import com.sun.jna.Memory; import com.sun.jna.NativeLibrary; public class VLCJinLWJGL implements RenderCallback { private static final int WIDTH = 1280, HEIGHT = 720; private MediaPlayerFactory mediaPlayerFactory; private DirectMediaPlayer mediaPlayer; private int texture; private ByteBuffer buffer = null; public static void main(String[] argv) { NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:\\Program Files\\VideoLAN\\VLC"); new VLCJinLWJGL().updateLoop(); } public VLCJinLWJGL() { System.setProperty("jna.library.path", "vlib"); initGL(); if (isMac()) mediaPlayerFactory = new MediaPlayerFactory(new String[] { "--no-video-title-show", "--vout=macosx" }); else mediaPlayerFactory = new MediaPlayerFactory(new String[] { "--no-video-title-show" }); mediaPlayer = mediaPlayerFactory.newDirectMediaPlayer("RGBA", WIDTH, HEIGHT, WIDTH * 4, this); mediaPlayer.playMedia("op00.mpg"); Display.setTitle("VLCJ - LWJGL - " + mediaPlayer.getMediaMeta().getTitle()); } private void initGL() { try { Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); Display.create(); //Display.setVSyncEnabled(true); } catch (LWJGLException e) { e.printStackTrace(); System.exit(0); } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, WIDTH, HEIGHT, 0, 1, -1); glMatrixMode(GL_MODELVIEW); glEnable(GL_TEXTURE_2D); texture = glGenTextures(); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, (ByteBuffer) null); } public static boolean isMac() { return (System.getProperty("os.name").toLowerCase().indexOf("mac") >= 0); } public void updateLoop() { while (!Display.isCloseRequested()) { glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, texture); if (buffer != null) { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer); } glBegin(GL_QUADS); { glTexCoord2f(0, 0); glVertex2f(0, 0); glTexCoord2f(1, 0); glVertex2f(WIDTH, 0); glTexCoord2f(1, 1); glVertex2f(WIDTH, HEIGHT); glTexCoord2f(0, 1); glVertex2f(0, HEIGHT); } glEnd(); Display.update(); } mediaPlayer.stop(); mediaPlayer.release(); mediaPlayerFactory.release(); mediaPlayerFactory = null; mediaPlayer = null; Display.destroy(); } @Override public void display(Memory memory) { buffer = memory.getByteBuffer(0, WIDTH * HEIGHT * 4); } |
修正箇所はmainのはじめに書かれている行です。
jarに対してネイティブライブラリの登録をしたのですが、何故かダメだったので直接ソースコードに。
あとは、再生したい動画ファイルをクラスパス直下において、
1 |
mediaPlayer.playMedia("op00.mpg"); |
のop00.mpgの名前を変え、フィールドの一番上にあるWIDTHとHEIGHTの値を変えるだけです。
↑RewriteのOPを拝借して再生してみましたが、問題ありませんでした。
基本的にVLCで再生出来るものなら問題ないと見て大丈夫でしょう。
ではノシ