我需要获取图像作为用户加载的视频的预览,它不需要是一个很好的缩略图,因为它只是用于聊天应用程序,所以我想到当用户发送包含mp4 我处理它并保存随机帧。
我用谷歌搜索了一下,每个人都在使用 ffmpeg,但这是一个外部软件,你只能用 java 与它交互,我的项目需要独立,我不希望它依赖于服务器安装了 ffmpeg 的事实,所以我回到过去并找到了JavaFX,但是网上的所有代码片段都没有指定他们正在使用的版本,而且chatGPT一如既往地没用,你们能告诉我如何做到这一点,或者至少向我解释一下它是如何工作的这样我就可以自己编码了?我正在使用这个依赖项
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version> <!-- the version chatGPT wrote but you can change that -->
</dependency>
如果您有完全不同的解决方案,那也很棒,我只关心在指定路径上使用指定名称保存视频中的随机帧,提前感谢
我尝试了这种方法,但它给出了很多错误,可能是因为版本不匹配
private byte[] getFrameFromVideo(String videoFilePath, int targetTimeSeconds) throws IOException {
try {
Media media = new Media(new File(videoFilePath).toURI().toString());
MediaPlayer mediaPlayer = new MediaPlayer(media);
CountDownLatch latch = new CountDownLatch(1);
mediaPlayer.setOnReady(() -> {
mediaPlayer.pause();
mediaPlayer.setStartTime(mediaPlayer.getTotalDuration().multiply(targetTimeSeconds * 1.0 / media.getDuration().toSeconds()));
mediaPlayer.setStopTime(mediaPlayer.getStartTime().add(mediaPlayer.getTotalDuration().multiply(1.0 / media.getDuration().toSeconds())));
latch.countDown();
});
mediaPlayer.setOnEndOfMedia(() -> {
BufferedImage bufferedImage = new BufferedImage(mediaPlayer.getMedia().getWidth(), mediaPlayer.getMedia().getHeight(), BufferedImage.TYPE_3BYTE_BGR);
FXImage fxImage = mediaPlayer.snapshot(null);
fxImage.pixelReaderProperty().get().getPixels(0, 0, (int) fxImage.getWidth(), (int) fxImage.getHeight(), javafx.scene.image.PixelFormat.getByteRgbInstance(), bufferedImage.getRaster().getDataBuffer());
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
mediaPlayer.dispose();
latch.countDown();
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
});
mediaPlayer.play();
latch.await();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
您需要 JavaFX 媒体才能使用 JavaFX Media。
您需要启动JavaFX运行时才能正确使用媒体系统。
对媒体的 JavaFX API 调用应在 JavaFX 应用程序线程上进行。 JavaFX 应用程序线程永远不应该休眠或锁定。
runLater 中的步骤:
如果您的应用程序是模块化的,则在您的模块信息中包含使其工作所需的所有模块依赖项:
参考文献
替代品