如何逐帧阅读视频? [英] How to read a video frame by frame?

查看:190
本文介绍了如何逐帧阅读视频?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想逐帧读取java8-64bit中的Mp4文件,并将每个帧作为jpg写入我的硬盘。我的第一次尝试是使用JavaFX 2.2媒体播放器在View组件上播放文件
。我想也许会有一个选项来注册一个观察者来获取一个事件,每次加载一个新的框架并准备在组件表面上绘制,但似乎没有这样的方法。
它足以抓住组件上绘制的那些帧/像素。



这可以通过使用媒体播放器来完成吗?我使用媒体播放器的原因是bcs这是我工作的最简单的解决方案。我尝试了vlcj,只有32位,而gstreamer却没有运气:(



到目前为止我所得到的:

 公共类VideoGrabber extends扩展JFrame {

//场景设置代码省略

final MediaView view = createMediaView(...)

//其他一些东西发生在这里

//现在开始播放视频
view.getMediaPlayer()。seek(Duration.ZERO);
view .getMediaPlayer()。play();
view.getMediaPlayer()。setOnEndOfMedia(new Runnable()
{//完成时保存图像
BufferedImage img = new BufferedImage(getWidth(), getHeight(),BufferedImage.TYPE_INT_BGR
view.paint(img.getGraphics());
ImageIO.write(img,JPEG,new File(pic - + System.currentTimeMillis()+ .jpg));
});

//在其他地方创建
私有MediaView createMediaView(String url)
{
final Media clip = new Media(url);
final MediaPlayer player = new MediaPlayer(clip);
final MediaView view = new MediaView(pla) YER);
view.setFitWidth(VID_WIDTH);
view.setFitHeight(VID_HEIGHT);
返回视图;
}

有某种方法可以执行以下操作:

  player.setOnNextFrameReady(final event evt){writeImage(evt.getFrame())}; 

谢谢!

解决方案

和视频这里



使用Marvin请求媒体文件框架的基本源代码:

  public class MediaFileExample实现Runnable {

private MarvinVideoInterface videoAdapter;
私人MarvinImage videoFrame;

public MediaFileExample(){
try {
//创建用于加载视频文件的VideoAdapter
videoAdapter = new MarvinJavaCVAdapter();
videoAdapter.loadResource(./ res / snooker.wmv);

//启动请求视频帧的线程
new Thread(this).start();
}
catch(MarvinVideoInterfaceException e){e.printStackTrace();}
}

@Override
public void run(){
尝试{
while(true){
//申请视频帧
videoFrame = videoAdapter.getFrame();
}
} catch(MarvinVideoInterfaceException e){e.printStackTrace();}
}

public static void main(String [] args){
MediaFileExample m = new MediaFileExample();
}
}


i would like to read a Mp4 file in java8-64bit frame by frame and write each frame as a jpg to my harddisk. my first attempt was to use JavaFX 2.2 media player to play the file on a View component. i thought maybe there would be an option to register an observer to get an event each time a new frame was loaded and ready to be painted on the component surface but seems there is no such method. it would be enough to grab just those frames/pixels that got painted on the component.

Can this be done by using the media player? the reason why i use the media player is bcs it was the simplest solution i got workin. i tryed vlcj, just 32bit, and gstreamer but without luck :(

what i got so far:

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;
}

is there somehow a way to do the following:

player.setOnNextFrameReady(final Event evt) { writeImage(evt.getFrame()) };

Thanks!

解决方案

Marvin Framework provides methods to process media files frame by frame. Below it is shown a simple video processing example that highlights the path of a snooker ball.

At the left the video is played frame by frame with an interval of 30ms between frames. At the right the video is played frame by frame, but keeping all positions of the white ball through a simple image processing approach.

The source code can be checked here and the video here.

Below the essential source code to request media file frames using Marvin:

public class MediaFileExample implements Runnable{

    private MarvinVideoInterface    videoAdapter;
    private MarvinImage             videoFrame;

    public MediaFileExample(){
        try{
            // Create the VideoAdapter used to load the video file
            videoAdapter = new MarvinJavaCVAdapter();
            videoAdapter.loadResource("./res/snooker.wmv");

            // Start the thread for requesting the video frames 
            new Thread(this).start();
        }
        catch(MarvinVideoInterfaceException e){e.printStackTrace();}
    }

    @Override
    public void run() {
        try{
            while(true){
                // Request a video frame
                videoFrame = videoAdapter.getFrame();
            }
        }catch(MarvinVideoInterfaceException e){e.printStackTrace();}
    }

    public static void main(String[] args) {
        MediaFileExample m = new MediaFileExample();
    }
}

这篇关于如何逐帧阅读视频?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆