JMFSnapper — 封裝 JMF 影片載入、播放、擷取幀。JMFMovieScreen (extends Shape3D) — 管理四邊形幾何體與紋理貼圖。TimeBehavior (extends Behavior) — 定時器,每 40ms 呼叫 nextFrame() 更新畫面 (25fps)。JMFMovieScreen 與 TimeBehavior 皆為場景圖節點,掛載至 BranchGroup。JMFSnapper 非場景圖一部分,由 View 呼叫。
ImageComponent2D ic = new ImageComponent2D(
ImageComponent2D.FORMAT_RGB, SIZE, SIZE, true, true); // by-reference, Y-up
Windows + OpenGL 下:BufferedImage.TYPE_3BYTE_BGR 對應 FORMAT_RGB,避免資料拷貝。Y-up 意味著紋理 (0,0) 在左上角。四邊形頂點對應調整:
(0,0)→左上(p3), (1,0)→右上(p2), (1,1)→右下(p1), (0,1)→左下(p0)
// JMFSnapper 關鍵邏輯
Processor processor = Manager.createProcessor(mediaLocator);
processor.realize(); processor.prefetch(); processor.start();
DataSource source = processor.getDataOutput();
FrameGrabbingControl fgc = (FrameGrabbingControl)
source.getControl("javax.media.control.FrameGrabbingControl");
Buffer buffer = fgc.grabFrame();
BufferToImage bti = new BufferToImage((VideoFormat) buffer.getFormat());
Image awtImage = bti.createImage(buffer); // 轉為 AWT Image
// 進一步轉為 BufferedImage 供 ImageComponent2D 使用
FrameGrabbingControl 實作不穩定,部分編碼器不支援擷取幀。// WrapMovie3D 中建立動畫畫面
private void addMovieScreen(String filename) {
ms = new JMFMovieScreen(new Point3f(1.5f, 0, -1), 2.0f, filename);
sceneBG.addChild(ms);
timer = new TimeBehavior(40, ms); // 40ms 間隔
timer.setSchedulingBounds(bounds);
sceneBG.addChild(timer);
}