Locked History Actions

vlcj/JavaFx1

JavaFxからの利用

JavaFxにおける利用サンプルは

にあるのだが、わかりづらいので、簡単化してみた。この例ではAnimationTimerを使用している。

import java.nio.*;

import com.sun.jna.*;

import javafx.animation.*;
import javafx.application.*;
import javafx.application.Platform;
import javafx.scene.*;
import javafx.scene.canvas.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.*;
import uk.co.caprica.vlcj.component.*;
import uk.co.caprica.vlcj.discovery.*;
import uk.co.caprica.vlcj.player.direct.*;
import uk.co.caprica.vlcj.player.direct.format.*;

public class Simple extends Application {

  static final String VIDEO_FILE = "c:\\users\\admin\\desktop\\video.mp4";
  
  AnimationTimer timer;
  DefaultDirectMediaPlayer mediaPlayer;
  MyMediaPlayerComponent mediaPlayerComponent;
  
  @Override
  public final void start(final Stage stage) throws Exception {

    final Canvas canvas = new Canvas();
    BorderPane borderPane = new BorderPane();
    borderPane.setCenter(canvas);

    mediaPlayerComponent = new MyMediaPlayerComponent(canvas.getGraphicsContext2D().getPixelWriter(), new Callback() {
      public void setSize(int width, int height) {
        canvas.setWidth(width);
        canvas.setHeight(height);
        stage.setWidth(width);
        stage.setHeight(height);
      }
    });
    mediaPlayer = (DefaultDirectMediaPlayer)mediaPlayerComponent.getMediaPlayer();

    timer = new AnimationTimer() {
      @Override
      public void handle(long now) {
        mediaPlayerComponent.renderFrame();
      }
    };
    

    stage.setTitle("vlcj JavaFX Direct Rendering Test");
    Scene scene = new Scene(borderPane);
    stage.setScene(scene);
    stage.show();
    mediaPlayer.playMedia(VIDEO_FILE);
    timer.start();
  }

  @Override
  public final void stop() throws Exception {
    timer.stop();
    mediaPlayer.stop();
    mediaPlayer.release();
  }

  static class MyMediaPlayerComponent extends DirectMediaPlayerComponent {

    private final PixelWriter pixelWriter;
    private final WritablePixelFormat<ByteBuffer> pixelFormat;
    private final DefaultDirectMediaPlayer mediaPlayer;
    
    public MyMediaPlayerComponent(PixelWriter pixelWriter, final Callback widthHeight) {
      super(new BufferFormatCallback() {
        @Override
        public BufferFormat getBufferFormat(final int width, final int height) {
          Platform.runLater(new Runnable() {
            @Override
            public void run() {
              widthHeight.setSize(width,  height);
            }});
          return new RV32BufferFormat(width, height);
        }
      });
      this.pixelWriter = pixelWriter;
      pixelFormat = PixelFormat.getByteBgraInstance();
      mediaPlayer = (DefaultDirectMediaPlayer)getMediaPlayer();
    }
    
    public void renderFrame() {
      Memory[]nativeBuffers = mediaPlayer.lock();
      try {
        if (nativeBuffers == null) return;
        Memory nativeBuffer = nativeBuffers[0];
        if (nativeBuffer == null) return;
        ByteBuffer byteBuffer = nativeBuffer.getByteBuffer(0, nativeBuffer.size());
        BufferFormat bufferFormat = mediaPlayer.getBufferFormat();
        if (bufferFormat == null) return;
        int width = bufferFormat.getWidth();
        int height = bufferFormat.getHeight();
        if (width <= 0 || height <= 0) return;
        pixelWriter.setPixels(0, 0, width, height, pixelFormat, byteBuffer, bufferFormat.getPitches()[0]);        
      } finally {
        mediaPlayer.unlock();
      }
    }
  }

  public interface Callback {
    public void setSize(int width, int height);
  }
  
  public static void main(final String[] args) {
    new NativeDiscovery().discover();
    Application.launch(args);
  }
}