Я успешно рендерил видео с помощью EmbeddedMediaPlayer с CallbackVideoSurface с моими собственными BufferFormatCallback и RenderCallback.
Но проблема заключается в методе отображения RenderCallback внутри, он создает много потоков, поэтому он потребляет высокий процессор Я не могу найти, что не так с моим кодом, если кто-то может мне помочь, это было бы здорово.
Вот мой код
VideoPlayerTest. java
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import javax.swing.JFrame;
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
import uk.co.caprica.vlcj.media.MediaRef;
import uk.co.caprica.vlcj.medialist.MediaList;
import uk.co.caprica.vlcj.medialist.MediaListRef;
import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.videosurface.CallbackVideoSurface;
import uk.co.caprica.vlcj.player.embedded.videosurface.VideoSurfaceAdapters;
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.format.RV32BufferFormat;
import uk.co.caprica.vlcj.player.list.MediaListPlayer;
import uk.co.caprica.vlcj.player.list.MediaListPlayerEventAdapter;
import uk.co.caprica.vlcj.player.list.PlaybackMode;
public class VideoPlayerTest {
private static VideoPlayerTest videoPlayerTest;
private final JFrame frame;
private final EmbeddedMediaPlayerComponent mediaPlayerComponent;
private final EmbeddedMediaPlayer embeddedMediaPlayer;
public static void main(String[] args) {
videoPlayerTest = new VideoPlayerTest();
}
public VideoPlayerTest() {
frame = new JFrame("My First Media Player");
frame.setBounds(100, 100, 600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ArrayList<FrameListener> listeners = new ArrayList<FrameListener>();
MyVideoPanel myVideoPanel = new MyVideoPanel();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
listeners.add(myVideoPanel);
super.windowOpened(e);
}
@Override
public void windowClosing(WindowEvent e) {
frame.setVisible(false);
listeners.remove(myVideoPanel);
if(listeners.isEmpty())
{
embeddedMediaPlayer.controls().stop();
embeddedMediaPlayer.release();
}
frame.dispose();
System.exit(0);
}
});
BufferFormatCallback bufferFormatCallback = new BufferFormatCallback() {
@Override
public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) {
return new RV32BufferFormat(1920, 1080);
}
@Override
public void allocatedBuffers(ByteBuffer[] buffers) {
}
};
CallbackVideoSurface callbackVideoSurface = new CallbackVideoSurface(bufferFormatCallback, new MyRenderCallback(listeners, 1920, 1080), false, VideoSurfaceAdapters.getVideoSurfaceAdapter());
mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
MediaPlayerFactory mediaPlayerFactory = mediaPlayerComponent.mediaPlayerFactory();
embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();
embeddedMediaPlayer.audio().setVolume(0);
callbackVideoSurface.attach(embeddedMediaPlayer);
embeddedMediaPlayer.videoSurface().set(callbackVideoSurface);
embeddedMediaPlayer.videoSurface().attachVideoSurface();
MediaListPlayer mediaListPlayer = mediaPlayerFactory.mediaPlayers().newMediaListPlayer();
mediaListPlayer.events().addMediaListPlayerEventListener(new MediaListPlayerEventAdapter() {
@Override
public void nextItem(MediaListPlayer mediaListPlayer, MediaRef item) {
System.out.println("nextItem()");
}
});
mediaListPlayer.mediaPlayer().setMediaPlayer(embeddedMediaPlayer);
MediaList mediaList = mediaPlayerFactory.media().newMediaList();
mediaList.media().add("{Media Path 1}");
mediaList.media().add("{Media Path 2}");
mediaList.media().add("{Media Path 3}");
MediaListRef mediaListRef = mediaList.newMediaListRef();
try {
mediaListPlayer.list().setMediaList(mediaListRef);
}
finally {
mediaListRef.release();
}
mediaListPlayer.controls().setMode(PlaybackMode.LOOP);
mediaListPlayer.controls().play();
frame.setContentPane(myVideoPanel);
frame.setVisible(true);
}
}
MyVideoPanel. java
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class MyVideoPanel extends JPanel implements FrameListener {
private BufferedImage image;
public void newFrameRecieved(BufferedImage image) {
this.image = image;
repaint();
}
@Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
g.dispose();
}
}
FrameListener. java
import java.awt.image.BufferedImage;
@FunctionalInterface
public interface FrameListener
{
public void newFrameRecieved(BufferedImage image);
}
MyRenderCallback. java
Я думаю, проблема в этом классе display method
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.util.List;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormat;
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.RenderCallback;
public class MyRenderCallback implements RenderCallback
{
private List<FrameListener> videoSurfaces;
private int width;
private int height;
private BufferedImage image;
private int[] rgbBuffer;
public MyRenderCallback(List<FrameListener> listeners, int width, int height)
{
this.width = width;
this.height = height;
this.videoSurfaces = listeners;
this.image = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_ARGB);
rgbBuffer = new int[image.getWidth() * image.getHeight()];
}
@Override
public void display(MediaPlayer mediaPlayer, ByteBuffer[] nativeBuffers, BufferFormat bufferFormat) {
synchronized (this.rgbBuffer) {
nativeBuffers[0].asIntBuffer().get(rgbBuffer, 0, bufferFormat.getHeight() * bufferFormat.getWidth());
image.setRGB(0, 0, image.getWidth(), image.getHeight(), rgbBuffer, 0, image.getWidth());
}
for(FrameListener fl: videoSurfaces) {
fl.newFrameRecieved(this.image);
}
}
}