java如何逐帧读取视频?
我想逐帧读取java8-64位格式的Mp4文件,并将每个帧作为jpg写入硬盘。我的第一次尝试是使用JavaFX2.2媒体播放器来播放文件 在视图组件上。我想可能会有一个选项,在每次加载新帧并准备在组件表面上绘制时注册一个观察者以获取事件,但似乎没有这样的方法。 只抓取在组件上绘制的帧/像素就足够了
这可以通过使用媒体播放器来完成吗?我使用媒体播放器的原因是bcs,这是我得到的最简单的解决方案。我尝试了vlcj,仅32位,和gstreamer,但没有运气:(
到目前为止,我得到的是:
public class VideoGrabber extends extends JFrame {
// code for scene setup omitted
final MediaView view = createMediaView(...)
// some other stuff happens here
// now start the video
view.getMediaPlayer().seek(Duration.ZERO);
view.getMediaPlayer().play();
view.getMediaPlayer().setOnEndOfMedia(new Runnable()
{ // save image when done
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_BGR
view.paint(img.getGraphics());
ImageIO.write(img, "JPEG", new File("pic-"+System.currentTimeMillis()+".jpg"));
});
// somewhere else to create
private MediaView createMediaView(String url)
{
final Media clip = new Media(url);
final MediaPlayer player = new MediaPlayer(clip);
final MediaView view = new MediaView(player);
view.setFitWidth(VID_WIDTH);
view.setFitHeight(VID_HEIGHT);
return view;
}
是否有办法做到以下几点:
player.setOnNextFrameReady(final Event evt) { writeImage(evt.getFrame()) };
谢谢
# 1 楼答案
像ffmpeg这样的框架带有命令行工具,可以将视频分割成单独的帧(即文件夹中的图像)
见这个问题:ffmpeg split avi into frames with known frame rate
答案包含指向包装ffmpeg的Java框架的链接
# 2 楼答案
您可以使用MediaView的快照()。 首先将mediaPlayer连接到MediaView组件,然后使用mediaPlayer。seek()查找视频位置。然后可以使用以下代码提取图像帧:
# 3 楼答案
Marvin Framework提供逐帧处理媒体文件的方法。下面是一个简单的视频处理示例,突出显示了斯诺克球的路径
在左侧,视频逐帧播放,每帧之间的间隔为30毫秒。在右侧,视频逐帧播放,但通过简单的图像处理方法保持白球的所有位置
可以检查源代码here和视频here
下面是使用Marvin请求媒体文件帧的基本源代码: