简体   繁体   中英

Grabbing frames from .avi

I am trying to grab individual frames (and eventually audio) from .avi files. Ultimately i want to make a JNI-bound library that allows me to open .avi files in Java, but for now i'm working in native win32 C++.

I have been banging my head against the wall with this, tried VFW, and it barely works for older videos, but it flatly refuses to give me any frame of a more recent video. I resigned myself to that VFW was old.

Upon trying DirectShow i find virtually no documentation on how to support it, and wind up reading articles saying it sucks for individual frame grabs due to its streaming nature.

Then i find out ffmpeg doesn't even support visual studio.

Java's JMF is outdated and also seems to be completely unsupported in the new century, and no good tutorials exist for that either.

Can anyone point me in the direction of a codec-independent .avi decoder solution? Preferrably native or Java, but i guess i can try to retrofit something .NET if it comes down to the wire.

According to my experience JMF works fine, it is very up-to-date, the API is very powerful etc. I wrote program that splits clip into individual frames. Unfortunately I cannot achieve now any code sample but as far as I remember I used Player and some kind of Control (FrmeControl or so).

If for some reason you still do not want to use JMF I'd recommend you to invoke ffmpeg from command line. Since ffmpeg is a very strong (even the strongest) command line utility for video processing and available for multiple platforms your application can be cross-platform too.

You can try OpenCV. I have functions to read and modify a video file and it can open variety of formats. It is available for C++ but not sure if it is available for JAVA. Also it will not parse the audio.

Here is a sample implementation of mine which i use in my computer vision projects

.h file

#ifndef _VPLAYER_H_

#define _VPLAYER_H_

#include #include #include #include "cv.h" #include "highgui.h"

class VPlayer {

public: VPlayer(); ~VPlayer();

private:

CvCapture* pAvi;
IplImage* pFrame;

public: int Height; int Width; int fps; int numFrames; double CodecCode;

public:

bool LoadVideo(char * fname);
void GetFrame(int FrameNo);
void GetImage (IplImage* &pOutBuffer);
void GetProperties();

};

#endif

.cpp file

#include "stdafx.h" #include "VideoPlayer_PB_1.h"

bool VPlayer::LoadVideo(char * fname){

if(pAvi)cvReleaseCapture(&pAvi);
if(!(pAvi = cvCaptureFromAVI(fname)))return false;
GetProperties();
return true;

}

VPlayer::VPlayer(){ pAvi = 0; pFrame =0; }

VPlayer::~VPlayer(){

cvReleaseCapture(&pAvi);

}

void VPlayer::GetFrame(int FrameNo){

cvSetCaptureProperty(pAvi,CV_CAP_PROP_POS_FRAMES,FrameNo);

if(!cvGrabFrame(pAvi)){              // capture a frame 
    printf("Could not grab a frame\n\7");
    exit(0);
}
pFrame = cvRetrieveFrame(pAvi);  

}

void VPlayer::GetImage (IplImage* &pOutBuffer){

pOutBuffer = cvCloneImage(pFrame);

}

void VPlayer::GetProperties(){ if(pAvi){ cvQueryFrame(pAvi); // this call is necessary to get correct capture properties

    Height = (int) cvGetCaptureProperty(pAvi, CV_CAP_PROP_FRAME_HEIGHT);

    Width = (int) cvGetCaptureProperty(pAvi, CV_CAP_PROP_FRAME_WIDTH);

    fps       = (int) cvGetCaptureProperty(pAvi, CV_CAP_PROP_FPS);

    numFrames = (int) cvGetCaptureProperty(pAvi,  CV_CAP_PROP_FRAME_COUNT);

    CodecCode = cvGetCaptureProperty(pAvi, CV_CAP_PROP_FOURCC);
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM